本文不考虑严格模式(错误之处感谢提出,请勿喷)
function 函数 this 指向一共有4种规则:默认绑定,隐式绑定,显式绑定, new绑定
默认绑定
function fn() {
var a = 10;
console.log(this.a);
}
var a = 1;
fn(); // a: 1
fn在没有任何修饰的被调用,只能使用默认绑定;this指向了直接调用的window
隐式绑定
function fn() {
var a = 10;
console.log(this.a);
}
var a = 1;
var obj = {
a: 5,
fn1: fn
}
obj.fn1(); // a: 5
函数fn有了上下文的对象,隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象上边;fn 的 this 指向到obj上边
个人理解:不管是默认还是隐式绑定,函数的this指向直接调用者
注意一个问题:
function fn() {
console.log(this.a);
}
var obj = {
a: 8,
fn1: fn
}
var a = 0;
var b = obj.fn1;
b(); // a: 0
// b 引用的是 fn函数本身,此时丢掉了绑定的对象,即 b() 的直接调用者是window,因此 this 指向全局对象
显式绑定
显示绑定一共3种方式(自己统计,对错不知道): bind call aplly
function fn() {
var a = 10;
console.log(this.a);
}
var a = 1;
var obj = {
a: 5,
fn1: fn.bind(window)
}
obj.fn1(); // a: 1
函数 fn 默认应该绑定到obj上边,但是bind 函数会返回一个硬编码的函数,指向你传进去的上下文;所以这个this指向了window
function fn() {
var a = 10;
console.log(this.a);
}
var a = 1;
var obj = {
a: 5,
fn1: fn.call(window) // fn1: fn.aplly(window)
}
obj.fn1(); // a: 1
new 关键字绑定
function fn(a) {
console.log(this);
this.a = a;
}
var a = 9;
var bar = new fn(8);
console.log(bar.a); // a: 8
使用 new 来调用 fn()时,我们会构造一个全新的对象并把它绑定到 fn()调用中的this 上,即把 bar 绑定到 fn 的 this 上
4中绑定的优先级: 默认绑定<隐式绑定<显式绑定<new绑定
ps: ES6新增的箭头不是function 函数,所以不在这个约束之内;箭头函数的this指向永远指向直接调用者的this,无法被更改。