在JavaScript语言中存在一个this
关键词,这个关键词指的是函数运行时所在的环境。因为函数能够在不一样的运行环境执行,因此须要有一种机制,可以在函数体内部得到当前的运行环境(context)。因此,this
就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。bash
前一个系列的做用域讲过,做用域运用的是词法做用域,意味着是编写时肯定的,但this与其工做原理彻底不一样,它的指向并非编写时肯定的,而是运行时肯定。markdown
以前在阅读 You Don't Know JS系列的: this & Object Prototypes中,将this的指向总结了几条规则:数据结构
函数调用方式与内部
this
指针关系:app
this
指向全局对象window
this
指向触发事件的对象call
的方法来间接调用方法:函数内部this指向call
方法的第一参数对象,咱们能够建立结构相同,但内容不一样的对象new
的方式来调用:函数内部this
指向本次函数执行时对应的一个匿名对象(以new的方式建立的函数,函数名的首字母通常以大写字母开始)new
关键词调用,经过apply
、call
方法不会改变内部的this
指向参考了上面的规则发现,this
的指向不管如何都逃脱不了上面的5大原则,那它们以前是否存在必定的规律呢,或者说是什么来决定this
的指向的。函数
一般咱们会对一下例子的结果无法准确的肯定this
指向:oop
var name = 'zhou'; var obj = { name: 'shaw', say: function () { console.log(this.name); } } obj.say(); var say = obj.say; say(); 复制代码
上面的输出结果会是什么呢:this
obj.say(); // 输出shaw
say(); // 输出zhou
复制代码
为何这里obj.say
和say
的输出结果会不一致呢?下面咱们来一探究竟。spa
this
的指向与数据在内存里的数据结构有关:设计
上面案例里的obj
对象是如何在内存中存储的呢指针
obj.say-> { [[value]]: say函数地址 [[write]]: true, [[readable]]: true } 复制代码
实际上say
函数并无存储在obj
对象中,它只存储了say
函数的地址。
咱们直接经过obj.say
来调用函数,与obj.say
赋值给say
变量调用彻底不一样,由于obj
中存储的是say函数
的地址,咱们进行赋值操做时直接将say函数地址直接赋值过去了,而不是咱们想象的将obj.say
引用赋值过去。