默認綁定通常發生在回調函數,函數直接調用;bash
function fn() {
console.log( this.a )
}
let a = 2;
fn(); //2
複製代碼
this.a被解析成了全局變量a,函數調用時應用了this的默認綁定,所以this指向全局對象。在代碼中,fn是直接使用不帶任何修飾的函數引用進行調用的,所以只能使用默認綁定,沒法應用其餘規則。app
若是使用嚴格模式(use strict),則不能將全局對象用於默認綁定,所以this會綁定到undefined函數
通俗來講誰最終調用函數,this指向誰學習
const obj = {
name : 'lyq',
getName () {
console.log( this ); //obj
console.log( this.name ); //lyq
}
};
obj.getName();
複製代碼
鏈式調用只有最後一層在調用位置中起做用ui
var obj2 = {
name:'lyq',
foo() {
console.log( this.name )
}
}
var obj1 = {
name:'zs',
obj2:obj2
}
obj1.obj2.foo(); // lyq
複製代碼
一個最多見的this綁定問題是被隱式綁定的函數會丟失綁定對象,也就是你說它會應用默認綁定,從而把this綁定到全局對象或者undefined上,取決因而否是嚴格模式this
var a = 100;
var obj = {
a : 2,
foo() {
console.log( this.a )
}
}
var bar = obj.foo;
bar(); //100
複製代碼
obj.foo 是引用屬性,賦值給bar的實際上就是foo函數(即:bar指向foo自己,所以應用了默認綁定,指向全局屬性aspa
相對隱式綁定,this值在調用過程當中會動態變化,但是咱們就想綁定指定的對象,這時就用到了顯示綁定。prototype
顯示綁定主要是經過改變對象的prototype關聯對象。具體使用上,能夠經過這兩個方法call(…)或apply(…)來實現(大多數函數及本身建立的函數默認都提供這兩個方法)。code
function foo() {
console.log( this.a )
}
var obj = {
a : 2
}
foo.call( obj ) // 2
複製代碼
call和bind是同樣的,區別在於參數的設置上。對象
function foo() {
console.log( this.a );
}
var a = 2;
var obj1 = {
a: 3,
};
var obj2 = {
a: 4,
};
var bar = function() {
foo.call( obj1 );
}
setTimeout( bar, 100 ); // 3
bar.call( obj2 ); //3
複製代碼
這裏須要注意下,雖然bar被顯示綁定到obj2上,對於函數bar 中的this確實被綁定到了obj2,而foo由於經過foo.call( obj1 )已經顯示綁定了obj1,因此在foo函數內,this指向的是obj1,不會由於bar函數內指向obj2而改變自身。因此打印的是obj1.a(即3)。
function foo(a) {
this.a = a;
}
var a = 2;
var bar1 = new foo(3);
console.log(bar1.a); // 3
複製代碼
使用new來調用foo()時,會創造一個新對象並把它綁定到foo()調用中的this上。
首先須要明確,箭頭函數不適用以上this的四種標準規則,而是根據外層(函數或者全局)做用域來決定this
箭頭函數this的定義:箭頭函數中的this是在定義函數的時候綁定,而不是在執行函數的時候綁定 。
var name = 'lyq';
var obj = {
name : 'zs',
getName:function() {
console.log( this.name )
}
}
obj.getName(); //zs
複製代碼
var name = 'lyq';
var obj = {
name : 'zs',
getName:()=>{
console.log( this.name )
}
}
obj.getName(); //lyq
複製代碼
所謂的定義時候綁定,就是this是繼承自父執行上下文中的this,好比這裏的箭頭函數中的this.name,箭頭函數自己所在的對象爲obj,而obj的父執行上下文就是window,所以這裏的this.name 實際上表示的是window.name,所以輸出的是lyq。(this只有在函數被調用,或者經過構造函數new Object()的形式纔會有this)
注意簡單對象(非函數)是沒有執行上下文的!
在setInterval和setTimeout中傳入函數時,函數中的this會指向window對象。箭頭函數可讓setTimeout裏面的this,綁定定義時所在的做用域,而不是指向運行時所在的做用域。
export default {
data () {
return {
name: zs,
}
},
methods: {
setName () {
setTimeout(() => {
this.name = 0;
}, 500);
}
}
}
複製代碼
此時函數的this指向的是定義它的時候的對象,也就是this指向了data內中對應的變量。若是使用function,this則會指向window,沒法得到當前對象。