this解讀

規(guī)范解讀this:

基礎(chǔ)類型(base) | 引用類型(reference)

reference由三個(gè)組成部分豁状,分別是:
base value: 基礎(chǔ)值(null,undefined,string,number,boolean,symbol, or an environment record(環(huán)境記錄))其中的一種驼唱。
referenced name: 屬性名
strict reference: 嚴(yán)格模式

reference組成部分的方法:如GetBase和IsPropertyReference.
1.GetBase
返回reference的base balue

2.IsPropertyReference
如果base value是一個(gè)對(duì)象信卡,就返回true豌汇;

如何確定this的值:

讓我們描述一下:
1.計(jì)算 MemberExpression 的結(jié)果賦值給 ref

2.判斷 ref 是不是一個(gè) Reference 類型

2.1 如果 ref 是 Reference潮梯,并且 IsPropertyReference(ref) 是 true, 那么 this 的值為 GetBase(ref)

2.2 如果 ref 是 Reference靡羡,并且 base value 值是 Environment Record, 那么this的值為 ImplicitThisValue(ref)

2.3 如果 ref 不是 Reference贱鄙,那么 this 的值為 undefined

舉例:

舉最后一個(gè)例子:

var value = 1;

var foo = {
  value: 2,
  bar: function () {
    return this.value;
  }
}

//示例1
console.log(foo.bar());//1
//示例2
console.log((foo.bar)());//1, 因?yàn)閷?shí)際上()并沒(méi)有對(duì)它進(jìn)行計(jì)算
//示例3
console.log((foo.bar = foo.bar)());//2 .賦值的化會(huì)觸發(fā)GetValue方法扼劈,所以返回的值不是reference類型,那么this的值就是undefined蝌矛,在非嚴(yán)格模式下道批,this的值為undefined的時(shí)候,其值會(huì)被隱式地轉(zhuǎn)換為全局對(duì)象入撒。
//示例4
console.log((false || foo.bar)());//2 隆豹; 用了GetValue方法,返回的不是reference類型茅逮,this為undefined
//示例5
console.log((foo.bar, foo.bar)());//2璃赡, 逗號(hào)操作符,也 用了GetValue方法献雅,返回的不是reference類型碉考,this為undefined

補(bǔ)充:
function foo() {
    console.log(this)
}

foo(); 
MemberExpression 是 foo,解析標(biāo)識(shí)符挺身,查看規(guī)范 10.3.1 Identifier Resolution侯谁,會(huì)返回一個(gè) Reference 類型的值:

var fooReference = {
    base: EnvironmentRecord,
    name: 'foo',
    strict: false
};
因?yàn)?base value 是 EnvironmentRecord,并不是一個(gè) Object 類型章钾,還記得前面講過(guò)的 base value 的取值可能嗎墙贱? 只可能是 undefined, an Object, a Boolean, a String, a Number, 和 an environment record 中的一種。

IsPropertyReference(ref) 的結(jié)果為 false贱傀,進(jìn)入下個(gè)判斷:

2.2 如果 ref 是 Reference惨撇,并且 base value 值是 Environment Record, 那么this的值為 ImplicitThisValue(ref)

base value 正是 Environment Record,所以會(huì)調(diào)用 ImplicitThisValue(ref)

查看規(guī)范 10.2.1.1.6府寒,ImplicitThisValue 方法的介紹:該函數(shù)始終返回 undefined魁衙。

所以最后 this 的值就是 undefined。

模擬實(shí)現(xiàn)call:

call分為三步:

1.將函數(shù)設(shè)為對(duì)象的屬性 foo.fn = bar

2.執(zhí)行該函數(shù) foo.fn()

3.刪除該函數(shù) delete foo.fn;

eg:
    var foo = {
        value : 1
    }
    function bar () {
        console.log(this.value)
    }
    bar.call(foo);

也就是:
 var foo = {
     value:1,
     bar: function () {
         console.log(this.value)
     }
 }

 代碼實(shí)現(xiàn)
 Function.prototype.myCall = function (obj) {//
     //1.首先要獲取調(diào)用call的函數(shù)株搔,用this獲取
     obj.fn = this;
     //執(zhí)行函數(shù)
     obj.fn();
     //刪除刪除
     delete obj.fn;
     
 }
代碼實(shí)現(xiàn)第二步剖淀,傳參的時(shí)候
var foo = {
    value: 1
};

function bar(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.value);
}

bar.call(foo, 'kevin', 18);


理解:
arguments = {
    0: foo,
    1: 'kevin',
    2:  18,
    length: 3,
}
var argus = [];
for(var i = 1 , len = arguments.length ; i < len ; i ++) {
    argus.push('arguments['+ i +']')
}

利用eval():參數(shù)是字符串,計(jì)算字符串并執(zhí)行計(jì)算出來(lái)的值
eval('obj.fn('+ argus +')')

Function.prototype.myCall = function (obj) {
    obj.fn = this;
    var argus = [];
    for(var i = 1,len = obj.length; i < len; i++){
        argus.push('obj['+i+']')
    }
    eval('obj.fn('+argus+')');
    delete obj.fn;
}


最終版:當(dāng)指向null的時(shí)候邪狞,視為指向window
Function.prototype.call2 = function (obj) {
    //沒(méi)有值的時(shí)候就指向window
    var obj = obj || window;
    obj.fn = this;

    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }

    var result = eval('obj.fn(' + args +')');

    delete obj.fn
    return result;
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祷蝌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子帆卓,更是在濱河造成了極大的恐慌,老刑警劉巖米丘,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剑令,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡拄查,警方通過(guò)查閱死者的電腦和手機(jī)吁津,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人碍脏,你說(shuō)我怎么就攤上這事梭依。” “怎么了典尾?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵役拴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我钾埂,道長(zhǎng)河闰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任褥紫,我火速辦了婚禮姜性,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘髓考。我一直安慰自己部念,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布氨菇。 她就那樣靜靜地躺著印机,像睡著了一般。 火紅的嫁衣襯著肌膚如雪门驾。 梳的紋絲不亂的頭發(fā)上射赛,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音奶是,去河邊找鬼楣责。 笑死,一個(gè)胖子當(dāng)著我的面吹牛聂沙,可吹牛的內(nèi)容都是我干的秆麸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼及汉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼沮趣!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起坷随,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤房铭,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后温眉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缸匪,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年类溢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凌蔬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砂心,靈堂內(nèi)的尸體忽然破棺而出懈词,到底是詐尸還是另有隱情,我是刑警寧澤辩诞,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布坎弯,位于F島的核電站,受9級(jí)特大地震影響躁倒,放射性物質(zhì)發(fā)生泄漏荞怒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一秧秉、第九天 我趴在偏房一處隱蔽的房頂上張望褐桌。 院中可真熱鬧,春花似錦象迎、人聲如沸荧嵌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)啦撮。三九已至,卻和暖如春汪厨,著一層夾襖步出監(jiān)牢的瞬間赃春,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工劫乱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留织中,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓衷戈,卻偏偏與公主長(zhǎng)得像狭吼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子殖妇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容