JavaScript | call、apply、bind 用法區別小結

call && apply && bind 用法區別小結面試

摘要

故事開頭,恰逢其時,就行系統的總結下 call apply bind ,這也是面試官常常問的小程序

你知道this指向的問題嗎,簡單說說你的理解?
--------------------------------------------------
我……
複製代碼

簡潔的貼上一段小程序的代碼數組

/** * 生命週期函數--監聽頁面加載 */
  onLoad: function(options) {
      console.log("接收url中的參數",options)
      AuthApis.voteItemListRouter(
          options
      ).then((res) =>{
          console.log(res.data.voteContent)
          let voteItemListvote = res.data
          let voteItemListdetail = res.data.voteContent
          console.log("data",voteItemListvote)
          this.setData({
              voteItemvote:voteItemListvote,
              voteItemList: voteItemListdetail
          })
          console.log('test1',voteItemListdetail,voteItemListvote)
          console.log('test2',voteItemvote,voteItemList)
      })
  },
複製代碼

如上的代碼看起來也沒有什麼問題,控制檯輸出便有點問題,也趁此機會總結一下三者的區別bash

實現效果

call 改變 this 指向;自動執行函數;參數列表形式傳入

// 定義上下文
let ctx = {
  name: `yayxs`
};
// 定義函數
const fn = function(age, sex) {
  console.log(`${this.name}-${age}-${sex}`);
};

// 調用函數
fn(18, `男`);
複製代碼

apply 改變 this 指向;自動執行函數;參數數組形式傳入

const fnCall = function(age, sex) {
  console.log(`call-${this.name}-${age}-${sex}`);
};

// fnCall(18, `男`); // call-undefined-18-男

fnCall.call(ctx, 18, `男`); // call-yayxs-18-男

// 總結:改變this指向,執行函數,參數列表傳入
複製代碼

bind 返回一個改變了的 this 指向的函數;參數列表形式傳入

const fnBind = function(age, sex) {
  console.log(`bind-${this.name}-${age}-${sex}`);
};

fnBind.bind(ctx); // 沒有輸出

const res = fnBind.bind(ctx);

console.log(res); // [Function: bound fnBind]

res(18, "男"); // bind-yayxs-18-男
複製代碼

手寫代碼

假若本身手寫代碼實現callapplyapp

  1. 獲取被綁定的函數
  2. 被綁定的函數追加到劫持替換的對象
  3. 被綁定的函數追加到劫持替換的對象

手寫 call

Function.prototype.myCall = function(ctx, ...params) {
  // console.log(ctx); { name: 'yayxs' }
  // console.log(...params); 18 男
  if (typeof ctx === "object") {
    ctx = ctx || window;
  } else {
    ctx = null;
  }

  // 臨時方法名
  let funcName = Symbol();

  // console.log(funcName);
  ctx[funcName] = this;
  // console.log(this); [Function: testFn]

  ctx[funcName](...params);
  delete ctx[funcName];
};
複製代碼

最後總結

整體來講,call apply bind 三個函數的做用都是用來改變this的指向。目前的 js 還存在回調函數這一現象,尤爲在框架中一些異步回調也是十分的常見,不免this會迷失方向。三者既有不一樣也有類似框架

方法名 做用 是否自動執行 參數列表
call 改變 this 指向 自動執行 通常列表
apply 改變 this 指向 自動執行 數組形式
bind 改變 this 指向 返回一個函數 通常列表

參考閱讀

相關文章
相關標籤/搜索