JS中使用apply方法通过不同数量的参数调用函数的方法


Posted in Javascript onMay 31, 2016

apply()方法定义

函数的apply()方法和call方法作用相同,区别在于接收的参数的方式不同。
apply()方法接收两个参数,一个是对象,一个是参数数组。

apply()作用

1、用于延长函数的作用域

示例:

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
sayColor.apply(o);//"blue"

这里通过apply()方法把函数动态绑定到了对象o上了,这时this指向o对象,得到结果"blue"。

2、对象不需要与方法有任何耦合关系

下面举个耦合的例子,看如何通过apply来解决这种耦合。

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
o.sayColor=sayColor;
o.sayColor();//"blue"

这里先将函数放到了对象o中,这里对象和方法就紧耦合到一起了,方法的调用必须通过对象o。

没有使用apply()和call()方法那样灵活。
重构上面代码,得到前例中的代码。

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
sayColor();//"red"
sayColor.apply(o);//"blue"

这里对象并没有绑定任何方法,只是在需要使用的时候,利用函数的apply或call方法来动态绑定。

对象和方法之间没有耦合在一起。这里还可以通过ES5提供的bind()方法来完成

3、实现可变参数函数传参

下面一个计算任意数量数字平均值的函数

average(,,);
average();
average(,,,,,,,,);
average(,,,,,,,,,);

average函数是一个称为可变参数或可变元函数(函数的元数是指其期望的参数个数)的例子。

当然这个函数也可以写成一个接收数组的形式。

averageOfArray([,,]);
averageOfArray([]);
averageOfArray([,,,,,,,,]);
averageOfArray([,,,,,,,,,]);

使用可变参数的函数更简洁、优雅。可变参数函数具有便捷的语法,至少让调用者预先明确地知道提供了多少个参数。

如果我有这样一个数组

var scores=getAllScores();

如何使用average函数计算平均值呢?

1.可变参数函数版本。

这时就可以和apply()方法配合使用,这里因为函数并没用引用this变量,因此第一个参数我们传入一个null。代码如下:

var scores=getAllScores();
average.apply(null,scores);

2.直接参数为数组的形式

这里可以直接传入数组参数。

var scores=getAllScores();
averageOfArray(scores);

以上两种形式,个人觉得都是可以,反而第二种更简单。多知道一种方法,对于遇到别人写的函数时,可以轻松应对,不需要重构代码。这个好处反而更多。

4、实现可变参数方法的传值

示例:buffer对象包含一个可变参数的append方法,该方法添加元素到函数内部的state数组中。

var buffer={
state:[],
append:function(){
for(var i=,n=arguments.length;i<n;i++){
this.state.push(arguments[i]);
}
}
};

这时append方法可以接受任意多个参数。

buffer.append('Hello,');
buffer.append('firtName',' ','lastName','!');
buffer.append('newLine');

形式如

buffer.append(arg1,arg2,arg3,...)

借助apply方法的this参数,我们可以指定一个可计算的数组调用append方法

buffer.append.apply(buffer,getInputStrings());

注意:这里的buffer很重要,如果传递不同的对象,则append方法将尝试修改该错误对象的state属性

提示

•使用apply方法指定一个可计算的参数数组来调用可变参数的函数
•使用apply方法的第一个参数给可变参数的方法提供一个接收者

附录一

average函数

function average(){
var args=[].slice.call(arguments);
var sum=args.reduce(function(prev,cur){
return prev+cur;
});
return parseInt(sum/args.length,);
}

averageOfArray函数

function averageOfArray(arr){ 
var sum=arr.reduce(function(prev,cur){
return prev+cur;
});
return parseInt(sum/arr.length,);
}

ES5 bind()方法

这个方法创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
例如

var color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
var oSayColor=sayColor.bind(o);
oSayColor();//"blue"

兼容低版本,参考使用下面的版本 :

if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = [].slice.call(arguments, ),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP? this: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype; 
}
fBound.prototype = new fNOP();
return fBound;
};
}
Javascript 相关文章推荐
解决extjs在firefox中关闭窗口再打开后iframe中js函数访问不到的问题
Nov 06 Javascript
javascript 学习之旅 (1)
Feb 05 Javascript
JS中常用的输出方式(五种)
Jun 12 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
Aug 08 Javascript
微信小程序实现登录页云层漂浮的动画效果
May 05 Javascript
十大 Node.js 的 Web 框架(快速提升工作效率)
Jun 30 Javascript
echarts饼图扇区添加点击事件的实例
Oct 16 Javascript
小程序实现左滑删除功能
Oct 30 Javascript
利用d3.js制作连线动画图与编辑器的方法实例
Sep 05 Javascript
Vue的生命周期操作示例
Sep 17 Javascript
使用Layui搭建后台管理界面的操作方法
Sep 20 Javascript
angular inputNumber指令输入框只能输入数字的实现
Dec 03 Javascript
jQuery解决IE6、7、8不能使用 JSON.stringify 函数的问题
May 31 #Javascript
利用jQuery实现CheckBox全选/全不选/反选的简单代码
May 31 #Javascript
TinyMCE汉化及本地上传图片功能实例详解
May 31 #Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
May 31 #Javascript
BootStrap创建响应式导航条实例代码
May 31 #Javascript
浅谈js中的延迟执行和定时执行
May 31 #Javascript
温习Javascript基础语法之词法结构
May 31 #Javascript
You might like
ASP知识讲座四
2006/10/09 PHP
php模板函数 正则实现代码
2012/10/15 PHP
php获取参数的几种方法总结
2014/02/18 PHP
PHP的mysqli_query参数MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
2014/09/29 PHP
php比较两个字符串长度的方法
2015/07/13 PHP
基于逻辑运算的简单权限系统(实现) JS 版
2007/03/24 Javascript
Prototype使用指南之selector.js说明
2008/10/26 Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
2013/05/08 Javascript
JavaScript link方法入门实例(给字符串加上超链接)
2014/10/17 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
关于验证码在IE中不刷新的快速解决方法
2016/09/23 Javascript
基于Bootstrap仿淘宝分页控件实现代码
2016/11/07 Javascript
简单理解vue中实例属性vm.$els
2016/12/01 Javascript
Bootstrap基本组件学习笔记之进度条(15)
2016/12/08 Javascript
详解使用Visual Studio Code对Node.js进行断点调试
2017/09/14 Javascript
AngularJs 延时器、计时器实例代码
2017/09/16 Javascript
Angular5中状态管理的实现
2018/09/03 Javascript
vue生成文件本地打开查看效果的实例
2018/09/06 Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
2019/12/15 Javascript
[02:58]魔廷新尊——痛苦女王至宝语音台词节选
2020/06/14 DOTA
windows系统下Python环境的搭建(Aptana Studio)
2017/03/06 Python
Python爬虫的两套解析方法和四种爬虫实现过程
2018/07/20 Python
VSCode Python开发环境配置的详细步骤
2019/02/22 Python
手把手教你使用Python创建微信机器人
2019/04/29 Python
基于python实现从尾到头打印链表
2019/11/02 Python
Python+Redis实现布隆过滤器
2019/12/08 Python
python3中确保枚举值代码分析
2020/12/02 Python
x-ua-compatible content=”IE=7, IE=9″意思理解
2013/07/22 HTML / CSS
Html5+CSS3+EL表达式问题小结
2020/12/19 HTML / CSS
俄罗斯大型在线书店:Читай-город
2019/10/10 全球购物
应届生会计求职信
2013/11/11 职场文书
信仰心得体会
2014/09/05 职场文书
高校教师个人总结
2015/02/10 职场文书
初中教师德育工作总结2015
2015/05/12 职场文书
蓝天保卫战收官在即 :15行业将开展环保分级评价
2019/07/19 职场文书
为什么MySQL 删除表数据 磁盘空间还一直被占用
2021/10/16 MySQL