当前位置:网站首页>Simple implementation of call, bind and apply
Simple implementation of call, bind and apply
2022-07-07 12:35:00 【Xiaoding Chong duck!】
Preface :
These three are all functions api, Used to change this The direction of , Enable an object to call another method that does not belong to it , The core idea is through Change the this Point to , Borrow others' methods .
One 、call
adopt Object call implicit binding this Method implementation of , Because execution obj1.getName.myCall(obj), be myCall Medium this It means pointing. obj1.getName Of , Then add the method to the object you want to use .
Function.prototype.myCall = function (context = window, ...args) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
// here this Is refers to [Function: getName], To add methods to context On
context.$fn = this;
// Call the function implicitly
const result = context.$fn(...args);
// Remove added properties
delete context.$fn;
// Returns the return value of a function call
return result;
}But hang the function on the incoming object (context) in , In order to avoid the problem of duplicate name coverage , have access to symbol rewrite , as follows :
Function.prototype.myCall = function (context = window, ...args) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
// here this Is refers to [Function: getName], To add methods to context On
let fn = Symbol('call');
context[fn] = this;
// Call the function implicitly
const result = context[fn](...args);
// Remove added properties
delete context[fn];
// Returns the return value of a function call
return result;
}verification :
let obj = {
name: 'obj'
};
let obj1 = {
name: 'obj1',
getName: function (age, hobby) {
return this.name + ' This year, ' + age + ' year , like ' + hobby;
}
};
console.log(obj1.getName.myCall(obj, 12, ' Sing a song ')); // obj This year, 12 year , Like singing
Two 、apply
apply The implementation principle is the same , Only the format of parameter transmission is different , Just put the args Just change it
Function.prototype.myApply = function (context = window, args = []) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
// here this Is refers to [Function: getName], To add methods to context On
context.$fn = this;
// Call the function implicitly
const result = context.$fn(...args);
// Remove added properties
delete context.$fn;
// Returns the return value of a function call
return result;
}verification :
let obj = {
name: 'obj'
};
let obj1 = {
name: 'obj1',
getName: function (age, hobby) {
return this.name + ' This year, ' + age + ' year , like ' + hobby;
}
};
console.log(obj1.getName.myApply(obj, [12, ' Sing a song '])); // obj This year, 12 year , Like singing 3、 ... and 、bind
And call and apply The difference is ,bind() Method creates a new function , stay bind() When called , Of this new function this Is specified as bind The first parameter of , The remaining parameters will be specified as parameters of the new function , For calling .
characteristic :
- Returns a new function
- bind As the first parameter of the new function this
- All other parameters (bind And the second call ) As a parameter of the new function
The first one is :
Unsupported use new Call the newly created constructor
Function.prototype.myBind = function () {
let fn = this;
let asThis = arguments[0], args = [...arguments].slice(1);
if (typeof fn !== 'function') {
throw new TypeError('Function.prototype.bind - ' + 'what is trying to be bound is not callable');
}
return function () {
let args2 = [...arguments];
let fnArgs = args.concat(args2);
return fn.apply(asThis, fnArgs);
}
}verification :
let person = {
name: ' Xiaohong '
}
function Person(value) {
return this.name + ' like ' + Array.prototype.slice.call(arguments);
}
let demo = Person.myBind(person, ' Sing a song ');
console.log(demo(' dance ')); // Xiao Hong likes singing , dance But this is the case , If you use new Call the newly created constructor , There will be this Point to the problem of change , as follows :
let person = {
name: ' Xiaohong '
}
function Person(value) {
return this.name + ' like ' + Array.prototype.slice.call(arguments);
}
let Demo = Person.myBind(person, ' Sing a song ');
let demo = new Demo(' dance ');
console.log(demo.name); // undefinedIn fact, at this time, we hope demo.name Or print Xiaohong , But by new after ,this It points to demo example , therefore demo.name Namely undefined
So there is a second way to write , The following writing method supports the use of new Call the newly created constructor :
Function.prototype.myBind = function () {
let fn = this;
// console.log(this);
let asThis = arguments[0], args = Array.prototype.slice.call(arguments, 1);
if (typeof fn !== 'function') {
throw new TypeError('Function.prototype.bind - ' + 'what is trying to be bound is not callable');
}
let resultFn = function () {
let args2 = Array.prototype.slice.call(arguments);
let fnArgs = args.concat(args2);
let that = this instanceof resultFn ? this : asThis;
return fn.apply(that, fnArgs);
};
// Enable the instance to inherit the prototype of the binding function
function tmp() {};
tmp.prototype = fn.prototype;
resultFn.prototype = new tmp();
return resultFn;
}
边栏推荐
- Configure an encrypted web server
- NGUI-UILabel
- 解密GD32 MCU产品家族,开发板该怎么选?
- Realize all, race, allsettled and any of the simple version of promise by yourself
- Will the filing free server affect the ranking and weight of the website?
- 对话PPIO联合创始人王闻宇:整合边缘算力资源,开拓更多音视频服务场景
- ES底层原理之倒排索引
- Pule frog small 5D movie equipment | 5D movie dynamic movie experience hall | VR scenic area cinema equipment
- JS to convert array to tree data
- Learning and using vscode
猜你喜欢

Inverted index of ES underlying principle
![[play RT thread] RT thread Studio - key control motor forward and reverse rotation, buzzer](/img/5f/75549fc328d7ac51f8b97eef2c059d.png)
[play RT thread] RT thread Studio - key control motor forward and reverse rotation, buzzer

BGP third experiment report

<No. 9> 1805. Number of different integers in the string (simple)

PowerShell cs-utf-16le code goes online

2022危险化学品生产单位安全生产管理人员考题及在线模拟考试

@What happens if bean and @component are used on the same class?

In the small skin panel, use CMD to enter the MySQL command, including the MySQL error unknown variable 'secure_ file_ Priv 'solution (super detailed)

"Series after reading" my God! It's so simple to understand throttling and anti shake~

数据库系统原理与应用教程(010)—— 概念模型与数据模型练习题
随机推荐
Tutorial on the principle and application of database system (008) -- exercises on database related concepts
wallys/Qualcomm IPQ8072A networking SBC supports dual 10GbE, WiFi 6
Epp+dis learning path (1) -- Hello world!
Idea 2021 Chinese garbled code
通讯协议设计与实现
In the small skin panel, use CMD to enter the MySQL command, including the MySQL error unknown variable 'secure_ file_ Priv 'solution (super detailed)
【统计学习方法】学习笔记——第四章:朴素贝叶斯法
2022-07-07日报:GAN发明者Ian Goodfellow正式加入DeepMind
MPLS experiment
SQL Lab (41~45) (continuous update later)
【PyTorch实战】用PyTorch实现基于神经网络的图像风格迁移
牛客网刷题网址
【统计学习方法】学习笔记——第五章:决策树
RHSA first day operation
wallys/Qualcomm IPQ8072A networking SBC supports dual 10GbE, WiFi 6
<No. 9> 1805. Number of different integers in the string (simple)
Is it safe to open Huatai's account in kainiu in 2022?
Baidu digital person Du Xiaoxiao responded to netizens' shouts online to meet the Shanghai college entrance examination English composition
普乐蛙小型5d电影设备|5d电影动感电影体验馆|VR景区影院设备
Multi row and multi column flex layout