javascript的this簡單記憶
一直感覺 javascript 中的 this 是一個大坑,雖然一直都有注意,一直都有研究,但是總是會忘記。在這里,總結一下一些簡單的規律
不考慮箭頭函數的情況下
下面的所有的都是不考慮箭頭函數的情況下,因為箭頭函數和普通的差別很大
直接調用的都是window
除非是 bind 綁定過的 ,其他情況下,直接調用的方法的 this 都是 window 。所謂的直接調用,就是直接以 method() 的形式調用,沒有 call , apply , new
看幾種情況:
function foo(){
return this;
}
foo(); // window
var obj = {
foo: function(){ return this; }
}
var foo = obj.foo;
foo(); // window
function Foo(){
this.foo = function(){
console.log(this);
}
var foo = this.foo;
foo(); // window
}
new Foo();
誰調用,誰是this
除非是 bind 綁定過的 ,一般情況下,誰調用這個方法,那么內部的 this 就指向這個對象。也就是說 obj.method() ,那么就指向 obj 。 obj.foo.method() ,那么就指向 obj.foo
看幾個例子:
var obj = {
foo: function(){ return this; }
}
obj.foo(); // obj調用,所以結果是obj
function foo(){ return this };
var obj = {};
obj.foo = foo;
obj.foo(); // obj調用,所以結果是obj
var obj = {
bar: function(){ return this; },
foo: function(){
return this.bar();
}
}
obj.foo(); // 在foo中, this是obj, 而this調用的bar, 所以返回的是obj
var obj = {
bar: {
foo: function(){ return this }
}
}
obj.bar.foo(); // obj.bar調用的foo,所以返回的結果是bar
function foo(){
this.bar = function(){ return this }
return this.bar();
}
foo(); // 由于foo中的this是window, 所以this.bar()返回的是window
function Foo(){
this.foo = function(){ console.log(this); }
this.foo();
}
var object = new Foo(); // 由于this.foo中的this是object,所以this是object
new會生成一個新的this
所有情況下,(箭頭函數不能使用 new 關鍵字),使用了 new 以后,會把內部的 this 指向新生成的對象。
除去bind的情況下, prototype 中的 this 也指向新生成的對象
function Foo(){
console.log(this); // this指向新生成的對象,object
}
var object = new Foo();
function Foo(){
this.foo = function(){ return this === object; }
}
var object = new Foo();
object.foo(); // 輸出true
function Foo(){}
Foo.prototype.foo = function(){ return this === object; }
var object = new Foo();
object.foo(); // 輸出true
call, apply是誰,this就是誰
除非是bind的情況, call , apply 是誰,那么內部的 this 就是誰。
注意:如果是基本類型,那么 javascript 會把基本類型轉換成 Object 的形式
也是看例子:
function foo(){ return this; }
foo.call("a"); // String
typeof foo.call("a"); // object
var obj = {
foo : function(){ return this; }
}
obj.foo.call(1); // Number
typeof obj.foo.call(1); // object
function Foo(){
this.foo = function(){ return this; }
}
var object = new Foo();
object.foo.call(1); // Number
bind是誰,this就是誰
除了 new 這一種特殊情況 , bind 的對象是誰,那么 this 也就是誰。即使 call , apply 也沒有權利改變。
注意:如果是基本類型,那么 javascript 會把基本類型轉換成 Object 的形式
function foo() { return this; }
foo = foo.bind(1);
foo(); // Number
typeof foo(); // object
function foo() { return this; }
foo = foo.bind(1);
foo.call("a"); // Number 1
function Foo() { return this; }
Foo.prototype.foo = (function(){ return this; }).bind(1);
var object = new Foo();
object.foo(); // Number
特殊情況
new 這個關鍵詞可以改變方法內部的 this ,使他指向新生成的對象
function Foo(){ this.foo = function(){ console.log(this === obj) } }
Foo = Foo.bind(1);
var obj = new Foo();
obj.foo(); // 輸入true
箭頭函數
箭頭函數的 this 是根據定義環境的 this 來定的,也就是說定義的函數周圍的 this 是什么,它的 this 就是什么。
而且不會被 bind , call , apply 所改變
var foo = ()=>{ return this };
foo() // window
var obj = { foo: ()=>this }
obj.foo(); // 由于定義的時候,周圍的環境是window,所以返回window
var obj = {
foo(){
var bar= ()=>{ return this };
return bar();
}
}
obj.foo(); // 由于定義bar的時候,周圍環境是obj,所以返回obj
var foo = obj.foo;
foo(); // 同理,這里是window
var foo = ()=>{ return this };
foo = foo.bind(1);
foo(); // window
foo.call(1); // window
foo.apply(1); // window
function Foo(){
// 箭頭函數
var a = ()=>{
console.log(this === object); // true
}
// 對比普通函數
var b = function(){
console.log(this === window); // true
}
this.foo = function(){
a(); b();
}
}
var object = new Foo();
object.foo();
function Foo(){}
// window
Foo.prototype.foo = ()=>{ return this }
// window
var object = new Foo();
object.foo(); // 由于定義foo的時候,周圍環境是window,所以這里是window
由于只是我根據經驗和資料自己總結的,所以不知道是否有疏忽或者遺漏,如果有問題的地方,歡迎提出。謝謝
來自:https://segmentfault.com/a/1190000008374668