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 相关文章推荐
jQuery 连续列表实现代码
Dec 21 Javascript
jQuery Flash/MP3/Video多媒体插件
Jan 18 Javascript
学习掌握JavaScript中this的使用技巧
Aug 29 Javascript
switch语句的妙用(必看篇)
Oct 03 Javascript
input输入密码变黑点密文的实现方法
Jan 09 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
Jan 22 Javascript
Angular如何引入第三方库的方法详解
Jul 13 Javascript
vue3.0 搭建项目总结(详细步骤)
May 20 Javascript
layer 刷新某个页面的实现方法
Sep 05 Javascript
webpack常用构建优化策略小结
Nov 21 Javascript
vue created钩子函数与mounted钩子函数的用法区别
Nov 05 Javascript
ant design charts 获取后端接口数据展示
May 25 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
Notice: Trying to get property of non-object problem(PHP)解决办法
2012/03/11 PHP
php计算整个mysql数据库大小的方法
2015/06/19 PHP
Yii视图操作之自定义分页实现方法
2016/07/14 PHP
再谈ie和firefox下的document.all属性
2009/10/21 Javascript
javascript中用星号表示预录入内容的实现代码
2011/01/08 Javascript
jquery ajax请求实例深入解析
2012/11/26 Javascript
JQuery中阻止事件冒泡几种方式及其区别介绍
2014/01/15 Javascript
Javascript中的arguments与重载介绍
2015/03/15 Javascript
利用jQuery实现WordPress中@的ID悬浮显示评论内容
2015/12/11 Javascript
jQuery Validate初步体验(一)
2015/12/12 Javascript
弱类型语言javascript中 a,b 的运算实例小结
2019/08/07 Javascript
微信小程序引入VANT组件的方法步骤
2019/09/19 Javascript
vue页面切换项目实现转场动画的方法
2019/11/12 Javascript
python中合并两个文本文件并按照姓名首字母排序的例子
2014/04/25 Python
python简单分割文件的方法
2015/07/30 Python
Python批量创建迅雷任务及创建多个文件
2016/02/13 Python
python回调函数中使用多线程的方法
2017/12/25 Python
Python 从相对路径下import的方法
2018/12/04 Python
Python3批量移动指定文件到指定文件夹方法示例
2019/09/02 Python
win10安装tensorflow-gpu1.8.0详细完整步骤
2020/01/20 Python
python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍
2020/02/25 Python
tensorflow 20:搭网络,导出模型,运行模型的实例
2020/05/26 Python
Keras中的多分类损失函数用法categorical_crossentropy
2020/06/11 Python
Jupyter Notebook安装及使用方法解析
2020/11/12 Python
如何用python开发Zeroc Ice应用
2021/01/29 Python
Python的Tqdm模块实现进度条配置
2021/02/24 Python
美国Rue La La闪购网站:奢侈品、中高档品牌限时折扣
2016/10/19 全球购物
Pam & Gela官网:美国性感前卫女装品牌
2018/07/19 全球购物
丹麦优惠购物网站:PLUSSHOP
2019/03/24 全球购物
FC-Moto英国:欧洲最大的摩托车服装和头盔商店之一
2019/08/25 全球购物
知名企业招聘广告词大全
2014/03/18 职场文书
中英文求职信范文
2015/03/19 职场文书
环境保护宣传标语大全!
2019/06/28 职场文书
企业转让协议书(范文2篇)
2019/08/15 职场文书
MySQL数据库⾼可⽤HA实现小结
2022/01/22 MySQL
Win11更新失败并提示0xc1900101
2022/04/19 数码科技