js中call和apply的實現原理


js中call和apply的實現原理           

 

 

實現call的思路: 

/*
  還有就是call方法是放在Function().prototype上的也就是構造函數才有的call方法
   (我門可以查看自己的方法的原型鏈上的也就是
    方法名.__proto__==Function.prototype 自己定義的構造函數通過原型鏈可以找到原型 Function.prototype中就有call方法 )
   那我門就在Function.prototype中定義一個自己的方法實現call的功能
*/
   Function.prototype.myCall = function() {
 
    /* 先接受參數把對象和參數區分開 center:對象 arg:參數 */
    let [center, ...arg] = [...arguments]
 
    /* 重點 用傳遞過來的對象 添加一個屬性賦值為this(這是我感覺最神奇的地方 后面通過隱式綁定) */
    center.storageA = this;
 
     /* 然后執行調用call這個方法的對象 */
     /* js中有誰調用的this 就指向誰->this的隱式綁定 然后接收執行的結果 */
    let result = center.storageA(...arg)
 
    /* 這句話 就是隱式綁定 center.that(...arg) <==>this.(...arg) 這兩句話等同
    在這個函數中this指向的是調用call的這個方法 就是應為Person.call 導致this指向了 Person
    同樣的方法通過 center.that讓this指向了center
    這個that屬性是自己為了儲存調用call的對象的 在原來的對象中是沒有這個屬性的所有要刪除這個屬性
    不刪除的話可以看到that中的結構式Person對象  影響繼承的結構
    */
    delete center.storageA return result;
  }
 

補充下:對象的隱式調用,就是在A.call(B)的時候,在call函數內部的this是指向A的(應為js中誰調用this就指向誰的)。

call的第一個參數B是一個我們想讓A函數內部屬性指向的對象,只能再通過隱式調用,把函數A聲明在B的一個屬性中,也就是B.storageA =A ,

我們執行A(),也就是在執行B.storageA() 。把結果返回出去,就是實現了this.指向的變化了

 

實現apply的思路:

apply和call的區別是參數的傳遞方式不一樣apply的第二個參數式一個數組 

 

實際應用 

Function.prototype.myCall = function() {
    let [center, ...arg] = [...arguments]
    center.that = this;
    let result = center.that(...arg)
    delete center.that
    return result;
}
 
  function Person() {
    this.firstname = 'Join'
    this.say = function() {
      console.log(`my name is: ${this.firstname} ~${this.listname}`)
    }
   }
 
  function Baby(name) {
    this.listname = name Person.myCall(this, this.name)
  }
 
  let a = new Baby('inter')
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM