bind、call、apply區別?如何實現?

yangkangkang發表於2024-11-16

一、作用:

  call、apply、bind 作用是改變函式執行的上下文,簡而言之就是改變函式執行時的this指向

二、區別

  call:

    1. 傳入的引數不固定

     2.第一個引數是this繫結的物件,後面其餘的引數是傳入函式執行的引數列表

    3. 第一個引數為null、undefined的時候,預設指向window

    4. 改變this指向後原函式會立即執行,且此方法之時臨時改變this一次

  apply:

    1.接收兩個引數

     2.第一個引數是this繫結的物件,第二個引數是函式接受的引數,以陣列的形式傳入

3. 第一個引數為null、undefined的時候,預設指向window

     4. 改變this指向後原函式會立即執行,且此方法之時臨時改變this一次

  bind:

1. 傳入的引數不固定

     2.第一個引數是this繫結的物件,後面其餘的引數是傳入函式執行的引數列表(但這個列表可以分多次傳入)

    3.第一個引數為null、undefined的時候,預設指向window

    4. 改變this指向後不會立即執行,而是返回一個永久改變this指向的函式

    5. 多個連續bind,最後this指向第一次呼叫bind方法的引數決定

            function fn (...args){
                console.log(this,args)
            }
            let obj = {
                name:'張三'
            }
            let obj2 = {
                name:'張三2'
            }
            // apply改變this指向,會立即執行
            fn.apply(obj,[1,2]) // {name:'張三'} [1,2]
            fn([3,4]) // window

            // call改變this指向,會立即執行
            fn.call(obj,5,6)  // {name:'張三'} [5,6]
            fn()  //window


            // bind改變this指向,不會立即執行,需要手動呼叫,引數可分多次傳入,多次bind,this指向第一個物件
            const fn1 = fn.bind(obj,5,6).bind(obj2,7,8)
            fn1() //  {name:'張三'}  [5,6,7,8]
            fn1(9,0) // {name:'張三'} [5,6,7,8,9,0]  

三、手寫實現call、bind、apply 函式

  手寫call、bind、apply

相關文章