简单对比分析JavaScript中的apply,call与this的使用


Posted in Javascript onDecember 04, 2015

1.apply定义

apply:调用函数,并用指定对象替换函数的 this 值,同时用指定数组替换函数的参数。
语法:apply([thisObj[,argArray]])
thisObj
可选。要用作 this 对象的对象。

argArray
可选。要传递到函数的一组参数。

2.call定义

call:调用一个对象的方法,用另一个对象替换当前对象。
语法:call([thisObj[, arg1[, arg2[, [, argN]]]]])
thisObj
可选。将作为当前对象使用的对象。

arg1, arg2, , argN
可选。将被传递到该方法的参数列表。

3.二者区别

call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments。
定义也是有差别的。

4.实例分析

(1)官方实例:

function callMe(arg1, arg2){
  var s = "";

  s += "this value: " + this;
  s += "<br />";
  for (i in callMe.arguments) {
    s += "arguments: " + callMe.arguments[i];
    s += "<br />";
  }
  return s;
}

document.write("Original function: <br/>");
document.write(callMe(1, 2));
document.write("<br/>");

document.write("Function called with apply: <br/>");
document.write(callMe.apply(3, [ 4, 5 ]));
document.write(callMe.call(3, 4, 5 ));
// Output: // Original function: // this value: [object Window] // arguments: 1 // arguments: 2 // Function called with apply: // this value: 3 // arguments: 4 // arguments: 5

第一个用apply的:定义:调用函数,并用指定对象替换函数的 this 值
调用函数callMe,使用指定的对象3替换callMe函数中的this,这时候这里的this就从之前的[object Window]变成了3。
第一个用call的:定义:调用一个对象的方法,用另一个对象替换当前对象。
调用对象callMe的方法,用另一个对象3替换callMe中的对象。
从这些结果分析中可以看出,这两者都是使用指定的对象中的对象或者指定的值改变了对象中的this。
也可以说:是一个函数中的对象(this)"劫持"了另一个要执行函数中的对象(this)。
其实这里引出了一个问题:this到底是啥?为何如此重要的一次次来费劲心思的来改变它的指向?

    (2)实例:

function zqz(a,b){
  return alert(a+b);
}
function zqz_1(a,b){
  zqz.apply(zqz_1,[a,b])
}
zqz_1(1,2)  //->3

分析:根据定义:调用函数,并用指定对象替换函数的 this 值,
这里调用函数zqz,并用指定的对象zqz_1替换zqz函数的this值。

要注意js中的函数名其实是对象,因为函数名是对Funtion对象的引用!

function add(a, b)
{
 alert(a + b);
}
function sub(a, b)
{
 alert(a - b);
}
add.call(sub, 3, 1); // 4

分析:根据定义:调用一个对象的方法,用另一个对象替换当前对象。
这里就是调用对象add的方法,并用add对象替换当前对象sub;

再来一个例子:

function zqz(a,b){
  this.name=a;
  this.age=b;
  alert(this.name+" "+this.age);
}
function zqz_1(a,b){
  zqz.apply(this,[a,b])   //我们亦可以这么写  zqz.apply(this,arguments) 
}
zqz_1("Nic",12)  //Nic 12

分析:根据定义:调用函数,并用指定对象替换函数的 this 值,
这里调用函数zqz,使用指定的对象this替换函数zqz的this。

再来一个例子:

<input type="text" id="myText"  value="input text">
function Obj(){
  this.value="对象!";
}
var value="global 变量";
function Fun1(){
  alert(this.value);
}
Fun1();  //global 变量
Fun1.call(window); //global 变量
Fun1.call(document.getElementById('myText')); //input text
Fun1.call(new Obj());  //对象!
Fun1(); //global 变量

分析:定义:调用一个对象的方法,用另一个对象替换当前对象。

调用Fun1对象的方法,用window对象替换当前Fun1中的对象。
调用Fun1对象的方法,用input中对象替换当前Fun1中的对象。
调用Fun1对象的方法,用新new出来的obj中的对象替换当前Fun1中的对象。

下面我们来看一个网友提出的问题:

call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

然后自己动手了写了个案例,写的跟想象的有差别;如下代码

function parent()
 {
 alert(this.name);
 }
 function child()
 {
 var name = '张三';
 };
 
 parent.call(child);

他输出的是child  为什么不张三 根据上面那句话parent上下文已经变成了child

 而child 里面有name 值   应该输出的是张三啊 求大神解释

function parent()
 {
 alert(this.name);
 }
 function child()
 {
 this.name = '张三';
 };
 var p1 = new child();
 
 parent.call(p1);

这样可以输出 张三  为什么呢?

到底是怎么回事呢,我们来看

call和apply有个用处,就是可以用变量作为函数名称来调用。比如函数的回调函数。具体用法是:被执行函数.call(a,b,c...),其中a是在被执行函数中this需要指定的对象,可以为null,其他参数作为被执行函数的参数。apply用法类似,只不过第二个参数是数组。

举例说明:

function doPost(url,param,callback){
  //这里处理post请求
  var str = xhr.responseText;
  callback.apply(this,[str]);//相当于调用了callback(str);并把callback中的this设定为doPost对象
}
Javascript 相关文章推荐
jQuery获取注册信息并提示实现代码
Apr 21 Javascript
Flexigrid在IE下不显示数据的有效处理方法
Sep 04 Javascript
jQuery获取样式中颜色值的方法
Jan 29 Javascript
js面向对象之公有、私有、静态属性和方法详解
Apr 17 Javascript
jQuery检查事件是否触发的方法
Jun 26 Javascript
简单介绍JavaScript中字符串创建的基本方法
Jul 07 Javascript
使用AmplifyJS组件配合JavaScript进行编程的指南
Jul 28 Javascript
Javascript类型系统之undefined和null浅析
Jul 13 Javascript
Javascript 创建类并动态添加属性及方法的简单实现
Oct 20 Javascript
解决vue-router进行build无法正常显示路由页面的问题
Mar 06 Javascript
js计算最大公约数和最小公倍数代码实例
Sep 11 Javascript
vue使用axios实现excel文件下载的功能
Jul 16 Javascript
详解JavaScript的Date对象(制作简易钟表)
Apr 07 #Javascript
浅析2种JavaScript继承方式
Dec 04 #Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
Dec 03 #Javascript
浅析jQuery Mobile的初始化事件
Dec 03 #Javascript
jQuery+jsp实现省市县三级联动效果(附源码)
Dec 03 #Javascript
jQuery移动web开发中的页面初始化与加载事件
Dec 03 #Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
Dec 03 #Javascript
You might like
UCenter 批量添加用户的php代码
2012/07/17 PHP
php基于session实现数据库交互的类实例
2015/08/03 PHP
初学Jquery插件制作 在SageCRM的查询屏幕隐藏部分行的功能
2011/12/26 Javascript
Js判断参数(String,Array,Object)是否为undefined或者值为空
2013/11/04 Javascript
JS中三目运算符和if else的区别分析与示例
2014/11/21 Javascript
jQuery操作DOM之获取表单控件的值
2015/01/23 Javascript
Javascript中数组方法汇总(推荐)
2015/04/01 Javascript
JS实现消息来时让网页标题闪动效果的方法
2016/04/20 Javascript
基于jquery实现轮播特效
2016/04/22 Javascript
JavaScript的ExtJS框架中数面板TreePanel的使用实例解析
2016/05/21 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
JavaScript数组去重由慢到快由繁到简(优化篇)
2016/08/26 Javascript
从零学习node.js之模块规范(一)
2017/02/21 Javascript
基于angular实现三级联动的生日插件
2017/05/12 Javascript
JavaScript 巧学巧用
2017/05/23 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
2款Python内存检测工具介绍和使用方法
2014/06/01 Python
python中如何使用正则表达式的集合字符示例
2017/10/09 Python
Python机器学习之决策树算法
2017/12/22 Python
Python3 实现随机生成一组不重复数并按行写入文件
2018/04/09 Python
python直接获取API传递回来的参数方法
2018/12/17 Python
Python 中使用 PyMySQL模块操作数据库的方法
2019/11/10 Python
Matplotlib中%matplotlib inline如何使用
2020/07/28 Python
运行Python编写的程序方法实例
2020/10/21 Python
使用Python通过oBIX协议访问Niagara数据的示例
2020/12/04 Python
Python中的面向接口编程示例详解
2021/01/17 Python
加拿大城市本地限时优惠:Buytopia.ca
2018/09/19 全球购物
荷兰照明、灯具和配件网上商店:dmlights
2019/08/25 全球购物
在weblogic中发布ejb需涉及到哪些配置文件
2012/01/17 面试题
应届生保险求职信
2013/11/11 职场文书
24岁生日感言
2014/01/13 职场文书
父母寄语大全
2014/04/12 职场文书
离婚协议书怎样才有法律效力
2014/10/10 职场文书
法人代表资格证明书
2015/06/18 职场文书
2017元旦、春节期间廉洁自律承诺书
2016/03/25 职场文书
导游词之韩国济州岛
2019/10/28 职场文书