call 的功能
var obj = {
value:1
}
function foo(){
console.log(this.value)
}
foo.call(obj) //1
上段代码可以看出 call
的功能:
- 改变了
foo
函数this
的指向. 默认foo
的this
应该是window
.call
之后变为了 对象ob
了. - 并且
foo
函数还执行了.
基于此,我们可以这么写:
第一版:
Function.prototype.call2 = function(context){
context.fn = this;
context.fn();
delete context.fn;
}
foo.call2(obj); // 1
上面代码中的 this
就是被执行的函数 foo()
; context
就是传入的对象 obj
. 不信你可以自行打印一下.
等同于, 这里需要细品:
var obj = {
value:1,
foo:function(){
console.log(this.value)
}
}
obj.foo() //1
第二版
第二版解决的问题是 call
能够传入参数的问题,而上一版写的没有这个功能.
例如:
var obj = {
value:1
}
function foo(name,age){
console.log(name)
console.log(age)
console.log(this.value)
}
foo.call(obj,'wuxuwei',18) // 1 'wuxuwei' 18
这个其实简单,因为函数有个 arguments
. 写法如下
Function.prototype.call2 = function(context){
context.fn = this;
const args = [];
for(let i = 1, len = arguments.length; i < len ; i++){
args.push(arguments[i]);
};
context.fn(...args);
delete context.fn
}
foo.call2(obj,'wuxuwei',18) // 1 'wuxuwei' 18
第三版(终极版)
这一版需要解决两个问题
1.this 参数可以传 null,当为 null 的时候,视为指向 window
var value = 2;
function bar() {
console.log(this.value);
}
bar.call(null); // 2
2.函数是可以有返回值的!
var obj = {
value: 1
}
function foo(name, age) {
return {
value: this.value,
name: name,
age: age
}
}
console.log(foo.call(obj, 'wuxuwei', 18));
// Object {
// value: 1,
// name: 'wuxuwei',
// age: 18
// }
基于此,我们这么写:
var context = context || window;
context.fn = this;
console.log(context);
const args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push( arguments[i]);
}
var result = context.fn(...args);
delete context.fn
return result
foo.call2(null)
console.log(foo.call2(obj,'wuxuwei',18))
// 2
// Object {
// value: 1,
// name: 'kevin',
// age: 18
// }
网友评论