Function.prototype.apply()
apply()
方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数。
语法:
1 | fun.apply(thisArg, [argsArray]) |
thisArg
: 在fun
函数运行时指定的this
值。需要注意的是,指定的this
值并不一定是该函数执行时真正的this
值,如果这个函数处于非严格模式下,则指定为null
或undefined
时会自动指向全局对象(浏览器中就是window
对象),同时值为原始值(数字,字符串,布尔值)的this
会指向该原始值的自动包装对象。argsArray
: 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。
从 ECMAScript
第5版开始,可以使用任何种类的类数组对象,就是说只要有一个 length
属性和[0...length)
范围的整数属性。例如现在可以使用 NodeList
或一个自己定义的类似 {'length': 2, '0': 'eat', '1': 'bananas'}
形式的对象。
注意:Chrome 14 以及 Internet Explorer 9
仍然不接受类数组对象。如果传入类数组对象,它们会抛出异常。
例子:
例1
1 | var numbers = [5, 6, 2, 3, 7,+Infinity,-Infinity]; |
例2
1 | var cbj = { |
例3
1 | function Person() { |
当心:如果用上面的方式调用 apply
, 你很可能会遇到方法参数个数越界的问题. 当你对一个方法传入非常多的参数 (比如超过1W多个参数) 时, 就非常有可能会导致越界问题, 这个临界值是根据不同的 JavaScript
引擎而定的.
Function.prototype.call()
call()
方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。
语法:
1 | fun.call(thisArg[, arg1[, arg2[, ...]]]) |
thisArg
:在fun
函数运行时指定的this
值。需要注意的是,指定的this
值并不一定是该函数执行时真正的this
值,如果这个函数处于非严格模式下,则指定为null
和undefined
的this
值会自动指向全局对象(浏览器中就是window
对象),同时值为原始值(数字,字符串,布尔值)的this
会指向该原始值的自动包装对象。arg1, arg2, ...
:指定的参数列表。
可以让call()
中的对象调用当前对象所拥有的function
。你可以使用call()
来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)
例子:
使用 call
方法调用函数并且指定上下文的this
1 | var cbj = { |
使用call方法调用父构造函数
1 | function Product(name, price) { |
使用call
方法调用匿名函数
1 | var animals = [ |
Function.prototype.bind()
bind()
方法创建一个新的函数, 当被调用时,将其this
关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
语法
1 | fun.bind(thisArg[, arg1[, arg2[, ...]]]) |
thisArg
:当绑定函数被调用时,该参数会作为原函数运行时的this
指向。当使用new
操作符调用绑定函数时,该参数无效。arg1, arg2, ...
:当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
bind()
函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5
规范中内置的call
属性)。当新函数被调用时 this
值绑定到 bind()
的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。一个绑定函数也能使用new
操作符创建对象:这种行为就像把原函数当成构造器。提供的 this
值被忽略,同时调用时的参数被提供给模拟函数。
例子:
创建绑定函数
bind()
最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的 this
值。
1 | this.x = 9; |
用预设的初始参数创建函数
1 | function List() { |
作为构造函数使用的绑定函数
绑定函数适用于用new
操作符 new
去构造一个由目标函数创建的新的实例。
当一个绑定函数是用来构建一个值的,原来提供的 this
就会被忽略。
然而, 原先提供的那些参数仍然会被前置到构造函数调用的前面。
1 | function Point(x, y) { |
创建捷径
将一个类似于数组的对象(array-like object)
转换成一个真正的数组
1 | var a = {'1':'小明','2':'小黑','4':'小刚',length:6}; |
用 bind()
可以使这个过程变得简单
slice
是 Function.prototype
的 call()
方法的绑定函数.
并且将 Array.prototype
的 slice()
方法作为 this
的值
1 | var a = {'1':'小明','2':'小黑','4':'小刚',length:6}; |
最后
call()
方法第二个参数是若干个参数的列表;而apply()
方法的第二个参数是一个包含多个参数的数组;bind()
方法第二个参数是若干个参数的列表,是创建函数的预设的初始参数 。apply 、 call 、bind
三个方法的第一个参数都是this要指向的对象,可以改变函数的this对象的指向。bind
方法 返回对应的创建函数,便于后续调用;apply 、call
则是立即执行 。