Function.prototype.call()
åºçº¿
广æ³å¯ç¨
èª 2015å¹´7æ èµ·ï¼æ¤ç¹æ§å·²å¨ä¸»æµæµè§å¨ä¸å¾å°æ¯æï¼å¯å¨å¤§å¤æ°è®¾å¤åæµè§å¨çæ¬ä¸æ£å¸¸ä½¿ç¨ã
Function å®ä¾ç call() æ¹æ³ä¼ä»¥ç»å®ç this å¼åé个æä¾çåæ°è°ç¨è¯¥å½æ°ã
å°è¯ä¸ä¸
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = "food";
}
console.log(new Food("cheese", 5).name);
// Expected output: "cheese"
è¯æ³
call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, arg2)
call(thisArg, arg1, arg2, /* â¦, */ argN)
åæ°
thisArg-
å¨è°ç¨
funcæ¶è¦ä½¿ç¨çthiså¼ã妿彿°ä¸å¨ä¸¥æ ¼æ¨¡å¼ä¸ï¼nullåundefinedå°è¢«æ¿æ¢ä¸ºå ¨å±å¯¹è±¡ï¼å¹¶ä¸åå§å¼å°è¢«è½¬æ¢ä¸ºå¯¹è±¡ã arg1, â¦, argNå¯é-
彿°çåæ°ã
è¿åå¼
ä½¿ç¨æå®ç this å¼ååæ°è°ç¨å½æ°åçç»æã
æè¿°
夿³¨ï¼è¿ä¸ªå½æ°å ä¹ä¸ apply() ç¸åï¼åªæ¯å½æ°ç忰以å表çå½¢å¼éä¸ªä¼ éç» call()ï¼èå¨ apply() ä¸å®ä»¬è¢«ç»åå¨ä¸ä¸ªå¯¹è±¡ä¸ï¼é常æ¯ä¸ä¸ªæ°ç»ââä¾å¦ï¼func.call(this, "eat", "bananas") ä¸ func.apply(this, ["eat", "bananas"])ã
é常ï¼å¨è°ç¨å½æ°æ¶ï¼å½æ°å
é¨ç this 弿¯è®¿é®è¯¥å½æ°ç对象ãä½¿ç¨ call()ï¼ä½ å¯ä»¥å¨è°ç¨ç°æå½æ°æ¶å°ä»»æå¼åé
ç» thisï¼èæ éé¦å
å°å½æ°éå å°å¯¹è±¡ä¸ä½ä¸ºå±æ§ãè¿æ ·å¯ä»¥å°ä¸ä¸ªå¯¹è±¡çæ¹æ³ç¨ä½éç¨çå®ç¨å½æ°ã
è¦åï¼ä¸è¦ä½¿ç¨ call() æ¥é¾å¼è°ç¨æé 彿°ï¼ä¾å¦ï¼å®ç°ç»§æ¿ï¼ãè¿ä¼å°æé 彿°ä½ä¸ºæ®é彿°è°ç¨ï¼è¿æå³ç new.target çå¼ä¸º undefinedï¼èç±»ä¼æåºé误ï¼å 为å®ä»¬ä¸è½å¨æ²¡æ new çæ
åµä¸è¢«è°ç¨ã请æ¹ç¨ Reflect.construct() æ extendsã
示ä¾
>ä½¿ç¨ call() è°ç¨å½æ°å¹¶æå® this å¼
å¨ä¸é¢ç示ä¾ä¸ï¼å½æä»¬è°ç¨ greet æ¶ï¼this çå¼å°ç»å®å°å¯¹è±¡ objï¼å³ä½¿ greet 䏿¯ obj çæ¹æ³ã
function greet() {
console.log(this.animal, "çç¡ç æ¶é´ä¸è¬å¨", this.sleepDuration, "ä¹é´");
}
const obj = {
animal: "ç«",
sleepDuration: "12 å° 16 å°æ¶",
};
greet.call(obj); // ç« çç¡ç æ¶é´ä¸è¬å¨ 12 å° 16 å°æ¶ ä¹é´
ä½¿ç¨ call() å¨ä¸æå®ç¬¬ä¸ä¸ªåæ°çæ åµä¸è°ç¨å½æ°
妿çç¥ç¬¬ä¸ä¸ª thisArg åæ°ï¼åé»è®¤ä¸º undefinedãå¨éä¸¥æ ¼æ¨¡å¼ä¸ï¼this å¼å°è¢«æ¿æ¢ä¸º globalThisï¼ç±»ä¼¼äºå
¨å±å¯¹è±¡ï¼ã
globalThis.globProp = "Wisen";
function display() {
console.log(`globProp ç弿¯ ${this.globProp}`);
}
display.call(); // è¾åºâglobProp ç弿¯ Wisenâ
å¨ä¸¥æ ¼æ¨¡å¼ä¸ï¼this çå¼ä¸ä¼è¢«æ¿æ¢ï¼å æ¤å®ä¿æä¸º undefinedã
"use strict";
globalThis.globProp = "Wisen";
function display() {
console.log(`globProp ç弿¶ ${this.globProp}`);
}
display.call(); // æåº TypeError: Cannot read the property of 'globProp' of undefined
å°æ¹æ³è½¬æ¢ä¸ºå®ç¨å½æ°
call() å ä¹çåäºæ®é彿°è°ç¨ï¼åªæ¯å° this ä½ä¸ºæ®éåæ°ä¼ å
¥ï¼è䏿¯ä½ä¸ºå½æ°æå¨ç对象å¼ãè¿ç±»ä¼¼äºéç¨çå®ç¨å½æ°ç工使¹å¼ï¼ä½ å¯ä»¥ä½¿ç¨ map(array, callback) æ¥ä»£æ¿ array.map(callback)ï¼è¿æ ·å¯ä»¥é¿å
对 Array.prototype è¿è¡ä¿®æ¹ï¼è¿å¯ä»¥å° map ç¨äºä¸æ¯æ°ç»çç±»æ°ç»å¯¹è±¡ï¼ä¾å¦ argumentsï¼ã
以 Array.prototype.slice() 为ä¾ï¼ä½ æ³è¦å°ç±»æ°ç»å¯¹è±¡è½¬æ¢ä¸ºçæ£çæ°ç»ãä½ å¯ä»¥å建ä¸ä¸ªç±»ä¼¼è¿æ ·çå¿«æ·æ¹å¼ï¼
const slice = Array.prototype.slice;
// ...
slice.call(arguments);
请注æï¼ä½ ä¸è½å° slice.call ä¿åå¹¶å°å
¶ä½ä¸ºæ®é彿°è°ç¨ï¼å 为 call() æ¹æ³ä¹ä¼è¯»åå®ç this å¼ï¼èè¿ä¸ªå¼åºè¯¥æ¯å®è¦è°ç¨ç彿°ãå¨è¿ç§æ
åµä¸ï¼ä½ å¯ä»¥ä½¿ç¨ bind() æ¥ç»å® call() ç this å¼ãå¨ä¸é¢ç代ç çæ®µä¸ï¼slice() æ¯ä¸ä¸ªç»å®äº this å¼ä¸º Array.prototype.slice() ç Function.prototype.call() ççæ¬ãè¿æå³çé¢å¤ç call() è°ç¨å¯ä»¥è¢«çç¥ï¼
// ä¸åé¢ç¤ºä¾ä¸çâsliceâç¸å
const unboundSlice = Array.prototype.slice;
const slice = Function.prototype.call.bind(unboundSlice);
// ...
slice(arguments);
è§è
| è§è |
|---|
| ECMAScript® 2027 Language Specification> # sec-function.prototype.call> |