国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

JavaScript中的call和apply的用途以及區(qū)別

2024-05-06 16:34:30
字體:
供稿:網(wǎng)友

apply 接受兩個參數(shù),第一個參數(shù)指定了函數(shù)體內(nèi)this 對象的指向,第二個參數(shù)為一個帶下標的集合,這個集合可以為數(shù)組,也可以為類數(shù)組,apply 方法把這個集合中的元素作為參數(shù)傳遞給被調(diào)用的函數(shù):

var func = function( a, b, c ){  alert ( [ a, b, c ] ); // 輸出 [ 1, 2, 3 ]};func.apply( null, [ 1, 2, 3 ] );

在這段代碼中,參數(shù) 1、2、3 被放在數(shù)組中一起傳入func函數(shù),它們分別對應(yīng)func參數(shù)列表中的a、b、c。

call 傳入的參數(shù)數(shù)量不固定,跟apply 相同的是,第一個參數(shù)也是代表函數(shù)體內(nèi)的this 指向,從第二個參數(shù)開始往后,每個參數(shù)被依次傳入函數(shù):

var func = function( a, b, c ){  alert ( [ a, b, c ] ); // 輸出 [ 1, 2, 3 ]};func.call( null, 1, 2, 3 );

當調(diào)用一個函數(shù)時,JavaScript 的解釋器并不會計較形參和實參在數(shù)量、類型以及順序上的區(qū)別,JavaScript 的參數(shù)在內(nèi)部就是用一個數(shù)組來表示的。從這個意義上說,apply比call的使用率更高,我們不必關(guān)心具體有多少參數(shù)被傳入函數(shù),只要用apply 一股腦地推過去就可以了。call是包裝在apply上面的一顆語法糖,如果我們明確地知道函數(shù)接受多少個參數(shù),而且想一目了然地表達形參和實參的對應(yīng)關(guān)系,那么也可以用call 來傳送參數(shù)。

call和apply的用途

1. 改變this 指向

call 和apply 最常見的用途是改變函數(shù)內(nèi)部的this 指向,我們來看個例子:

var obj1 = {  name: 'sven'};var obj2 = {  name: 'anne'};window.name = 'window';var getName = function(){  alert ( this.name );};getName(); // 輸出: windowgetName.call( obj1 ); // 輸出: svengetName.call( obj2 ); // 輸出: anne

當執(zhí)行g(shù)etName.call( obj1 )這句代碼時,getName 函數(shù)體內(nèi)的this 就指向obj1 對象,所以此處的

var getName = function(){alert ( this.name );};

實際上相當于:

var getName = function(){alert ( obj1.name ); // 輸出: sven};

在實際開發(fā)中,經(jīng)常會遇到this指向被不經(jīng)意改變的場景,比如有一個div節(jié)點,div節(jié)點的onclick 事件中的this 本來是指向這個div的:

document.getElementById( 'div1' ).onclick = function(){  alert( this.id ); // 輸出:div1};

假如該事件函數(shù)中有一個內(nèi)部函數(shù)func,在事件內(nèi)部調(diào)用func 函數(shù)時,func 函數(shù)體內(nèi)的this就指向了window,而不是我們預(yù)期的div,見如下代碼:

document.getElementById( 'div1' ).onclick = function(){  alert( this.id ); // 輸出:div1  var func = function(){    alert ( this.id ); // 輸出:undefined  }  func();};

這時候我們用call 來修正func 函數(shù)內(nèi)的this,使其依然指向div:

document.getElementById( 'div1' ).onclick = function(){  var func = function(){    alert ( this.id ); // 輸出:div1  }  func.call( this );};

2. Function.prototype.bind

大部分高級瀏覽器都實現(xiàn)了內(nèi)置的Function.prototype.bind,用來指定函數(shù)內(nèi)部的this 指向,即使沒有原生的Function.prototype.bind 實現(xiàn),我們來模擬一個也不是難事,代碼如下:

Function.prototype.bind = function( context ){var self = this; // 保存原函數(shù)return function(){ // 返回一個新的函數(shù)    return self.apply( context, arguments ); // 執(zhí)行新的函數(shù)的時候,會   把之前傳入的context  // 當作新函數(shù)體內(nèi)的this  }};var obj = {  name: 'sven'};var func = function(){  alert ( this.name ); // 輸出:sven}.bind( obj);func();

我們通過Function.prototype.bind 來“包裝”func 函數(shù),并且傳入一個對象context 當作參數(shù),這個context 對象就是我們想修正的this 對象。

在Function.prototype.bind 的內(nèi)部實現(xiàn)中,我們先把func 函數(shù)的引用保存起來,然后返回一個新的函數(shù)。當我們在將來執(zhí)行func 函數(shù)時,實際上先執(zhí)行的是這個剛剛返回的新函數(shù)。在新函數(shù)內(nèi)部,self.apply( context, arguments )這句代碼才是執(zhí)行原來的func 函數(shù),并且指定context對象為func 函數(shù)體內(nèi)的this。

這是一個簡化版的Function.prototype.bind 實現(xiàn),通常我們還會把它實現(xiàn)得稍微復(fù)雜一點,

使得可以往func 函數(shù)中預(yù)先填入一些參數(shù):

Function.prototype.bind = function(){  var self = this, // 保存原函數(shù)  context = [].shift.call( arguments ), // 需要綁定的this 上下文  args = [].slice.call( arguments ); // 剩余的參數(shù)轉(zhuǎn)成數(shù)組  return function(){ // 返回一個新的函數(shù)    return self.apply( context, [].concat.call( args, [].slice.call(  arguments ) ) );    // 執(zhí)行新的函數(shù)的時候,會把之前傳入的context 當作新函數(shù)體內(nèi)的this    // 并且組合兩次分別傳入的參數(shù),作為新函數(shù)的參數(shù)  }};var obj = {  name: 'sven'};var func = function( a, b, c, d ){  alert ( this.name ); // 輸出:sven  alert ( [ a, b, c, d ] ) // 輸出:[ 1, 2, 3, 4 ]}.bind( obj, 1, 2 );func( 3, 4 );

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持VeVb武林網(wǎng)!


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 抚州市| 和政县| 靖边县| 桐城市| 株洲县| 绥芬河市| 山阳县| 泽普县| 涡阳县| 城市| 南部县| 临海市| 鄂托克前旗| 莱芜市| 汝城县| 托克逊县| 通州区| 枞阳县| 凤阳县| 安陆市| 石门县| 鄯善县| 阳泉市| 榆社县| 阜城县| 大化| 临泽县| 西充县| 霍州市| 邛崃市| 兴化市| 陕西省| 商河县| 应用必备| 南涧| 铜鼓县| 平果县| 马关县| 大竹县| 浪卡子县| 东乡族自治县|