JS中this关键字很常见,但是它似乎变幻莫测,让人抓狂。这篇文章就来揭示其中的奥秘。

借助阮一峰老师的话:它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。这句话看似平常,可是要非常注意三个字:“运行时”,这说明this关键字只与函数的执行环境有关,而与声明环境没有关系。也就是这个this到底代表的是什么对象要等到函数运行时才知道,有点类似函数定义时的参数列表只在函数调用时才传入真正的对象。理解了这一点对后面this关键字规律的掌握有很大帮助。

this关键字虽然会根据环境变化,但是它始终代表的是调用当前函数的那个对象。这就引出了JS中函数调用的问题。在JS中调用函数的模式可以分为4种: 方法调用模式、函数调用模式、构造器调用模式、apply调用模式。这些模式在如何初始化关键参数this上存在差异。

一、方法调用模式

当函数被保存为一个对象的属性时,它就可称为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上。如果调用表达式包含一个提取属性的动作(. 或 []),那么它被称为方法调用。例如:

var name = "window";
var obj = {
name: "kxy",
sayName: function() {
console.log(this.name);
}
};
obj.sayName(); //kxy

sayName函数作为对象obj的方法调用,所以函数体中的this就代表obj对象。

二、函数调用模式

当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下就是window对象。例如:

var name = "window";
function sayName() {
console.log(this.name);
}
sayName();

sayName以函数调用模式调用,所以函数体中的this代表window对象。

三、构造函数模式

如果在一个函数前面加上new关键字来调用,那么就会创建一个连接到该函数的prototype成员的新对象,同时,this会被绑定到这个新对象上。这种情况下,这个函数就可以成为此对象的构造函数。例如:

function Obj() {
this.name = "kxy";
}
var person = new Obj();
console.log(person.name); //kxy

Obj作为构造函数被调用,函数体内的this被绑定为新创建的对象person。

四、apply调用模式

在JS中,函数也是对象,所有函数对象都有两个方法:apply和call,这两个方法可以让我们构建一个参数数组传递给调用函数,也允许我们改变this的值。例如:

var name = "window";
var person = {
name: "kxy"
};
function sayName() {
console.log(this.name);
}
sayName(); //window
sayName.apply(person); //kxy
sayName.apply(); //window

当以函数调用模式调用sayName时,this代表window;当用apply模式调用sayName,并给它传入的第一个参数为person时,this被绑定到person对象上。如果不给apply传入任何参数,则this代表window。

自此,函数调用的4种模式就都介绍完了,this的绑定规律也就是以上几种,万变不离其宗。为了简单明了的介绍4种模式,以上的例子都比较简单,那么下面就跟我一起做一个稍复杂的练习,检验下自己是否真正掌握了this绑定对象的方法吧!

var name = "window";
function showName() {
console.log(this.name);
}
var person1 = {
name: "kxy",
sayName: showName
}
var person2 = {
name: "Jake",
sayName: function() {
var fun = person1.sayName;
fun();
}
}
person1.sayName(); //kxy
person2.sayName(); //window

首先心中时刻提醒自己this是在函数执行时被绑定的,不要被任何赋值语句打乱阵脚。

先看第一个执行语句:person1.sayName(); 首先确定这是方法调用模式,对象为person1,再看sayName被赋值为全局函数对象showName,在showName执行时,this绑定的是person1,所以结果为”kxy”。

再看第二个执行语句:person2.sayName(); 这还是方法调用模式,对象为person2,调用的是它的sayName方法。再看sayName函数体,发现函数体最终执行的函数是fun,fun是用函数调用模式调用的。而fun最终也被赋值为showName函数,因为fun是用函数调用模式调用的,所以这里的this绑定为window,结果为”window“。

怎么样,你做对了吗?

JS中的this对象详解的更多相关文章

  1. JS中的event 对象详解

    JS中的event 对象详解   JS的event对象 Event属性和方法:1. type:事件的类型,如onlick中的click:2. srcElement/target:事件源,就是发生事件的 ...

  2. js中中括号,大括号使用详解

    js中中括号,大括号使用详解 一.总结 一句话总结:{ } 是一个对象,[ ] 是一个数组 1.js大括号{}表示什么意思? 对象 { } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或 ...

  3. js中鼠标滚轮事件详解

    js中鼠标滚轮事件详解   (以下内容部分内容参考了http://adomas.org/javascript-mouse-wheel/ ) 之前js 仿Photoshop鼠标滚轮控制输入框取值中已使用 ...

  4. JS中的this用法详解

    随着对js的深入学习和使用,你会发现它里面包含了很多令人困惑的机制,比如对象.闭包.原型链继承等等,而这其中肯定包含令你现在或者曾经费解的this,如果你不把心一横,花点时间还真不明白这个this的用 ...

  5. js 中中括号,大括号使用详解

    一.{ } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数.如:var LangShen = {"Name":"Langshen",&quo ...

  6. Vue.js中学习使用Vuex详解

    在SPA单页面组件的开发中 Vue的vuex和React的Redux 都统称为同一状态管理,个人的理解是全局状态管理更合适:简单的理解就是你在state中定义了一个数据之后,你可以在所在项目中的任何一 ...

  7. Ajax中的XMLHttpRequest对象详解

    XMLHttpRequest对象是Ajax技术的核心.在Internet Explorer 5中,XMLHttpRequest对象以ActiveX对象引入,被称之为XMLHTTP,它是一种支持异步请求 ...

  8. Foundation框架中的NSNumber对象详解

    到目前为止,我们所讨论过的所有数字数据类型,如int型.float型和long型都是Objective-C语言中的基本数据类型,也就是说,它们都不是对象.例如,不能向它们发送消息.然而,有时需要作为对 ...

  9. Ajax中的XMLHttpRequest对象详解(转)

    XMLHttpRequest对象是Ajax技术的核心.在Internet Explorer 5中,XMLHttpRequest对象以ActiveX对象引入,被称之为XMLHTTP,它是一种支持异步请求 ...

随机推荐

  1. Java入门教程总目录

    Java入门教程总目录 持续更新中... 1.Java常识汇总 2.Java框架对比 3.Java技术路线 4.Java编码规范 5.Java环境变量配置 6.枚举 7.操作符 12.定时任务

  2. js获取当前时间&js 页面时钟

    js获取当前时间 //获取当前时间,格式YYYY-MM-DD function getNowFormatDate() { var date = new Date(); var seperator1 = ...

  3. linux网络编程-(socket套接字编程UDP传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  4. 7个混合式HTML5移动开发框架

    在这个时间开始学习移动开发真是最好不过了,每个人应该都有一些移动应用的创意,而且你并不需要任何的原生应用编程经验,你只需要一些HTML的相关知识,懂一些CSS和JavaScript就够了.如果你总听别 ...

  5. SilverlightERP&CRM源码(可用于开发基于Silverlight的CRM,OA,HR,进销存等)

    SilverlightERP系统源代码(支持创建OA.SilverlightCRM.HR.进销存.财务等系统之用) 可用于开发以下系统 SilverlightERP SilverlightCRM Si ...

  6. LeetCode "Integer Break"

    A typical CS style DP based solution: class Solution(object): def __init__(self): self.hm = {} def i ...

  7. Hbase条件筛选

    需求来自于,模糊查找当天的所有记录,并查找对应列的记录数 public static void main(String[] args) throws Exception{ //创建HBase连接 Co ...

  8. Hibernate getCurrentSession()和openSession()的区别

    通过getCurrentSession()创建的Session会绑定到当前线程上:openSession()不会. 通过getCurrentSession()获取Session,首先是从当前上下文中寻 ...

  9. JNI常见错误整理

    ndk开发常见错误1. android.mk文件不存在 $ ndk-buildAndroid NDK: Your APP_BUILD_SCRIPT points to an unknown file: ...

  10. Data Science at the Command Line学习笔记(一)

    学习Data Science at the Command Line时,win7下安装环境是遇到了一些小问题,最后通过百度解决. 官方指导可以在这个地址找到:http://datascienceatt ...