1、函数是和new一起被调用的吗(new绑定)?如果是,this就是新构建的对象。
var bar = new foo()
2、函数是用call或apply被调用(明确绑定),甚至是隐藏在bind 硬绑定 之中吗?如果是,this就是明确指定的对象。
var bar = foo.call( obj2 )
3、函数是用环境对象(也称为拥有者或容器对象)被调用的吗(隐含绑定)?如果是,this就是那个环境对象。
var bar = obj1.foo()
4、使用默认的this(默认绑定)。如果在strict mode下,就是undefined,否则是global对象。
var bar = foo()
【注:】 箭头函数中,this 指向声明函数时,最靠近箭头函数的普通函数的 this
从函数对象,活动对象,执行上下文内容对象角度解释 this 指向
this 引用的是函数执行时的执行上下文对象Scope属性维护的作用域链中的当前活动对象【即栈顶】的父级活动对象
this 指向调用函数时的对象。在全局执行时,则是全局对象。
箭头函数的this指向的是谁调用箭头函数的外层function,箭头函数的this就是指向该对象,如果箭头函数没有外层函数,则指向window。
【谁调用箭头函数的外层function,箭头函数的this就是指向该对象;
如果箭头函数没有外层函数,则指向window 】的理解:
function Caller(name){
this.name = name;
this.wrapFunc = function(){
return () => console.log(this.name);
}
}
let caller = new Caller('foo');
caller.wrapFunc(); // foo
1. caller 对象调用了 外层函数wrapFunc
2. 外层函数wrapFunc 的 this 指向 caller
2. 箭头函数中的 this 指向外层函数 wrapFunc 的 this
箭头函数
箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值。
箭头函数的this,因为没有自身的this,所以this只能根据作用域链往上层查找,直到找到一个绑定了this的函数作用域(即最靠近箭头函数的普通函数作用域,或者全局环境),并指向调用该普通函数的对象。
或者从现象来描述的话,即箭头函数的this指向声明函数时,最靠近箭头函数的普通函数的this。但这个this也会因为调用该普通函数时环境的不同而发生变化。导致这个现象的原因是这个普通函数会产生一个闭包,将它的变量对象保存在箭头函数的作用域中。
参考链接
var name = 'window'
var person1 = {
name: 'person1',
show1: function () {
console.log(this.name)
},
show2: () => console.log(this.name),
show3: function () {
return function () {
console.log(this.name)
}
},
show4: function () {
return () => console.log(this.name)
}
}
var person2 = { name: 'person2' }
person1.show1() // person1
person1.show1.call(person2) // person2
person1.show2() // window
person1.show2.call(person2) // window
person1.show3()() // window
person1.show3().call(person2) // person2
person1.show3.call(person2)() // window
person1.show4()() // person1
person1.show4().call(person2) // person1
person1.show4.call(person2)() // person2
var name = 'window'
function Person (name) {
this.name = name;
this.show1 = function () {
console.log(this.name)
}
this.show2 = () => console.log(this.name)
this.show3 = function () {
return function () {
console.log(this.name)
}
}
this.show4 = function () {
return () => console.log(this.name)
}
}
var personA = new Person('personA')
var personB = new Person('personB')
personA.show1() // personA
personA.show1.call(personB) // personB
personA.show2() // personA
personA.show2.call(personB) // personA
personA.show3()() // window
personA.show3().call(personB) // personB
personA.show3.call(personB)() // window
personA.show4()() // personA
personA.show4().call(personB) // personA
personA.show4.call(personB)() // personB
隐含绑定的丢失
尽管bar是obj.foo的引用,但实际上它只是另一个foo自己的引用而已(浅拷贝,将函数对象foo在内存中的堆地址拷贝给bar变量);最后起作用的调用点是bar(),处于全局环境中。
function foo(){
console.log(this.name);
}
var obj = {
name: 2,
foo: foo
}
var name = 'window';
var bar = obj.foo;
obj.foo(); // '2'
bar(); // 'window'