摘要:簡單比較一下與和的第一個實參是要調用函數的母對象,它是調用上下文,在函數體內通過來獲得對它的引用。而則會立即執行函數。
簡單比較一下call() apply() bind()
call()與apply()《JavaScript: The Definitive Guide》
call()和apply()的第一個實參是要調用函數的母對象,它是調用上下文,在函數體內通過this來獲得對它的引用。簡單來說就是把一個方法綁定到一個對象上去調用:
栗如,要想以對象o的方法來調用函數f():
f.call(o); f.apply(o);
其實相當于:
o.m = f; //將f存儲為o的臨時方法 o.m(); //調用它,不傳入參數 delete o.m; //將臨時方法刪除
--> 對于call(),第一個實參之后的所有實參就是要傳入待調用函數的值。栗如:
//以對象o的方法的形式調用函數f(),并傳入兩個參數 f.call(o, 1, 2);
--> 對于apply(),它的實參都放入一個數組當中:
f.apply(o,[1, 2]);
給apply()傳入的參數數組可以是任意長度的,栗如:
//找出一個數組中最大的數值元素 var biggest = Math.max.apply(Math, array_of_numbers);
傳入apply()的參數數組可以是類數組對象也可以是真實數組。實際上,可以將當前函數的arguments數組直接傳入apply()來調用另一個函數:
//將對象o中名為m的方法替換為另一個方法 //可以在調用原始方法之前和之后記錄日志消息 function trace(o, m) { var original = o[m];//在閉包中保存原始方法 o[m] = function() {//定義新的方法 console.log(new Date(), "Entering", m); var result = original.apply(this, arguments);//調用原始函數 console.log(new Date(), "Exiting", m); return result; }; } //這個新方法是包裹原始方法的另一個泛函數 (monkey-patching)?bind() 方法
bind()是ES5中的方法。
當在函數f()上調用bind()方法并傳入一個對象o作為參數,這個方法將返回一個新的函數,(以函數調用的方式)調用新的函數將會把原始的函數f()當作o的方法來調用。傳入新的函數的任何實參都講傳入原始函數。栗如:
function f(y) { return this.x + y; } var o = { x: 1 }; var g = f.bind(o); g(2); //=> 3
可以用ES3簡單模擬:
function bind(f, o) { if(f.bind) return f.bind(o); else return function() { return f.apply(o, arguments); } }
然而,bind()方法不僅僅是將函數綁定至一個對象----除了第一個參數外,傳入bind()的實參也會綁定至this,這個附帶的應用是一種常見的函數式編程技術,也被稱為“柯里化“。
function f(y, z) { return this.x + y + z } var g = f.bind({ x: 1 }, 2); g(3);//=> 6 this.x綁定到1, y綁定到2, z綁定到3
如果用ES3模擬:
if(!Function.prototype.bind){ Function.prototype.bind = function(o /*, args*/){ //將this和arguments的值保存至變量中 //以便在后面嵌套的函數中可以使用它們 var self = this, boundArgs = arguments; //bind方法的返回值是一個函數 return function(){ //創建一個實參列表,將傳入bind()的第二個及后續的實參傳入這個參數 var args = [], i; for(i=1; ihttp://web.jobbole.com/83642/
深入淺出妙用 Javascript 中 apply、call、bind一個比較:
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三個輸出的都是81,但是注意看使用 bind() 方法的,他后面多了對括號。
也就是說,區別是,當你希望改變上下文環境之后并非立即執行,而是回調執行的時候,使用 bind() 方法。而 apply/call 則會立即執行函數。
一個總結:
apply 、 call 、bind 三者都是用來改變函數的this對象的指向的;
apply 、 call 、bind 三者第一個參數都是this要指向的對象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后續參數傳參;
bind 是返回對應函數,便于稍后調用;apply 、call 則是立即調用 。
一道題:
定義一個 log 方法,讓它可以代理 console.log 方法
function log(){ console.log.apply(console, arguments); }若要給每一個 log 消息添加一個”(app)”的前輟?
//該怎么做比較優雅呢?這個時候需要想到arguments參數是個偽數組,通過 //Array.prototype.slice.call 轉化為標準數組,再使用數組方法unshift function log(){ var args = Array.prototype.slice.call(arguments); args.unshift("(app)"); console.log.apply(console, args); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/82171.html
摘要:不能應用下的等方法。首先我們可以通過給目標函數指定作用域來簡單實現方法保存,即調用方法的目標函數考慮到函數柯里化的情況,我們可以構建一個更加健壯的這次的方法可以綁定對象,也支持在綁定的時候傳參。原因是,在中,多次是無效的。 bind 是返回對應函數,便于稍后調用;apply 、call 則是立即調用 。 apply、call 在 javascript 中,call 和 apply 都是...
摘要:首先我們可以通過給目標函數指定作用域來簡單實現方法保存,即調用方法的目標函數考慮到函數柯里化的情況,我們可以構建一個更加健壯的這次的方法可以綁定對象,也支持在綁定的時候傳參。原因是,在中,多次是無效的。而則會立即執行函數。 bind 是返回對應函數,便于稍后調用;apply 、call 則是立即調用 。 apply、call 在 javascript 中,call 和 apply 都是...
摘要:首先,我們判斷是否存在方法,然后,若不存在,向對象的原型中添加自定義的方法。指向調用它的對象??傊齻€的使用區別都是用來改變函數的對象的指向的第一個參數都是要指向的對象都可以利用后續參數傳參是返回對應函數,便于稍后調用,是立即調用 apply和call都是為了改變某個函數運行時的上下文而存在的(就是為了改變函數內部this的指向),Function對象的方法,每個函數都能調用; 使用a...
摘要:它們有明確的和成員函數的定義,只有的實例才能調用這個的成員函數。用和調用函數里用和來指定函數調用的,即指針的指向。同樣,對于一個后的函數使用或者,也無法改變它的執行,原理和上面是一樣的。 函數里的this指針 要理解call,apply和bind,那得先知道JavaScript里的this指針。JavaScript里任何函數的執行都有一個上下文(context),也就是JavaScri...
摘要:返回值這段在下方應用中有詳細的示例解析?;卣{函數丟失的解決方案綁定回調函數的指向這是典型的應用場景綁定指向,用做回調函數。 showImg(https://segmentfault.com/img/remote/1460000019971331?w=1024&h=680); 函數原型鏈中的 apply,call 和 bind 方法是 JavaScript 中相當重要的概念,與 this...
閱讀 3076·2023-04-26 00:49
閱讀 3734·2021-09-29 09:45
閱讀 1010·2019-08-29 18:47
閱讀 2755·2019-08-29 18:37
閱讀 2738·2019-08-29 16:37
閱讀 3302·2019-08-29 13:24
閱讀 1785·2019-08-27 10:56
閱讀 2357·2019-08-26 11:42