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小时内与您取得联系。