- 所有方法的第一个参数需注意: 可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
apply的实现
- apply的定义: apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
Function.prototype.myApply = function(tThis, params) {
// 首先判断是不是被方法调用的
if(typeof this !== "function") {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
// 这句话的巧妙之处在于,运用this的特性谁调用就指向谁
// 如果tThis是空怎么办 暂时考虑兼容node和浏览器
if(tThis === null || tThis === undefined) {
tThis = typeof window !== "undefined" ? window : global;
}
tThis.fn = this;
// 这个时候执行的this的指向就被改变为tThis了
return params ? tThis.fn(...params) : tThis.fn();
}
call的实现
- call的定义: call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。和上面apply的区别在于参数的不一样,一个是多个一个是单个数组。
Function.prototype.myCall = function(params) {
// 首先判断是不是被方法调用的
if(typeof this !== "function") {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
let tThis = params;
if(tThis === null || tThis === undefined) {
tThis = typeof window !== "undefined" ? window : global;
}
tThis.fn = this;
// 因为我么无法得知到底传进来了多少参数,所以这里就使用arguments来获取参数的量。
let tParams = Array.prototype.slice.myApply(arguments, [1]);
return tThis.fn(...tParams);
}
bind的实现
- bind的定义: bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
Function.prototype.myBind = function(params) {
//同上
if(typeof this !== "function") {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
let tThis = this;
if(tThis === null || tThis === undefined) {
tThis = typeof window !== "undefined" ? window : global;
}
let currentThis = params;
let forParams = Array.prototype.slice.myCall(arguments, 1);
// 获取原本this的原型链
let cFn = function() {};
// new 过来的时候这个this
let fn = function () {
let gThis = this instanceof fn ? this : currentThis;
return tThis.apply(gThis, forParams.concat(Array.prototype.slice.myApply(arguments)));
}
if(this.prototype) {
cFn.prototype = this.prototype;
fn.prototype = new cFn();
cFn.prototype = null;
// 返回一个新的对象
}
return fn;
}
网友评论