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中函数作为参数调用的方法,包括了javascript中函数作为参数调用的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了javascript中函数作为参数调用的方法。分享给大家供大家参考。具体分析如下: 先来看示例: 这段代码执行的顺序是:从上往下顺序解释执行,这是JS的规定。 这里主要说明一下m.eachMap()中函数做为参数是怎么传递并执行的:
问题内容: 我需要帮助使此类型适用于任何类型。 我有一个函数,我需要接受具有属性的其他类型。 我尝试使用接口,但不适用于我的财产情况。这是代码: 我明白了 错误prog.go:39:在Count的参数中无法将人类([人类]类型)用作[]哺乳动物 有关更多详细信息,请参见Go Playground,网址为http://play.golang.org/p/xzWgjkzcmH 问题答案: 使用接口而不
我在将这部分Java转换为Kotlin时遇到了问题: 方法的第二个参数(注意不是集合)接受。我尝试了几个解决方案,包括提供一个lambda: 但这导致: 错误:(32,38)Kotlin:意外标记 错误:(33,38)Kotlin:意外标记 错误:(31,56)Kotlin:类型不匹配:推断的类型是Kfunction1<@parametername mutablehttpresponse<>?,u
本文向大家介绍JS随机调用指定函数的方法,包括了JS随机调用指定函数的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JS随机调用指定函数的方法。分享给大家供大家参考。具体如下: 本代码通过随机定时器调用指定函数,可达到间隔随机时间之行指定的函数的目的 希望本文所述对大家的javascript程序设计有所帮助。
当我多次调用同一个函数时,每次都传递了不同的参数,我会这样做: 有没有更方便的方法做到这一点呢?
在下面的代码中,我编写了两种方法: 将变量定义为String的变量 根据键入的内容返回两种不同结果的方法 我有一个名为的变量在中,而中的参数被命名为。在中,我使用而不是-为什么这样工作? 调用方法时,参数是否无关紧要? 我知道,当输入一个返回某个内容的方法时,必须对其进行定义,参数进一步定义该方法将要处理的内容,因此,我假设,当从另一个方法调用所述方法时,必须使用相同的参数,但情况似乎并非如此。