简单对比分析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 相关文章推荐
addEventListener和attachEvent二者绑定的执行函数中的this不相同
Dec 09 Javascript
javascript弹出窗口实现代码
Nov 12 Javascript
浅析JSONP技术原理及实现
Jun 08 Javascript
微信小程序 wxapp内容组件 icon详细介绍
Oct 31 Javascript
Angular的MVC和作用域
Dec 26 Javascript
手把手搭建安装基于windows的Vue.js运行环境
Jun 12 Javascript
vue双花括号的使用方法 附练习题
Nov 07 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
Jan 02 jQuery
微信小程序 如何引入外部字体库iconfont的图标
Jan 31 Javascript
vue-devtools的安装步骤
Apr 23 Javascript
通过实例学习React中事件节流防抖
Jun 17 Javascript
Vue通过阿里云oss的url连接直接下载文件并修改文件名的方法
Dec 25 Vue.js
详解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
简单的用PHP编写的导航条程序
2006/10/09 PHP
php启用sphinx全文搜索的实现方法
2014/12/24 PHP
PHP查找数值数组中不重复最大和最小的10个数的方法
2015/04/20 PHP
jquery 最简单的属性菜单
2009/10/08 Javascript
js不完美解决click和dblclick事件冲突问题
2012/07/16 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
2013/02/04 Javascript
node.js中使用q.js实现api的promise化
2014/09/17 Javascript
jquery动态改变div宽度和高度
2015/02/09 Javascript
浅谈被jQuery抛弃的函数及替代函数
2015/05/03 Javascript
jQuery实现弹出窗口中切换登录与注册表单
2015/06/05 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
javascript简单实现等比例缩小图片的方法
2016/07/27 Javascript
xmlplus组件设计系列之路由(ViewStack)(7)
2017/05/02 Javascript
利用node.js实现自动生成前端项目组件的方法详解
2017/07/12 Javascript
Vue完整项目构建(进阶篇)
2018/02/10 Javascript
vue监听对象及对象属性问题
2018/08/20 Javascript
解决webpack+Vue引入iView找不到字体文件的问题
2018/09/28 Javascript
JS选取DOM元素常见操作方法实例分析
2018/12/10 Javascript
用vscode开发vue应用的方法步骤
2019/05/06 Javascript
微信小程序云开发使用方法新手初体验
2019/05/16 Javascript
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
微信小程序新闻网站详情页实例代码
2020/01/10 Javascript
分析Python编程时利用wxPython来支持多线程的方法
2015/04/07 Python
Python中的自省(反射)详解
2015/06/02 Python
基于Python对象引用、可变性和垃圾回收详解
2017/08/21 Python
Python基于类路径字符串获取静态属性
2020/03/12 Python
python selenium 获取接口数据的实现
2020/12/07 Python
香港钟表珠宝首饰商城:OneMallTime网摩间
2016/10/14 全球购物
Russell Stover巧克力官方网站:美国领先的精美巧克力制造商
2016/11/27 全球购物
最新会计专业求职信范文
2014/01/28 职场文书
政法干警核心价值观心得体会
2014/09/11 职场文书
2015届大学生就业推荐表自我评价
2014/09/27 职场文书
派出所副所长四风问题个人整改措施思想汇报
2014/10/13 职场文书
2014年前台文员工作总结
2014/12/08 职场文书
中班下学期个人工作总结
2015/02/12 职场文书
PO模式在selenium自动化测试框架的优势
2022/03/20 Python