談?wù)勀銓his的了解及應用場景?
this綁定方式(共4種方式):默認綁定者冤、隱式綁定、硬綁定(call,apply,bind)睦疫、new綁定
this的五種情況分析
this執(zhí)行主體皆辽,誰把它執(zhí)行的「和在哪創(chuàng)建&在哪執(zhí)行都沒有必然的關(guān)系」
- 函數(shù)執(zhí)行,看方法前面是否有“點”寻馏,沒有“點”,this是window「嚴格模式下是undefined」茄袖,有“點”操软,“點”前面是誰this就是誰
- 給當前元素的某個事件行為綁定方法,當事件行為觸發(fā)宪祥,方法中的this是當前元素本身「排除attachEvent」
- 構(gòu)造函數(shù)體中的this是當前類的實例
- 箭頭函數(shù)中沒有執(zhí)行主體聂薪,所用到的this都是其所處上下文中的this
- 可以基于Function.prototype上的call/apply/bind去改變this指向
- 手撕call/bind/apply源碼
手撕call 原理:就是利用 “點”定this機制,context.xxx=self “obj.xxx=function ” => obj.xxx()
Function.prototype._call = function (context, ...params) {
if (typeof context === "function") {
throw new TypeError('參數(shù)類型錯誤');
return;
}
let key = Symbol('fun');
context = context || window;
context[key] = this;
context[key](...params);
delete context[key];
};
手撕bind (把function執(zhí)行并且改變this即可 args->是執(zhí)行proxy的時候可能傳遞的值)
Function.prototype._bind = function (context, ...params) {
if (typeof context === "function") {
throw new TypeError('參數(shù)類型錯誤');
return;
}
let self = this;
context = context || window;
return function (...arg) {
let key = Symbol('fun');
context[key] = self;
context[key](...[...params, ...arg]);
delete context[key];
};
};
手撕apply
Function.prototype._apply = function (context, params) {
if (typeof context === "function") {
throw new TypeError('參數(shù)類型錯誤');
return;
}
let key = Symbol('fun');
context = context || window;
context[key] = this;
context[key](...params);
delete context[key];
};