JavaScript Call函数原理
call原理分析,一定要看最后的例子。
1.call使用例子
function add(c, d) { return this.a + this.b + c + d; } const obj = { a: 1, b: 2 }; console.error(add.call(obj, 3, 4)); // 10
2.其实现原理类似于下面代码
const obj = { a: 1, b: 2, add: function(c, d) { return this.a + this.b + c + d } };
console.log(obj.add(3,4)); //10
其步骤伪码
// 1. 将函数设为对象的属性 obj.fn = add // 2. 执行该函数 obj.fn() // 3. 删除该函数 delete obj.fn
3. 实现
3.1基于ES3实现call
Function.prototype.es3Call = function (context) { var context = context || window; context.fn = this; var args = []; // arguments是类数组对象,遍历之前需要保存长度,过滤出第一个传参 for (var i = 1, len = arguments.length ; i < len; i++) { // 避免object之类传入 args.push('arguments[' + i + ']'); } var result = eval('context.fn('+args+')'); delete context.fn; return result; }
console.error(add.es3Call(obj, 3, 4)); // 10
3.2基于ES6实现call,es6的rest参数
Function.prototype.es6Call = function (context) { var context = context || window; context.fn = this; var 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; }
4.例子
测试一下自己是否真的理解了call
function fn1(){ console.log(1); } function fn2(){ console.log(2); } fn1.call(fn2); //输出 1 fn1.call.call(fn2); //输出 2
分析
/** * fn1.call(fn2) * fn2.fn = fn1 * fn2.fn() * delete fn2.fn * * fn1.call.call(fn2) * fn2.fn=fn1.call * fn2.fn()->fn2.call()->递归->最后执行window.fn2() * delete fn2.fn */
参考博客:
https://www.cnblogs.com/donghezi/p/9742778.html (例子分析太复杂了,让人难以理解)
https://blog.csdn.net/u010377383/article/details/80646415 (原理讲的很好)
posted on 2019-08-23 16:49 SmilingEye 阅读(202) 评论(0) 编辑 收藏 举报