成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入call apply bind

Alex / 1807人閱讀

摘要:眾所周知,這三個函數(shù)都是改變執(zhí)行上下文的,那么我們來捋一捋,這些函數(shù)內(nèi)部到底做了什么。

前言

稍微翻了一下call,apply, bind 的各種論壇上的文章, 發(fā)現(xiàn)講的都太淺了,大部分都只講了個用法, 對于實現(xiàn)的原理卻都沒有提,因此,在這里,我寫下這篇文章, 希望能讓大家認(rèn)識到原理所在。

眾所周知, 這三個函數(shù)都是改變執(zhí)行上下文的 , 那么我們來捋一捋,這些函數(shù)內(nèi)部到底做了什么。

call

Function是函數(shù)對象的構(gòu)造方法,call,apply,bind 都是函數(shù)原型上的方法 作為實例 他自身也有這三個方法

圈中的為原型方法, 方塊的為實例方法,另外length屬性就是argument的長度,我們通常調(diào)用一個函數(shù)

function a(){ console.log(this,"a")};
function b(b){console.log(b)}
a.call(b,"我是B的參數(shù)")

執(zhí)行a, 并把context指向b, 這里大家都沒有疑問, 那么問題來了

function a(){ console.log(this,"a")};
function b(){console.log(this,"b")}
a.call.call.call(b,"b")  // 這個結(jié)果是什么呢?
答案是


傻眼了吧 ? 怎么執(zhí)行了B 并且this指向了這個 b字符串

我們來分析一下 call是原型上的方法 那么a.call 他本身也是一個函數(shù) 所以a.call.call.call 不就是a.call.call的原型上的call方法么?
所以不就是執(zhí)行call.call 并改變 call.call的上下文

我們來擼一遍call的源碼,

第一個參數(shù)是上下文, 當(dāng)我們call(null),this指向了window 當(dāng)我們傳入字符串 會把字符串包裝成對象

a.call 執(zhí)行 this是指向a的(誰調(diào)用this 指向誰) 然后又執(zhí)行了a方法,所以內(nèi)部是

Function.prototype.call = function(context){
    context = context ? Object(context):window
    this()   // 因為調(diào)用的都是函數(shù) 所以this是一個函數(shù) 也就是a
}

那這樣并未改變this指向啊,咋辦? 上句話不是說((誰調(diào)用this 指向誰)),所以我們要在內(nèi)部改變掉this,做如下修改

Function.prototype.call = function(context){
    context = context ? Object(context):window
    context.fn = this  
    context.fn() // 通過調(diào)用context.fn 來改變調(diào)用者 實現(xiàn)fn的this指向context 即改變a內(nèi)部的this
}

那么參數(shù)怎么傳呢,我們首先要拿到call的里的參數(shù)

Function.prototype.call = function(context,...args){
    context = context ? Object(context):window
    context.fn = this  
    let r = context.fn(...args) // 通過調(diào)用context.fn 來改變調(diào)用者 實現(xiàn)fn的this指向context 即改變a內(nèi)部的this
    delete context.fn   //刪除屬性
    return r  // 返回執(zhí)行的結(jié)果 
}

現(xiàn)在我們回頭分析一下a.call.call.call(b,"b")
a.call.call是個函數(shù),它調(diào)用call方法 執(zhí)行它 我們進入函數(shù)里面看看

首先把context 也就是b轉(zhuǎn)為字符串對象 它的屬性上賦予fn 也就是a.call.call ,然后執(zhí)行context.fn(...args), 也就是a.call.call("b") 接著刪除fn 返回執(zhí)行結(jié)果 宏觀來看 是a.call.call這個函數(shù)去執(zhí)行并傳入("b") a.call.call 也就是Function.prototype.call 所以就是call("b") 所以啊, 結(jié)果才是this是指向string的b 并且參數(shù)是undefined

Function.prototype.call = function(context,...args){
    context = context ? Object(context):window 
    context.fn = this  //a.call.call("b")
    var r = context.fn(...args) // 通過調(diào)用context.fn 來改變調(diào)用者 實現(xiàn)fn的this指向context 即改變a內(nèi)部的this
    delete context.fn
    return r
}


function a(){ console.log(this,"a")};
function b(args){console.log("我是this:" + this,"我是b的參數(shù)args:" + args)}
a.call.call.call(b,"我到底是參數(shù)呢還是this")

結(jié)論!
一個函數(shù)call2次或者2次以上 執(zhí)行的永遠是b(b需要是一個函數(shù)), 并且call的第二個參數(shù)成為當(dāng)前context

apply

apply 就是參數(shù)不同 直接上代碼

Function.prototype.apply = function(context,...args){
    context = context ? Object(context):window 
    context.fn = this;
    var r; 
    if(args.length){
        r = context.fn(...args) 
        delete context.fn
    }else{
        r = context.fn()
    }
    return r
}


function a(args){ console.log(this,args)};
function b(){console.log("我是this:" + this)}
a.apply(b,[1,2,3,4])

bind 明天寫 累了

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/101838.html

相關(guān)文章

  • JavaScript深入bind的模擬實現(xiàn)

    摘要:也就是說當(dāng)返回的函數(shù)作為構(gòu)造函數(shù)的時候,時指定的值會失效,但傳入的參數(shù)依然生效。構(gòu)造函數(shù)效果的優(yōu)化實現(xiàn)但是在這個寫法中,我們直接將,我們直接修改的時候,也會直接修改函數(shù)的。 JavaScript深入系列第十一篇,通過bind函數(shù)的模擬實現(xiàn),帶大家真正了解bind的特性 bind 一句話介紹 bind: bind() 方法會創(chuàng)建一個新函數(shù)。當(dāng)這個新函數(shù)被調(diào)用時,bind() 的第一個參數(shù)...

    FingerLiu 評論0 收藏0
  • this總結(jié)【2】—— call/applybind

    摘要:和概覽我們要將歸為一類,單獨歸為一類三者的共同點是都可以指定和都是綁定在的原型上的,所以的實例都可以調(diào)用這三個方法至于為什么,看完這篇文章你就懂了如果你不懂什么是實例的話,請移步深入淺出面向?qū)ο蠛驮透拍钇钊霚\出面向?qū)ο蠛驮透拍钇谝粋€ 1.call/apply和bind概覽 我們要將call/apply歸為一類,bind單獨歸為一類 三者的共同點是都可以指定this call/...

    wudengzan 評論0 收藏0
  • 深入理解JavaScript(三):獲取數(shù)組中的最大值方法(this,apply

    摘要:三個方法的作用,都是改變的指向,只是用法稍微有些區(qū)別什么是既不指向函數(shù)自身,也不指函數(shù)的詞法作用域。它在函數(shù)定義的時候是確定不了的在函數(shù)被調(diào)用時才發(fā)生的綁定,也就是說具體指向什么,取決于你是怎么調(diào)用的函數(shù)。 1.排序法 思路:給數(shù)組先排序(由大到小排序),第一項就是最大值 let arr = [1,5,6,7,9,20,40,2,3]; let max1 = arr.sort(func...

    canopus4u 評論0 收藏0
  • call,apply and bind in JavaScript

    摘要:文章盡量使用大量實例進行講解,它們的使用場景。在嚴(yán)格模式下,函數(shù)被調(diào)用后,里面的默認(rèn)是后面通過調(diào)用函數(shù)上的和方法,該變指向,函數(shù)里面的指向。利用,可以傳入外層的上下文。同樣適用的還有,里面的對象,它也是一種類數(shù)組對象。 call,apply and bind in JavaScript 在ECMAScript中,每個函數(shù)都包含兩個繼承而來的方法:apply() 和 call(),這兩個...

    JohnLui 評論0 收藏0
  • JavaScript深入callapply的模擬實現(xiàn)

    摘要:深入系列第十篇,通過和的模擬實現(xiàn),帶你揭開和改變的真相一句話介紹方法在使用一個指定的值和若干個指定的參數(shù)值的前提下調(diào)用某個函數(shù)或方法。如果有錯誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,請?wù)必給予指正,十分感謝。 JavaScript深入系列第十篇,通過call和apply的模擬實現(xiàn),帶你揭開call和apply改變this的真相 call 一句話介紹 call: call() 方法在使用一個指定的 this...

    miya 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<