Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

call、apply函数的实现 #10

Open
conan1992 opened this issue Jun 8, 2020 · 0 comments
Open

call、apply函数的实现 #10

conan1992 opened this issue Jun 8, 2020 · 0 comments

Comments

@conan1992
Copy link
Owner

conan1992 commented Jun 8, 2020

call

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

先看一个例子

var foo = {
    value: 1
};

function bar() {
    console.log(this.value);
}

bar.call(foo); // 1

思考:

  1. call 改变了 this 的指向,指向到 foo
  2. bar 函数执行了

模拟实现步骤:

  1. 将函数设为对象的属性
  2. 执行该函数
  3. 删除该函数

关键点:

函数执行可带不定长参数

解决办法

var args = [];
//第一个参数是this指定对象,所以i从1开始
for(var i=1;i<arguments.length;i++){
	args.push('arguments['+i+']')
}

动手实现:

Function.prototype.call2 = function(target){
	target = target || window;
	target.fun = this;
	var args = [];
	for(var i=1;i<arguments.length;i++){
		args.push('arguments['+i+']')
	}
	var result = eval('target.fun('+args+')')
	delete target.fun;
	return result;
}


// 测试一下
var value = 2;

var obj = {
    value: 1
}

function bar(name, age) {
    console.log(this.value);
    return {
        value: this.value,
        name: name,
        age: age
    }
}

bar.call2(null); // 2

console.log(bar.call2(obj, 'manny', 18));
// 1
// Object {
//    value: 1,
//    name: 'manny',
//    age: 18
// }

apply

apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。

模拟实现

和apply的差别就是在于参数的格式

Function.prototype.apply2 = function (target, arr) {
    target = target || window;
    target.fun = this;

    var result;
    if (!arr) {
        result = target.fun();
    }
    else {
        var args = [];
        for (var i = 0, len = arr.length; i < len; i++) {
            args.push('arr[' + i + ']');
        }
        result = eval('target.fun(' + args + ')')
    }

    delete target.fun
    return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant