JavaScript call() apply()学习笔记
2016-07-09 21:26
295 查看
我们可以将call()和apply()看做是某个对象的方法,通过调用方法的形式来间接调用函数,call()和apply()的第一个实参是要调用函数的母对象,该对象是函数中的上下文,可以通过this关键字来获取该对象的引用,如果想要以obj对象来调用函数a,可以像下面这样调用。
call()
apply()
上面两份代码与下面的代码的功能类似
在ECMAScript5的严格模式中,call()和apply()的第一个实参都会变成this值,哪怕传入的实参原始值是null或者undefined,在ECMAScript3和非严格模式中,传入的null或者undefined都会被全局对象那个所取代,而其他的值则会被包装成相应的对象所替代。
对于call()来说,第一个调用上下文实参之后的所有的实参就是要传入等待调用的函数的值。
apply()方法与call()方法类似,但传入实参的形式和call()不同,apply()的实参都是放到一个数组里面的。
需要注意的是,如果一个函数的实参个数可以是任意数量,给apply()传入的参数数组也可以是任意长度的。
传入apply()的参数数组可以是类数组对象也可以是真实的数组,可以将当前函数的arguments对象直接传入apply()来调用另一个函数。
call()
// var obj = {x: "obj"}; //声明一个函数a,控制台输出函数中的上下文(this) function a() { console.log(this); } //函数a调用call方法,传入obj对象做上下文 a.call(obj);⇒ Object {x: "obj"}
apply()
// var obj = {x: "obj"}; //声明一个函数a,控制台输出函数中的上下文(this) function a() { console.log(this); } //函数a调用call方法,传入obj对象做上下文 a.apply(obj);⇒ Object {x: "obj"}
上面两份代码与下面的代码的功能类似
//定义一个与上面代码类似的函数 Object.prototype.callTest = function (obj){ //将调用此函数的上下文对象储存为传入对象的临时方法 obj.fn = this; //调用这个临时方法,不传入参数 obj.fn(); //调用完成之后将临时方法删除 delete obj.fn; } //调用callTest实现类似功能 a.callTest(obj);⇒ Object {x: "obj"}
在ECMAScript5的严格模式中,call()和apply()的第一个实参都会变成this值,哪怕传入的实参原始值是null或者undefined,在ECMAScript3和非严格模式中,传入的null或者undefined都会被全局对象那个所取代,而其他的值则会被包装成相应的对象所替代。
对于call()来说,第一个调用上下文实参之后的所有的实参就是要传入等待调用的函数的值。
//测试对象 var obj = {x: "obj"}; //测试函数接收两个实参 function a(x,y) { console.log(this); //计算两个实参的和 console.log(x + "+" + y + "=" + (x + y)); } //调用call,传入两个实参1和2 a.call(obj,1,2);⇒ Object {x: "obj"} 1+2=3
apply()方法与call()方法类似,但传入实参的形式和call()不同,apply()的实参都是放到一个数组里面的。
//测试对象 var obj = {x: "obj"}; //测试函数接收两个实参 function a(x,y) { console.log(this); //计算两个实参的和 console.log(x + "+" + y + "=" + (x + y)); } //调用apply,传入一个数组,包含两个实参1和2 a.apply(obj,[1,2]);⇒ Object {x: "obj"} 1+2=3
需要注意的是,如果一个函数的实参个数可以是任意数量,给apply()传入的参数数组也可以是任意长度的。
//长度为10的数字数组 var array_of_numbers = [1,2,3,4,5,6,7,8,9,10]; //调用Math对象中的Max计算出数组中的最大值 console.log(Math.max.apply(Math,array_of_numbers));⇒ 10
传入apply()的参数数组可以是类数组对象也可以是真实的数组,可以将当前函数的arguments对象直接传入apply()来调用另一个函数。
//测试对象 var obj = {x: "obj",fn : function(x,y){ //计算两个实参的和 console.log(x + "+" + y + "=" + (x + y)); }}; //调用替换之前的fn obj.fn(1,2);⇒ 1+2=3 //将对象obj中的方法fn替换为另一个方法 /** * trace函数接收两个参数 * @param obj 对象 * @param fn 指定对象中需要替换的方法名 */ function trace(obj, fn){ //在闭包中保存原始方法 var original = obj[fn]; //定义一个新的方法到fn中 obj[fn] = function(){ //输出日志 console.log(new Date(),"输入中:",fn); //调用原始的函数 var result = original.apply(this,arguments); //输出日志 console.log(new Date(),"退出中:",fn); //返回结果 return result; }; } //调用替换方法的函数 trace(obj,"fn"); //调用替换之后的fn obj.fn(1,2); /** * Sat Jul 09 2016 21:50:57 GMT+0800 (中国标准时间) "输入中:" "fn" * 1+2=3 * Sat Jul 09 2016 21:50:57 GMT+0800 (中国标准时间) "退出中:" "fn" */
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解