参考文章:
https://www.jianshu.com/p/473a86d509b9
- call方法
var a = {value:1};
function getValue(name,age){
console.log("arguments in getValue = ",arguments);//arguments in getValue = [Arguments] { '0': 'test', '1': 20 }
console.log(name,age);//test 20
console.log(this.value); //1
}
Function.prototype.myCall = function (func) {
//func是当前要调用函数的对象,即此时的a对象
console.log("func = ",func); //func = { value: 1 }
//this指的被调用函数
console.log("this = ",this);
//输出结果
//this = function getValue(name,age){
// console.log("arguments in getValue",arguments);
// console.log(name,age);
// console.log(this.value);
// }
if(typeof this != 'function'){
throw new TypeError('Error');
}
let ctx = func || window;
console.log("ctx = ",ctx); //ctx = { value: 1 }
console.log("arguments = ",arguments); //arguments = [Arguments] { '0': { value: 1 }, '1': 'test', '2': 20 }
let args = [...arguments].splice(1);
console.log("args = ",args); //args = [ 'test', 20 ]
ctx.fn = this;
console.log('ctx.fn = ',ctx.fn);
//输出结果
// ctx.fn = function getValue(name,age){
// console.log("arguments in getValue",arguments);
// console.log(name,age);
// console.log(this.value);
// }
var result = ctx.fn(...args);
delete ctx.fn;
return result;
};
getValue.myCall(a,'test',20);
输出结果
输出结果
- apply方法
let a = {value:1};
function getValue(name,age) {
console.log(name,age);
console.log(this.value);
}
Function.prototype.myApply = function (funcCxt) {
if(typeof this != "function"){
throw TypeError('Error');
}
let cxt = funcCxt || window;
cxt.fn = this;
let result;
if(arguments[1]){
result = cxt.fn(...arguments[1]);
}else{
result = cxt.fn();
}
delete cxt.fn;
return result;
};
getValue.myApply(a,["jack",12]);
输出结果:
输出结果
- bind方法
let a = {value:1};
let getValue = function(name,age) {
this.gender = '男';
console.log(name,age);
console.log(this.value);
};
getValue.prototype.height = 180;
Function.prototype.myBind = function (context) {
if(typeof this != 'function'){
throw TypeError('Error');
}
let ctx = context || window;
let _this = this;
console.log("this = ",this); //this = function(name,age) {
// this.gender = '男';
// console.log(name,age);
// console.log(this.value);
// }
let args = [...arguments].splice(1);
let F = function () {};
let bound = function () {
// 如果当做构造函数使用
let self = this instanceof bound ? this : ctx;
_this.apply(self,args.concat(...arguments));
};
let f = function () {};
f.prototype = this.prototype;
console.log("this.prototype = ",this.prototype); //this.prototype = getValue { height: 180 }
bound.prototype = new f();
return bound;
};
let fn = getValue.myBind(a,'jack',15);
//当 bind 返回的函数作为构造函数的时候,bind 时指定的 this 值会失效,但传入的参数依然生效。
let test = new fn(); //jack 15 undefined
console.log("test = ",test); //test = getValue { gender: '男' }
console.log(test.height);//180
console.log(test.gender); //男
网友评论