javascript 中 的apply,call 和 bind的區(qū)別

apply和call

在js中,apply和call都是用來改變函數(shù) 執(zhí)行時上下文 的,也就是改變 this 的指向。
js中上下文分為定義時上下文,執(zhí)行時上下文,且上下文this的指向是可以改變的。

舉一個栗子??

new 一個人 叫nathan,為黃皮膚

function Preson (name) {
  this.name = name
}
Preson.prototype.skinColor = 'yellow'
Preson.prototype.say = function () {
  console.log('Hello World, My name is ' + this.name + ' and my skin color is ' + this.skinColor)
}
let nathan = new Person('nathan')
nathan.say() // Hello World, My name is nathan and my skin color is 'yellow'

當存在另一個黑人,需要從nathan的口中說出他的膚色

let mike = {
  skinColor: 'black',
  name: 'mike'
}
nathan.say.apply(mike) // Hello World, My name is mike and my skin color is black
nathan.say.call(mike) // Hello World, My name is mike and my skin color is black
nathan.say() // Hello World, My name is nathan and my skin color is yellow

可以看出 applycall 都改變了 this 中的 ** skinColor** 和 name 對應的值,但是當我再使用 nathansay() 方法時,nathan 說的還是和之前的結果是一樣的
這樣就可以形象的看作是,mikenathan 說了話,而不是 mike 直接變成了 nathan

apply和call區(qū)別

兩者的區(qū)別就是傳參的方式不同

function Preson (name) {
this.name = name
}
Preson.prototype.skinColor = 'yellow'
Preson.prototype.say = function (old, sex) {
  console.log('Hello World, My name is ' + this.name + ' and my skin color is ' + this.skinColor + '. I\'m a ' + sex + ' and I ' + old + 'years old')
}
let nathan = new Preson('nathan')
nathan.say(12, 'boy')
let mike = {
  skinColor: 'black',
  name: 'mike'
}
let detail = [20, 'girl']
nathan.say.apply(mike, detail)
nathan.say.call(mike, ...detail)

apply除了第一個傳入的改變this內(nèi)的參數(shù)之外,函數(shù)本身的參數(shù)使用數(shù)組的形式傳入,而call則是按順序傳入

在toString()方法沒有被重寫的前提下:我寫了以下的工具函數(shù)來判斷數(shù)據(jù)類型,這里只寫了判斷數(shù)組的,還可以寫String object

function isArray (data, type) {
  let t = ''
  if (arguments.length === 2) {
    t = type.toLowerCase()
  } else {
    t = 'array'
  }
  if (t === 'array') {
    if (!Array.isArray) {
      Array.isArray = function (arg) {
        return Object.prototype.toString.call(arg) === '[object Array]'
      }
    }
    return ArrayisArray(data)
  }
}

bind

在函數(shù)后面鏈式使用bind(),第一個參數(shù)是改變函數(shù)內(nèi)部的this為這個參數(shù),后面的參數(shù)是在調(diào)用目標函數(shù)時,預先添加到綁定函數(shù)的參數(shù)

var module = {
  x: 42,
  getX: function(a) {
    if (a) {
        console.log(a);
    }
    return this.x;
  }
}
var unboundGetX = module.getX;
console.log(unboundGetX());// output: undefined

var boundGetX = unboundGetX.bind(module, 'arg1');
console.log(boundGetX());
// ouput: arg1
// output: 42

然后多次綁定bind是無效的。

三者之間的區(qū)別

當你需要在函數(shù)改變上下文之后不是馬上執(zhí)行,在回調(diào)時執(zhí)行,使用bind

apply和call會立即執(zhí)行函數(shù)

我是看了 此人 的文章之后,按照自己的理解再次寫的這篇文章,使自己記憶深刻,然后有一些話也做了簡單的自己理解的義譯,歡迎評論提錯
peace~
author: nathan[圖片上傳中...(IMG_6061.JPG-daecac-1594702430431-0)]

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容