call原理分析,一定要看最后的例子。

1.call使用例子

function add(c, d) {
return this.a + this.b + c + d;
} const obj = { a: , b: }; console.error(add.call(obj, , )); //

2.其实现原理类似于下面代码

const obj = {
a: ,
b: ,
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 = , 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 = , 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();
}
function fn2(){
console.log();
} 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 (原理讲的很好)

JavaScript Call函数原理的更多相关文章

  1. 理解JavaScript Call()函数原理。

    最近在做面试题的过程中偶然碰到关于call函数的问题.然后再百度上查了查.偶然看到一篇文章:JavaScript中的call.apply.bind深入理解 抛开其对call函数基本概念的介绍还有其他原 ...

  2. JavaScript中函数的形参和实参的实现原理剖析

    我们都知道JS里面参数的传递是可以不一样的,比如我们有一个函数: <script type="text/javascript"> function one(a,b,c) ...

  3. JavaScript异步编程原理

    众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...

  4. javascript escape()函数和unescape()函数

    javascript escape()函数和unescape()函数 escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串. 语法: escape(string) stri ...

  5. JavaScript调用函数的方法

    摘要:这篇文章详细的介绍了Javascript中各种函数调用的方法及其原理,对于理解JavaScript的函数有很大的帮助! 一次又一次的,我发现,那些有bug的Javascript代码是由于没有真正 ...

  6. [转]javascript eval函数解析json数据时为什加上圆括号eval("("+data+")")

    javascript eval函数解析json数据时为什么 加上圆括号?为什么要 eval这里要添加 “("("+data+")");//”呢?   原因在于: ...

  7. JavaScript的闭包原理

    什么是js(JavaScript)的闭包原理,有什么作用? 一.定义 官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 个人的理解是 ...

  8. javascript引擎工作原理

    1. 什么是JavaScript解析引擎? 简单地说,JavaScript解析引擎就是能够“读懂”JavaScript代码,并准确地给出代码运行结果的一段程序.比方说,当你写了 var a = 1 + ...

  9. Js(javaScript)的闭包原理

    问题?什么是js(javaScript)的闭包原理,有什么作用? 一.定义 官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.  小编 ...

随机推荐

  1. C# 在运行中拖拽,改变控件大小位置类(转载)

    原文地址:https://blog.csdn.net/zgke/article/details/3718989 copy的code /// <summary> /// 移动改变控件大小 / ...

  2. matlab cell

    cell元包是matlab中提供的一种数据类型,功能强大. 关于cell的创建: 1.跟一般创建举证一样,直接使用C = {A B D E}这种形式,不过这里把"[]"改成了}&q ...

  3. vue 钩子函数的初接触

    vue-router的路由钩子函数: 第一种:全局钩子函数. router.beforeEach((to, from, next) => { console.log('beforeEach') ...

  4. 【外网不好用】可以尝试添加dns即可解决上不去外网的问题。

    可以将IPv4这里的DNS修改成以下内容再尝试上网试试.

  5. HTML锚点的使用

    锚点: 连接到的本页面的位置:

  6. navicat远程连接mysql错误

    确保端口与服务正常. 如果都正常,那么服务有可能没有添加远程访问. 本人链接报错10060,那么问题出在阿里云的主机默认不开放3306端口,那么在安全组策略中加入对应的端口   登录后输入 use m ...

  7. Scrapy 中常用的中间件和管道组件

    Pipeline用法 储存到MongoDB pipline.py中的代码 import pymongo class MongoPipeline(object): def __init__(self, ...

  8. STM32窗口看门狗WWDG库函数的一点思考

    WWDG当前计数器的值以及激活位和WWDG_CR这个寄存器相关.如下图所示: 而STM32f10x的库函数提供了两种设置WWDG_CR[0:6]位的方式. WWDG_SetCounter方法 #def ...

  9. 算法之暴力破解和kmp算法 判断A字符串是否包含B字符串

    我们都知道java中有封装好的方法,用来比较A字符串是否包含B字符串 如下代码,contains,用法是 str1.contains(str2), 这个布尔型返回,存在返回true,不存在返回fals ...

  10. Ubuntu系统---C++之VScode IDE 编译器安装

    Ubuntu系统---C++之VScode IDE 编译器安装 简单了解了一下VScode,直观印象:安装包很小(不像VS那么大占用十G左右).跨平台.小巧.可以编译C++ / java / pyth ...