JavaScript中的this、apply()、call()、bind()
this
this是函式執行時基於函式的執行環境繫結的,指向最後呼叫它的那個物件。
例1:
function a(){
var name= "Carol";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
最後一個呼叫a的是全域性物件Window,因此a的this指向Window,this.name會輸出undefined。
例2:
var a = { name: "Carol", fn : function () { console.log(this.name); // Carol } } a.fn();
這裡最後一個呼叫fn的是物件a,所以fn中的this指向a,this.name會輸出Carol。
例3:
var a = {
name: "Carol",
fn : function () {
console.log(this.name); // Carol
}
}
window.a.fn();
這裡與上面同樣,因為this指向的是最後呼叫它的那個物件,在這裡還是a。
例4:
var a = { name : null, // name: "Carol", fn : function () { console.log(this.name); // undefined } } var f = a.fn; f();
這裡fn的this仍然是指向window的。
因為雖然fn被賦給了變數f,但是並沒有執行,所以fn的this並不是指向a的,最後f是在window裡執行的,所以fn的this還是指向window。
例5:
function fn()
{
this.name = 'Carol';
return function(){};
}
var a = new fn;
console.log(a.name); //undefined
以及
function fn() { this.name = 'Carol'; return 1; } var a = new fn; console.log(a.name); //Carol
如果返回值是一個物件(除null外),那麼this指向的就是那個返回的物件,如果返回值不是一個物件那麼this還是指向函式的例項。
如何改變this的指向
使用ES6的箭頭函式
箭頭函式中沒有this繫結,必須通過查詢作用域鏈來決定其值,如果箭頭函式被非箭頭函式包含,則this繫結的是最近一層非箭頭函式的 this,否則,this為undefined。
用區域性變數代替this指標
在函式內部寫上var _this=this;
用_this來代替this使用。
apply()
apply()接受兩個引數,第一個引數是要繫結給this的值,第二個引數是一個引數陣列。如果第一個引數是null、undefined的話,this指向window。
var obj = {
message: 'My name is: '
}
function getName(firstName, lastName) {
console.log(this.message + firstName + ' ' + lastName)
}
getName.apply(obj, ['Carol', 'Lee'])// My name is: Carol Lee
call()
call()和apply()的作用一樣,都可以改變this的指向,只不過接受引數的方式不同。
var obj = {
message: 'My name is: '
}
function getName(firstName, lastName) {
console.log(this.message + firstName + ' ' + lastName)
}
getName.apply(obj,'Carol','Lee')// My name is: Carol Lee
bind()
bind()和上面兩種略有不同。apply()和call()都是立即執行的,而bind()返回的是一個待執行的函式,便於需要稍後再呼叫的情況。
var obj = {
name: 'Carol'
}
function printName() {
console.log(this.name)
}
var c = printName.bind(obj)
console.log(c) //function() { … }
c() //Carol
也就是bind()();
才是執行改變。