this是javascript中的關鍵字之一。他是使用對象自動生成的一個內部對象,只能在對象內部使用。它會根據上下文而進行變化,而且會在不一樣的 JavaScript的模式(是否爲嚴格模式)下表現出差別。javascript
this的指向取決於什麼地方以什麼方式調用,而不是建立時。箭頭函數中的 this
的做用域繼承自執行上下文,箭頭函數自身不綁定 this
,所以 this
的值將在調用堆棧中查找。前端
構造調用
後,js幫咱們作了什麼工做:
__proto__
屬性指向 原函數的prototype
屬性。(即繼承原函數的原型);new 綁定 > 顯示綁定 > 隱式綁定 > 默認綁定java
1. 默認綁定
function foo(){
var a = 1 ;
console.log(this.a); // 10
}
var a = 10;
foo();
2. 隱性綁定
function foo(){
console.log(this.a);
}
var obj = {
a : 10,
foo : foo
}
foo(); // undefined (默認綁定)
obj.foo(); // 10
// 隱式丟失(引用賦值)
var a = 0;
function foo(){
console.log(this.a);
};
var obj = {
a : 2,
foo:foo
}
//把obj.foo賦予別名bar,形成了隱式丟失,由於只是把foo()函數賦給了bar,而bar與obj對象則毫無關係
var bar = obj.foo;
bar();//0
//等價於
var a = 0;
var bar = function foo(){
console.log(this.a);
}
bar();//0
// 隱式丟失(參數傳遞)參數傳遞其實就是一種隱式賦值,所以咱們傳入的函數也會被隱式賦值。
function foo(){
console.log(this.a);
}
function doFoo(fn){
//fn其實引用的是foo
fn();//調用位置
}
var obj = {
a:2,
foo:foo
};
var a = "oops,global";//a是全局對象的屬性
doFoo(obj.foo);//oops,global
//若是把函數傳入內置的函數中結果是同樣的
function foo(){
console.log(this.a);
}
var obj = {
a:2,
foo:foo
};
var a = "oops,global";//a是全局對象的屬性
setTimeout(obj.foo,100);//oops,global
3. 顯性綁定
function foo(){
console.log(this.a);
}
var obj = { a : 10 };
foo = foo.bind(obj);
foo(); // 10
function foo(){
this.a = 10;
console.log(this);
}
foo(); // window對象
console.log(window.a); // 10 默認綁定
var obj = new foo(); // foo{ a : 10 } 建立的新對象的默認名爲函數名
// 而後等價於 foo { a : 10 }; var obj = foo;
console.log(obj.a); // 10 new綁定
// 使用new調用函數後,函數會 以本身的名字 命名 和 建立 一個新的對象,並返回。
//若是原函數返回一個對象類型,那麼將沒法返回新對象,你將丟失綁定this的新對象。
function foo(){
this.a = 10;
return new String("搗蛋鬼");
}
var obj = new foo();
console.log(obj.a); // undefined
console.log(obj); // "搗蛋鬼"
複製代碼
github地址: github.com/ruralist-si…git