手写系列文章
手写算法,要想实现和原生的功能一致,则弄懂原生的都支持些什么功能是很重要的。
原生.call方法
作用
套用MDN上的解释为:
call()方法使用一个指定的this值和单独给出的一个或多个参数来调用函数
语法
调用原生call的语法为:
functionA.call(thisArg, arg1, arg2, ...)
参数含义:
thisArg: 在function函数运行时使用的this值。如果是在非严格模式下,thisArg指定为null或undefined时会自动替换为指向全局对象。
arg1, arg2, ...: 指定的参数列表
返回值
使用调用者提供的this值和参数调用该函数的返回值。若该方法没有返回值,则返回undefined。
示例
const a = {
name: 'xiao a',
b() {
console.log('my name is: ', this.name);
}
}
c = {name: 'xiao c'};
a.b.call(c); // 打印的内容为: my name is: xiao c
手写call方法
手写call方法需要注意几个点:
- 调用call的参数中第一个是调用者提供的this值,具体的参数是从第二个位置开始的
- 在非严格模式下,如果没有提供this值,或者this值为null、undefined,则this会被自动替换为全局对象,在浏览器中指向的是window
- call是Function原型对象上的一个方法
具体的代码如下:
Function.prototype.myCall = function(context, ...args) {
if (typeof this !== 'function') {
throw Error(`typeError: ${this} not function.`);
}
const ctx = context || window;
const func = Symbol();
ctx[func] = this;
const result = args.length ? ctx[func](...args) : ctx[func]();
delete ctx[func];
return result;
}
测试
const a = {
name: 'xiao a',
b() {
console.log('my name is: ', this.name);
}
}
c = {name: 'xiao c'};
a.b.myCall(c); // 打印的内容为: my name is: xiao c
// 不提供this
a.b.myCall() // 打印的内容为: my name is:
// 在window对象上增加属性: window.name = 'window';
a.c.myCall() // 打印的内容为: my name is: window