We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
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() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数
上面是 call 的定义,apply 与 call 类似只是第二个参数是一个数组而 call 接收的则是一个参数列表。
看一个例子
var obj = { name: "obj" }; function foo() { return this.name; } foo.call(obj); //obj
上面通过 call 改变了 this 的指向,下面就是模拟实现
call 和 apply 是 es5 的方法,既然是模拟实现那肯定不能用 es5 方法了,我们先分析一下怎么来指定 this,this 跟动态作用域类似是在执行时确定,那我们在指定 this 的属性上添加一个方法并且执行,那么这个方法的 this 就是指定 this
var obj = { name: "obj", foo: function foo() { return this.name; } }; obj.foo();
上面解决了 this,下面来看下怎么实现参数的传递,call 方法可以传递任意参数列表,我们可以通过arguments来获取,它是一个类数组。
arguments
function getName() { console.log(arguments); //Arguments(5) [1, 2, 3, 4, 5] } function foo() { var args = []; for (var i = 0; i < arguments.length; i++) { args.push("arguments[" + i + "]"); } eval("getName(" + args + ")"); } foo(1, 2, 3, 4, 5);
OK,这两块已经搞定了,下面就是实现
Function.prototype.calls = function(con) { con.fn = this; // 获取参数 var args = []; for (var i = 1; i < arguments.length; i++) { args.push("arguments[" + i + "]"); } var result = eval("con.fn(" + args + ")"); delete con.fn; return result; };
上面删除属性是为了避免污染,这里的fn可以是任意属性名只要保证不重复就行了,不过仔细观察上面函数还是有问题
fn
null
undefined
Function.prototype.calls = function(con) { if (con == null) { con = typeof window === "object" ? window : global; } con = Object(con); con.fn = this; // 获取参数 var args = []; for (var i = 1; i < arguments.length; i++) { args.push("arguments[" + i + "]"); } var result = eval("con.fn(" + args + ")"); delete con.fn; return result; };
测试一下
function foo() { return this.length; } console.log(foo.calls("obj")); // 3
撒花,这样就实现了 call
与 call 十分类似,这里就直接贴代码了
Function.prototype.applys = function(con, arr) { if (con == null) { con = typeof window === "object" ? window : global; } con = Object(con); con.fn = this; var result; if (typeof arr === "object" && arr.length) { var args = []; for (var i = 0; i < arr.length; i++) { args.push("arr[" + i + "]"); } result = eval("con.fn(" + args + ")"); } else { result = eval("con.fn()"); } delete con.fn; return result; };
The text was updated successfully, but these errors were encountered:
No branches or pull requests
上面是 call 的定义,apply 与 call 类似只是第二个参数是一个数组而 call 接收的则是一个参数列表。
看一个例子
上面通过 call 改变了 this 的指向,下面就是模拟实现
实现
call 和 apply 是 es5 的方法,既然是模拟实现那肯定不能用 es5 方法了,我们先分析一下怎么来指定 this,this 跟动态作用域类似是在执行时确定,那我们在指定 this 的属性上添加一个方法并且执行,那么这个方法的 this 就是指定 this
上面解决了 this,下面来看下怎么实现参数的传递,call 方法可以传递任意参数列表,我们可以通过
arguments
来获取,它是一个类数组。OK,这两块已经搞定了,下面就是实现
call
上面删除属性是为了避免污染,这里的
fn
可以是任意属性名只要保证不重复就行了,不过仔细观察上面函数还是有问题null
或者undefined
;测试一下
撒花,这样就实现了 call
apply
与 call 十分类似,这里就直接贴代码了
参考
The text was updated successfully, but these errors were encountered: