首先this并不会指向函数本身。
1. 当函数在没有任何修饰的情况下调用,非严格模式下,this指向window,严格模式下this指向undefined。(默认绑定)
2. 当函数由一个对象引导调用时,this指向该对象。(隐式绑定)
3. 函数通过apply,call,bind绑定时,this指向绑定的对象。(显式绑定)
4. 当函数被当做构造函数使用,又new引导调用时,this指向new创建出来的对象。(new绑定);
5. 箭头函数其this取决于函数定义时所在的上下文。
其优先级为:new绑定 > 显示绑定 > 隐式绑定 > 默认绑定;
1. 当函数在没有任何修饰的情况下调用,非严格模式下,this指向window,严格模式下this指向undefined。(默认绑定)
(1)非严格模式
console.log(this); // window
(2) 严格模式(当使用了'use strict'后,成为严格模式,此时this是undefined。)
'use strict';
console.log(this);// undefined
2.当函数由一个对象引导调用时,this指向该对象。(隐式绑定)
function test () {
console.log(this); // testObj
}
var testObj = {
name: 'test',
func: test
};
testObj.func();
3.函数通过apply,call,bind绑定时,this指向绑定的对象。(显式绑定)
function test (name) {
console.log(name + ':' + JSON.stringify(this));
}
var testObj = {
name: 'test'
};
test.bind(testObj)('bind'); // bind:{"name":"test"}
test.call(testObj, 'call'); // call:{"name":"test"}
test.apply(testObj, ['apply']); // apply:{"name":"test"}
4.当函数被当做构造函数使用,又new引导调用时,this指向new创建出来的对象。(new绑定);
function Test (name) {
this.name = name;
}
var ts = new Test('haha');
//此时Test方法中的this指向`ts`,因此可以使用ts.name获取到`name`值;
console.log(ts.name); // haha
但是当构造函数中有返回对象或者函数时,this
指向new
创建出来的对象的返回值;
下面代码中ts.name
为123
,而非this.name
中设置的haha
;
关于new关键字的原理可见:http://www.netyali.cn/article/detail/101.html
function Test (name) {
// 此时下面`this.name = name;`也会执行,但是不会起作用;
this.name = name;
return {
name: '123'
};
}
var ts = new Test('haha');
console.log(ts.name);// 123
5.箭头函数其this取决于函数定义时所在的上下文。
function Test () {
this.func = function () {
console.log(this); // Test
return () => {
console.log(this); // Test
};
};
this.func1 = function () {
console.log(this);// Test
return function () {
console.log(this);// Window
};
};
}
var ts = new Test('haha');
// Test 构造函数下的func 和 func1都返回一个function,
// 并将整个function赋值给新的变量`func`和`func1`,
// 此时func和func1如果是在全局作用域下,其实是window.func和window.func1
// 通过window.func和window.func1调用方法,理论上方法中的this应该指向的是window
// 但是箭头函数自身没有this,指向的只能是代码块所在的父级作用域,因此指向的是Test构造函数中的func。
var func = ts.func();
var func1 = ts.func1();
window.func();
window.func1();
参考:
网友评论