首先需要理解:
1.this的指向在函數(shù)定義的時候并不能確定this的指向
2.this的最終指向是那個調(diào)用它的直接對象(注意兩個詞 :1.最終指向 2. 直接對象)
列子1
function a () {
var user = '趙老二';
console.log(this.user)//undefined
console.log(this)//window
}
a() //a()==window.a()
按照上面手的this指向調(diào)用它的直接對象恭金,那么這個調(diào)用的對象為window她按,所以this指向window
列子2
let a = {
user:'趙老二',
fn: function () {
console.log(this.user)//趙老二
console.log(this)//{user: "趙老二", fn: ?}對象
}
}
a.fn()
fn()的直接調(diào)用對象是a,所有this指向a随闺,這里再次強(qiáng)調(diào)一點,this的指向在函數(shù)創(chuàng)建的時候是決定不了的位仁,在調(diào)用的時候才能決定携悯,誰調(diào)用的就指向誰,一定要搞清楚這個涨岁。
列子3
let a = {
user:'趙老二',
fn: function () {
console.log(this.user)//undefined
console.log(this)//window
}
}
let b=a.fn
b()
這里this指向的是window,是不是有些蒙了吉嚣?其實是因為你沒有理解一句話梢薪,這句話同樣至關(guān)重要。
this永遠(yuǎn)指向最后調(diào)用它的那個對象尝哆,這里b=a.fn并沒有執(zhí)行秉撇,只是一個賦值的過程,b()才進(jìn)行調(diào)用秋泄,并且在window下直接調(diào)用的所以this指向window
列子5
var o = {
a:10,
b:{
fn:function(){
console.log(this.a); //undefined
console.log(this);//{fn: ?}
}
}
}
o.b.fn();
這里要記住一句話琐馆,this指向的永遠(yuǎn)是調(diào)用它的直接對象,所以上面的this指向的是b對象
再次說明:this指向的是最終調(diào)用該方法的直接對象印衔;
構(gòu)造函數(shù)版的this
function Fn(){
this.user = "趙老二";
}
var a = new Fn();
console.log(a.user); //趙老二
這里之所以對象a可以點出函數(shù)Fn里面的user是因為new關(guān)鍵字可以改變this的指向,將這個this指向?qū)ο骯姥敛,為什么我說a是對象奸焙,因為用了new關(guān)鍵字就是創(chuàng)建一個對象實例,理解這句話可以想想我們的例子3彤敛,我們這里用變量a創(chuàng)建了一個Fn的實例(相當(dāng)于復(fù)制了一份Fn到對象a里面)与帆,此時僅僅只是創(chuàng)建,并沒有執(zhí)行墨榄,而調(diào)用這個函數(shù)Fn的是對象a玄糟,那么this指向的自然是對象a,那么為什么對象a中會有user袄秩,因為你已經(jīng)復(fù)制了一份Fn函數(shù)到對象a中阵翎,用了new關(guān)鍵字就等同于復(fù)制了一份逢并。
添加手動實現(xiàn)new的過程
function Fn() {
this.user ='趙老二';
}
function newfn(fn) {
let obj = {};
//此外因為 shift 會修改原數(shù)組,所以 arguments 會被去除第一個參數(shù)
const Constructor = [].shift.call(arguments)
// 將obj的原型指向構(gòu)造函數(shù)的原型對象郭卫,這樣obj就可以訪問構(gòu)造函數(shù)原型上的屬性
obj.__proto__ = Constructor.prototype
// 將構(gòu)造函數(shù)的this指向obj乃摹,這樣obj就可以訪問到構(gòu)造函數(shù)中的屬性
Constructor.apply(obj, arguments);
return obj;
}
newfn(Fn) //Fn{user:'趙老二'}
更新一個小問題當(dāng)this碰到return時
function fn()
{
this.user = '趙老二';
return {};
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = '趙老二';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
再來
function fn()
{
this.user = '趙老二';
return 1;
}
var a = new fn;
console.log(a.user); //趙老二
function fn()
{
this.user = '趙老二';
return undefined;
}
var a = new fn;
console.log(a.user); //趙老二