this在javascript中一直是新手難以理解的一部分拷泽。其實(shí)并不難敢会,只要清楚幾種調(diào)用模式蔑穴,就容易掌握了。
函數(shù)調(diào)用模式
普通情況
var name = 'outer';
var fn = function() {
var name = 'inner';
console.log(this.name);
}
fn()迷扇; // outer
回調(diào)函數(shù)
無(wú)默認(rèn)綁定
var name = 'outer';
var A = function() {
console.log(this.name);
};
var B = function(cb) {
var name = 'inner';
cb();
}
B(A); // outer
默認(rèn)綁定
js中的事件機(jī)制百揭,會(huì)默認(rèn)綁定this
var name = 'outer';
var d = document.querySelector('div');
div.addEventListener('click', function(e) {
console.log(this.name); // undifined
}, false)
方法調(diào)用模式
var name = 'outer;
var obj = {
name: 'inner',
fn: function() {
console.log(this.name);
}
}
obj.fn() // inner
apply、call調(diào)用模式
var name = 'outer';
var obj = {
name: 'inner'
}
var fn = function() {
console.log(this.name);
}
fn() // outer;
fn.call(obj) // inner
fn.apply(obj) // inner
構(gòu)造器調(diào)用模式
var name = 'outer';
var Fn = function(name) {
this.name = name;
}
Fn.prototype.print = function() {
console.log(this.name)
}
var obj = new Fn('inner');
obj.print() // inner
bind, call優(yōu)先級(jí)
var name = 'outer';
var obj1 = {
name: 'inner1'
};
var obj2 = {
name: 'inner2';
};
var fn = function() {
console.log(this.name);
}
var f = fn.bind(obj1);
f(); // inner1
f.call(obj2) // inner1
可以看出蜓席,bind的優(yōu)先級(jí)是比call要高的器一,當(dāng)函數(shù)fn的this綁定為obj1后,再執(zhí)行f.call(obj2)厨内,輸出的name值還是name1祈秕,即this的值一直綁定為obj1。
es6的箭頭函數(shù)
箭頭函數(shù)的好處之一就是讓我們省去了每次敲打function這個(gè)關(guān)鍵詞雏胃,好處之二就是this值默認(rèn)綁定為函數(shù)定義時(shí)的上下文请毛,而跟調(diào)用模式無(wú)關(guān)。
var name = 'outer';
var obj = {
name: 'inner',
fn: ()=> {
console.log(this.name);
}
}
obj.fn() // outer
var name = 'outer';
var obj = {
name: 'inner'
};
var fn = ()=> {
console.log(this.name);
};
fn.call(obj) // outer
var name = 'outer';
var obj = {
name: 'inner'
};
var fn = ()=> {
console.log(this.name);
};
var f = fn.bind(obj);
f() // outer