Implement apply call bind

apply

use ES6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Function.prototype.myCall = function(obj, ...args) {
if (obj === null || obj === undefined) {
obj = window;
} else {
obj = Object(obj);
}
obj._fn = this;
obj._fn(...args);
delete obj._fn;
}

var test = {
name: 'test'
}

var obj = {
name: 'obj',
fun: function() {
console.log(this.name, ...arguments);
}
}

obj.fun(1,2,3); // obj 1 2 3
obj.fun.myCall(test, 1,2,3) // test 1 2 3

use eval

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Function.prototype.myCall = function(obj) {
if (obj === null || obj === undefined) {
obj = window;
} else {
obj = Object(obj);
}
let arg = [];
for(let i=1; i < arguments.length; i++) {
arg.push('arguments[' + i + ']');
}
obj._fn = this;
eval('obj._fn(' + arg + ')');
delete obj._fn;
}
var test = {
name: 'test'
}

var obj = {
name: 'obj',
fun: function() {
console.log(this.name, ...arguments);
}
}
obj.fun(1,2,3); // obj 1 2 3
obj.fun.myCall(test, 1,2,3) // test 1 2 3

call

use ES6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Function.prototype.myApply = function(obj, arr) {
if (obj === null || obj === undefined) {
obj = window;
} else {
obj = Object(obj);
}
obj._fn = this;
obj._fn(...arr);
delete obj._fn;
}
var test = {
name: 'test'
}

var obj = {
name: 'obj',
fun: function() {
console.log(this.name, ...arguments);
}
}
obj.fun([1,2,3]); // obj 1 2 3
obj.fun.myApply(test, [1,2,3]) // test 1 2 3

use eval

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Function.prototype.myApply = function(obj, arr) {
if (obj === null || obj === undefined) {
obj = window;
} else {
obj = Object(obj);
}
let args = [];
let val ;
for(let i = 0 ; i < arr.length ; i++){
args.push( 'arr[' + i + ']' ) ;
}
obj._fn_ = this;
val = eval( 'obj._fn_(' + args + ')' );
delete obj._fn_;
return val
}
var test = {
name: 'test'
}

var obj = {
name: 'obj',
fun: function() {
console.log(this.name, ...arguments);
}
}
obj.fun(1,2,3); // obj 1 2 3
obj.fun.myCall(test, 1,2,3) // test 1 2 3

bind

1
2
3
4
5
6
7
8
Function.prototype.myBind = function(obj, ...arg1) {
return (...arg2) => {
let args = arg1.concat(arg2);
obj._fn = this;
obj._fn(args);
delete obj._fn;
}
}

Update at 2020-04-02

call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function.prototype.myOwnCall = function(someOtherThis) {
someOtherThis = someOtherThis || global;
var uniqueID = "00" + Math.random();
while(someOtherThis.hasOwnProperty(uniqueID)) {
uniqueID = "00" + Math.random();
}
someOtherThis[uniqueID] = this;
const args = [];
for(let i = 1, len = arguments.length; i < len; i++) {
args.push("arguments[" + i + "]");
}
var result = eval("someOtherThis[uniqueID](" + args + ")");
delete someOtherThis[uniqueID];
return result;
}

apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Function.prototype.myApply = function(someOtherThis, arr) {
someOtherThis = someOtherThis || global;
var uniqueID = "00" + Math.random();
while(someOtherThis.hasOwnProperty(uniqueID)) {
uniqueID = "00" + Math.random();
}
someOtherThis[uniqueID] = this;
var result = null;
var args = []
if(!arr) {
result = someOtherThis[uniqueID]();
} else {
for(let i = 0, len = arr.length; i < len; i++) {
args.push("arr[" + i + "]")
}
result = eval("someOtherThis[uniqueID](" + args + ")");
}
delete someOtherThis[uniqueID];
return result;
}

function showProfileMessage(message) {
console.log(message, this.name);
}
const obj = {
name: "Ankur Anand"
};
showProfileMessage.myApply(obj, ["welcome "]); // welcome Ankur Anand

bind

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
if(!Function.prototype.bind) {
Function.prototype.bind = function(obj) {
if (typeof this !== "function") {
throw new Error(this + "cannot be bound as it's not callable");
}
var args = Array.prototype.slice.call(arguments, 1),
bindThis = this,
fNOP = function() {},
fBound = function() {
return bindThis.apply(
this instanceof fNOP ? this : obj,
args.concat(Array.prototype.slice.call(arguments))
)
};
if(this.prototype) {
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();
return fBound;
}
}

var person = {
lastName: "Anand"
};

function fullName(salutaion, firstName) {
console.log(salutaion, firstName, this.lastName);
}

var bindFullName = fullName.bind(person, "Mr");

bindFullName("Ankur"); // Mr Ankur Anand
Author: Rick
Link: https://rcrick.github.io/2019/12/18/Implement-apply-call-bind/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶