成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前端基礎(chǔ):call,apply,bind的的理解

netmou / 1996人閱讀

摘要:和區(qū)別其實他們的作用是一樣的,只是傳遞的參數(shù)不一樣而已。接受個參數(shù),第一個參數(shù)指定了函數(shù)體內(nèi)對象的指向,第二個參數(shù)為數(shù)組或者一個類數(shù)組。看個栗子一個有意思的事在中,多次是無效的。而則會立即執(zhí)行函數(shù)。

背景

前兩天在做小程序的需求的時候用到bind的時候才想起自己對這三的東西的了解比較淺薄,這個時候用的時候就有點怕。時候還是要好好學(xué)習(xí)下,理解下怎么玩。

正文

先說callapply吧:
ECMAScript3給Function的原型定義了兩個方法,他們是Function.prototype.callFunction.prototype.apply. 在實際開發(fā)中,特別是在一些函數(shù)式風(fēng)格的代碼編寫中,call和apply方法尤為有用。

1、call和apply區(qū)別

其實他們的作用是一樣的,只是傳遞的參數(shù)不一樣而已。
apply: 接受2個參數(shù),第一個參數(shù)指定了函數(shù)體內(nèi)this對象的指向,第二個參數(shù)為數(shù)組或者一個類數(shù)組。apply傳入的是一個參數(shù)數(shù)組,也就是將多個參數(shù)組合成為一個數(shù)組傳入,而call則作為call的參數(shù)傳入(從第二個參數(shù)開始)。
舉個栗子:

let obj1 = {
    name: "copyes",
    getName: function(){
        return this.name;
    }
}
let obj2 = {
    name: "Fanchao"
}

console.log(obj1.getName());  // "copyes"
console.log(obj1.getName.call(obj2));  // "Fanchao"
console.log(obj1.getName.apply(obj2));  // "Fanchao"
function showArgs(a, b, c){
    console.log(a,b,c);
}

showArgs.call(this, 3,4,5);
showArgs.apply(this, [5,6,7]);

2、常見的call 和 apply 用法

數(shù)組之間追加

let arr1 = [12, "foo", {name: "fanchao"}, -1024];
let arr2 = ["copyes", "22", 1024];

Array.prototype.push.apply(arr1, arr2);
console.log(arr1);
// [ 12, "foo", { name: "fanchao" }, -1024, "copyes", "22", 1024 ]

獲取數(shù)組中的最大值和最小值

let numbers = [5,665,32,773,77,3,996];
let maxNum = Math.max.apply(Math, numbers);
let maxNum2 = Math.min.call(Math, 5,665,32,773,77,3,996);

console.log(maxNum);
console.log(maxNum2);

驗證是否是數(shù)組(前提是toString()方法沒有被重寫過)

function isArray(obj){
    return Object.prototype.toString.call(obj)  === "[object Array]";
}

console.log(isArray(1));
console.log(isArray([1,2]));

類(偽)數(shù)組使用數(shù)組方法

var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));

3、通過一個面試題去深入理解下apply 和 call

定義一個 log 方法,讓它可以代理 console.log 方法:

// 常規(guī)做法
function log(msg){
    console.log(msg);
}
log(12);
log(1,2)

上面能夠基本解決打印輸出問題,但是下面多參數(shù)的時候就gg了。換個更好的方式吧。

function log(){
    console.log.apply(console, arguments);
}
log(12);
log(1,2)

接下來是要在每一條打印信息前面都要加上一個特定字符串"fanchao`s"又怎么說呢?

function log(){

    let args = Array.prototype.slice.call(arguments);
    
    args.unshift("(fanchao`s)");

    console.log.apply(console, args);
}
log(12);
log(1,2)

4、說完了call和apply,接下來說說bind

bind() 方法與 apply 和 call 很相似,也是可以改變函數(shù)體內(nèi) this 的指向。
MDN的解釋是:bind()方法會創(chuàng)建一個新函數(shù),稱為綁定函數(shù),當(dāng)調(diào)用這個綁定函數(shù)時,綁定函數(shù)會以創(chuàng)建它時傳入 bind()方法的第一個參數(shù)作為 this,傳入 bind() 方法的第二個以及以后的參數(shù)加上綁定函數(shù)運行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù)。
看個栗子:

var func = function(){
    console.log(this.x);
    console.log(arguments);
}

 
func();  // undefined, {}
var obj = {
    x: 2
}
var bar = func.bind(obj,1);

bar(); // 2 , {"0":1}

一個有意思的事:

var bar = function() {
    console.log(this.x);
}
var foo = {
    x: 3
}
var sed = {
    x: 4
}
var func = bar.bind(foo).bind(sed);
func(); //3

var fiv = {
    x: 5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //3

在Javascript中,多次 bind() 是無效的。更深層次的原因, bind() 的實現(xiàn),相當(dāng)于使用函數(shù)在內(nèi)部包了一個 call / apply ,第二次 bind() 相當(dāng)于再包住第一次 bind() ,故第二次以后的 bind 是無法生效的。

5、這三個方法的異同點是什么呢?

還是先看個栗子:

var obj = {
x: 81,
};

var foo = {
getX: function() {
return this.x;
}
}

console.log(foo.getX.bind(obj)()); //81
console.log(foo.getX.call(obj)); //81
console.log(foo.getX.apply(obj)); //81

看到bind后面對了一對括號。區(qū)別是,當(dāng)你希望改變上下文環(huán)境之后并非立即執(zhí)行,而是回調(diào)執(zhí)行的時候,使用 bind() 方法。而 apply/call 則會立即執(zhí)行函數(shù)。

總結(jié)

apply 、 call 、bind 三者都是用來改變函數(shù)的this對象的指向的;
apply 、 call 、bind 三者第一個參數(shù)都是this要指向的對象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后續(xù)參數(shù)傳參;
bind是返回對應(yīng)函數(shù),便于稍后調(diào)用;apply、call則是立即調(diào)用 。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/83332.html

相關(guān)文章

  • 《javascript高級程序設(shè)計》函數(shù)調(diào)用模式 & this深度理解

    在上一篇文章(《javascript高級程序設(shè)計》筆記:Function類型)中稍微提及了一下函數(shù)對象的屬性—this,在這篇文章中有深入的說明: 函數(shù)的三種簡單調(diào)用模式 1 函數(shù)模式 定義的函數(shù),如果單獨調(diào)用,不將其與任何對象關(guān)聯(lián),那么就是函數(shù)調(diào)用模式 function fn(num1, num2) { console.log(this); } // 直接在全局調(diào)用 fn();// w...

    wyk1184 評論0 收藏0
  • Javascript中this與閉包學(xué)習(xí)筆記

    摘要:但是在調(diào)用函數(shù)值執(zhí)行之后并沒有達(dá)到我們想要的效果。解析在這里我們?yōu)槊恳粋€的事件綁定了一個匿名函數(shù),這個匿名函數(shù)就形成了一個閉包。這樣我們就為每個的事件的匿名函數(shù),都保存下了自己閉包變量。 博客原址 理解 Javascript中的this 基于不同的調(diào)用方式this的指向也會有所不同,調(diào)用方式大致有如下幾種: 調(diào)用方式 表達(dá)式 構(gòu)造函數(shù)調(diào)用 new Foo(); 對象方法...

    pinecone 評論0 收藏0
  • 從一道面試題,到“我可能看了假源碼”

    摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。同時,將第一個參數(shù)以外的其他參數(shù),作為提供給原函數(shù)的預(yù)設(shè)參數(shù),這也是基本的顆?;A(chǔ)。 今天想談?wù)勔坏狼岸嗣嬖囶},我做面試官的時候經(jīng)常喜歡用它來考察面試者的基礎(chǔ)是否扎實,以及邏輯、思維能力和臨場表現(xiàn),題目是:模擬實現(xiàn)ES5中原生bind函數(shù)。也許這道題目已經(jīng)不再新鮮,部分讀者也會有思路來解答。社區(qū)上關(guān)于原生bind的研...

    Carson 評論0 收藏0
  • 從一道面試題,到“我可能看了假源碼”

    摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。同時,將第一個參數(shù)以外的其他參數(shù),作為提供給原函數(shù)的預(yù)設(shè)參數(shù),這也是基本的顆?;A(chǔ)。 今天想談?wù)勔坏狼岸嗣嬖囶},我做面試官的時候經(jīng)常喜歡用它來考察面試者的基礎(chǔ)是否扎實,以及邏輯、思維能力和臨場表現(xiàn),題目是:模擬實現(xiàn)ES5中原生bind函數(shù)。也許這道題目已經(jīng)不再新鮮,部分讀者也會有思路來解答。社區(qū)上關(guān)于原生bind的研...

    rockswang 評論0 收藏0
  • 從一道面試題,到“我可能看了假源碼”

    摘要:返回的綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。同時,將第一個參數(shù)以外的其他參數(shù),作為提供給原函數(shù)的預(yù)設(shè)參數(shù),這也是基本的顆?;A(chǔ)。 今天想談?wù)勔坏狼岸嗣嬖囶},我做面試官的時候經(jīng)常喜歡用它來考察面試者的基礎(chǔ)是否扎實,以及邏輯、思維能力和臨場表現(xiàn),題目是:模擬實現(xiàn)ES5中原生bind函數(shù)。也許這道題目已經(jīng)不再新鮮,部分讀者也會有思路來解答。社區(qū)上關(guān)于原生bind的研...

    jlanglang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<