全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

JavaScript中的call和apply的用途以及区别

apply 接受两个参数,第一个参数指定了函数体内this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组,apply 方法把这个集合中的元素作为参数传递给被调用的函数:

var func = function( a, b, c ){
  alert ( [ a, b, c ] ); // 输出 [ 1, 2, 3 ]
};
func.apply( null, [ 1, 2, 3 ] );

在这段代码中,参数 1、2、3 被放在数组中一起传入func函数,它们分别对应func参数列表中的a、b、c。

call 传入的参数数量不固定,跟apply 相同的是,第一个参数也是代表函数体内的this 指向,从第二个参数开始往后,每个参数被依次传入函数:

var func = function( a, b, c ){
  alert ( [ a, b, c ] ); // 输出 [ 1, 2, 3 ]
};
func.call( null, 1, 2, 3 );

当调用一个函数时,JavaScript 的解释器并不会计较形参和实参在数量、类型以及顺序上的区别,JavaScript 的参数在内部就是用一个数组来表示的。从这个意义上说,apply比call的使用率更高,我们不必关心具体有多少参数被传入函数,只要用apply 一股脑地推过去就可以了。call是包装在apply上面的一颗语法糖,如果我们明确地知道函数接受多少个参数,而且想一目了然地表达形参和实参的对应关系,那么也可以用call 来传送参数。

call和apply的用途

1. 改变this 指向

call 和apply 最常见的用途是改变函数内部的this 指向,我们来看个例子:

var obj1 = {
  name: 'sven'
};
var obj2 = {
  name: 'anne'
};
window.name = 'window';
var getName = function(){
  alert ( this.name );
};
getName(); // 输出: window
getName.call( obj1 ); // 输出: sven
getName.call( obj2 ); // 输出: anne

当执行getName.call( obj1 )这句代码时,getName 函数体内的this 就指向obj1 对象,所以此处的

var getName = function(){
alert ( this.name );
};

实际上相当于:

var getName = function(){
alert ( obj1.name ); // 输出: sven
};

在实际开发中,经常会遇到this指向被不经意改变的场景,比如有一个div节点,div节点的onclick 事件中的this 本来是指向这个div的:

document.getElementById( 'div1' ).onclick = function(){
  alert( this.id ); // 输出:div1
};

假如该事件函数中有一个内部函数func,在事件内部调用func 函数时,func 函数体内的this就指向了window,而不是我们预期的div,见如下代码:

document.getElementById( 'div1' ).onclick = function(){
  alert( this.id ); // 输出:div1
  var func = function(){
    alert ( this.id ); // 输出:undefined
  }
  func();
};

这时候我们用call 来修正func 函数内的this,使其依然指向div:

document.getElementById( 'div1' ).onclick = function(){
  var func = function(){
    alert ( this.id ); // 输出:div1
  }
  func.call( this );
};

2. Function.prototype.bind

大部分高级浏览器都实现了内置的Function.prototype.bind,用来指定函数内部的this 指向,即使没有原生的Function.prototype.bind 实现,我们来模拟一个也不是难事,代码如下:

Function.prototype.bind = function( context ){
var self = this; // 保存原函数
return function(){ // 返回一个新的函数
    return self.apply( context, arguments ); // 执行新的函数的时候,会   把之前传入的context
  // 当作新函数体内的this
  }
};
var obj = {
  name: 'sven'
};
var func = function(){
  alert ( this.name ); // 输出:sven
}.bind( obj);
func();

我们通过Function.prototype.bind 来“包装”func 函数,并且传入一个对象context 当作参数,这个context 对象就是我们想修正的this 对象。

在Function.prototype.bind 的内部实现中,我们先把func 函数的引用保存起来,然后返回一个新的函数。当我们在将来执行func 函数时,实际上先执行的是这个刚刚返回的新函数。在新函数内部,self.apply( context, arguments )这句代码才是执行原来的func 函数,并且指定context对象为func 函数体内的this。

这是一个简化版的Function.prototype.bind 实现,通常我们还会把它实现得稍微复杂一点,

使得可以往func 函数中预先填入一些参数:

Function.prototype.bind = function(){
  var self = this, // 保存原函数
  context = [].shift.call( arguments ), // 需要绑定的this 上下文
  args = [].slice.call( arguments ); // 剩余的参数转成数组
  return function(){ // 返回一个新的函数
    return self.apply( context, [].concat.call( args, [].slice.call(  arguments ) ) );
    // 执行新的函数的时候,会把之前传入的context 当作新函数体内的this
    // 并且组合两次分别传入的参数,作为新函数的参数
  }
};
var obj = {
  name: 'sven'
};
var func = function( a, b, c, d ){
  alert ( this.name ); // 输出:sven
  alert ( [ a, b, c, d ] ) // 输出:[ 1, 2, 3, 4 ]
}.bind( obj, 1, 2 );
func( 3, 4 );

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# call  # apply  # 区别  # javascript中apply和call方法的作用及区别说明  # js apply/call/caller/callee/bind使用方法与区别分析  # JavaScript学习点滴 call、apply的区别  # JavaScript中apply与call的用法意义及区别说明  # 在JavaScript中call()与apply()区别  # JavaScript中的this  # apply使用及区别详解  # 理解Javascript的caller  # callee  # apply区别  # 深入理解JavaScript中的call、apply、bind方法的区别  # javascript中apply、call和bind的使用区别  # Javascript call和apply区别及使用方法  # 深入理解关于javascript中apply()和call()方法的区别  # JavaScript中call和apply方法的区别实例分析  # 体内  # 的是  # 第一个  # 第二个  # 这句  # 放在  # 作新  # 才是  # 还会  # 可以用  # 中有  # 两次  # 把它  # 一颗  # 也可  # 这段  # 这是一个  # 有多少  # 更高  # 使其 


相关文章: 公司网站制作费用多少,为公司建立一个网站需要哪些费用?  Android使用GridView实现日历的简单功能  5种Android数据存储方式汇总  C++时间戳转换成日期时间的步骤和示例代码  建站主机与服务器功能差异如何区分?  上海网站制作开发公司,上海买房比较好的网站有哪些?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  建站之星×万网:智能建站系统+自助建站平台一键生成  杭州银行网站设计制作流程,杭州银行怎么开通认证方式?  宝盒自助建站智能生成技巧:SEO优化与关键词设置指南  已有域名能否直接搭建网站?  家庭服务器如何搭建个人网站?  制作公司内部网站有哪些,内网如何建网站?  网站app免费制作软件,能免费看各大网站视频的手机app?  制作电商网页,电商供应链怎么做?  家庭建站与云服务器建站,如何选择更优?  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  建站与域名管理如何高效结合?  制作宣传网站的软件,小红书可以宣传网站吗?  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  如何快速搭建支持数据库操作的智能建站平台?  寿县云建站:智能SEO优化与多行业模板快速上线指南  定制建站是什么?如何实现个性化需求?  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  制作营销网站公司,淘特是干什么用的?  如何在Golang中处理模块冲突_解决依赖版本不兼容问题  湖北网站制作公司有哪些,湖北清能集团官网?  北京网站制作的公司有哪些,北京白云观官方网站?  如何在宝塔面板中创建新站点?  东莞专业制作网站的公司,东莞大学生网的网址是什么?  南京网站制作费用,南京远驱官方网站?  建站之星安装失败:服务器环境不兼容?  潍坊网站制作公司有哪些,潍坊哪家招聘网站好?  完全自定义免费建站平台:主题模板在线生成一站式服务  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  如何快速搭建高效服务器建站系统?  如何快速配置高效服务器建站软件?  建站之星展会模版如何一键下载生成?  如何制作算命网站,怎么注册算命网站?  岳西云建站教程与模板下载_一站式快速建站系统操作指南  导航网站建站方案与优化指南:一站式高效搭建技巧解析  香港服务器如何优化才能显著提升网站加载速度?  如何通过VPS搭建网站快速盈利?  javascript基本数据类型及类型检测常用方法小结  建站主机选虚拟主机还是云服务器更好?  如何高效完成独享虚拟主机建站?  海南网站制作公司有哪些,海口网是哪家的?  如何在橙子建站上传落地页?操作指南详解  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。