javasrcipt----call,apply,bind(整理)

(1)call 和 apply 的功能相同,區別在於傳參的方式不一樣:
fn.call() 具有一個指定的this值和分別地提供的參數(參數的列表)。
fn.apply()具有一個指定的this值,以及作爲一個數組(或類數組對象)提供的參數。
(2)call,aplly和bind的模擬實現
call代碼實現

Function.prototype.call=function(context){
    /** 如果第一個參數傳入的是 null 或者是 undefined, 那麼指向this指向 window/global */
    /** 如果第一個參數傳入的不是null或者是undefined, 那麼必須是一個對象 */
     if(!context){
         context = typeof window === 'undefined' ?global:window
     }
     console.log(this)
     // 這裏的context---foo對象
     context.fn = this;  //將bar函數掛在到當前傳入的對象的一個方法上
     // this--bar函數
     let rest = [...arguments].slice(1)  //獲取參數
     let result = context.fn(...rest)  //執行方法,傳入剩餘的參數
     delete context.fn;  //刪除掛載的方法
     return result;  //返回結果
 }
 var foo = {
     name: 'Selina'
 }
 var name = 'Chirs';
 function bar(job, age) {
     console.log(this.name);
     console.log(job, age);
 }
 bar.call(foo,'cccc',20)

apply代碼實現(apply的第二個參數是數組或類數組)

Function.prototype.apply = function(context,rest){
     if(!context){
         context = typeof window==='undefined' ?global:window
     }
     context.fn = this
     let result
     if(rest === undefined || rest === null){
         result = context.fn(rest)
     }else if(typeof rest === 'object'){
         result = context.fn(...rest)
     }

     delete context.fn
     return result
 }

bind代碼實現

Function.prototype.myBind = function(context){ //context = {name: "Yvette"}
     if(typeof this !=='function'){
         throw new TypeError('not a function')
     }
     const me = this  //me = ƒ person(age, job, gender)
     const args = [...arguments].slice(1)
     return function F(){
         // 判斷是否用作構造函數
         if(this instanceof F){
             console.log('5555')
             return new me(...args, ...arguments)
         }
         console.log('88888')
         // 用作普通函數
         return me.apply(context, args.concat(...arguments))
     }
 }
 var name = 'Jack';
 function person(age, job, gender){
     console.log(this.name , age, job, gender);
 }
 var Yve = {name : 'Yvette'};
 let result = person.myBind(Yve, 22, 'enginner')('female');

第一遍代碼走到return,並沒有執行return裏面的代碼,而是再次走到了如圖所示。說明bind此時返回的是一個函數,如果想要執行代碼,必須是函數的調用
在這裏插入圖片描述
第二遍代碼進入return的內部
在這裏插入圖片描述
接着向下執行
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章