如何实现在Javascript
采用apply
是有关功能上下文(this
关键字)和参数传递。
首先,我想你应该知道在什么情况下该this
关键字隐含集:
1 - 当一个函数被调用的方法(函数被调用为对象的成员):
obj.method(); // 'this' inside method will refer to obj
2-甲正常的函数调用:
myFunction(); // 'this' inside the function will refer to the Global object
// or
(function() {})();
-3-当new
运算符用于:
var obj = new MyObj(); // this will refer to a newly created object.
下面是当apply
和call
来,这些方法让你设置明确情况下,当你调用一个函数,例如:
function test(a) {
alert(this + a);
}
test.call('Hello', ' world!');
在上面的代码当test
功能称为this
关键字设置到字符串('Hello'
),以及使所述a
参数(' world.'
)。
两者,call
和apply
变化所调用的函数内的执行功能(this
关键字)的上下文中,但它们之间差别是与apply
,则可以发送一个数组或数组状物体作为要执行的函数的参数,这是非常有用的,例如:
function sum() {
var result = 0;
for (var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
}
var args = [1,2,3];
sum.apply(null, args); // will return 6
这可以避免一些非常哈克,坏(共同)eval
调用,如:
var max = Math.max(2,4,6,8); // 8
但什么:10
eval('sum(' + args.join() +')');
另一个例子中,Math.max
和Math.min
方法,这些方法可以接收参数一样任意数量?
var numbers = [2,4,6,8];
numbers.push(10);
var max = Math.max.apply(null, numbers); // 10
还要注意的是,当null
或undefined
用作this
参数与call
或apply
,所述this
对象将参照全局对象(类似于情形#2,正常功能调用)。
对于Math.max
例如,上下文是不是真的有关,因为它们就像“静态”方法,该this
关键词未在内部使用...
我不知道任何设计名为“应用模式”的模式,所以我并不认为这与设计模式完全相关。然而,在JavaScript中有一个函数对象的应用方法(以及相应的调用方法),所以我将解释这些方法。
apply和call方法基本上允许一个对象从另一个对象中“窃取”一个方法。你会发现,在JavaScript中,方法非常迟到:在调用时。只有在调用方法时,才能解决'this'
的值。在通常的方法调用:
some_object.do_something();
在do_something的'this'
关键字引用some_object。申请并致电,让您重新分配'this'
。例如:
some_object.do_something.apply(another_object);
'this'
do_something now中的关键字指的是another_object。所以你在another_object上调用属于some_object的do_something方法。
现在,这是有趣的,但为什么会有人想这样做?这就是为什么这是非常有用的一个具体的例子:
// say you want to get some DIVs in the document, you can get all of them with:
var some_divs = document.getElementsByTagName('DIV');
// say you want the third to fifth DIV in the document, some_divs looks like an
// array so you might think you can slice it, but it's not. It's a collection
// of elements that fakes being an array and doesn't implement the slice method.
// No worries, we can steal the slice method from an array
// and apply it to some_divs:
var wanted_divs = [].slice.apply(some_divs,[2,5]);
// Alternatively:
var wanted_divs = [].slice.call(some_divs,2,5);
还有另一种使用情况适用的是之间如何应用和呼叫作品差异的结果。如果你把所有的参数在数组和函数需要单个参数,您可以使用适用于传递数组和具备的功能看不到阵列作为单独的参数的内容:
function some_function (first,second) {
alert(first+second);
}
var argument_array = ['hello','world'];
some_function.apply(null, argument_array);
您还可以使用呼叫/申请继承。
function Client (id) {
this.id = id;
this.name = "Client" + id;
}
Client.prototype = {
constructor: Client
, toString: function() {
return this.name;
}
};
function WebClient (id) {
Client.call (this, id);
}
WebClient.prototype = new Client();
WebClient.prototype.constructor = WebClient;
WebClient.prototype.ping = function() {
// do stuff
};
通知Client.call (this, id);
此使用this
实例,一个new WebClient
会造成执行Client
。因此,当
this.id = id;
this.name = "Client" + id;
在内部Client
执行WebClient
实例得到分配的那些属性。
+1非常好! ---- – 2009-12-29 18:27:00
啊我想我现在明白了。我错过的全部观点是“这是作为第一个参数提供的价值”。现在,为什么我们想将应用方法区分为单独的调用类型,这是有道理的。 那么什么是差异。通话和应用关键字之间呢? – Priyank 2009-12-29 18:30:41
@cms +1完美打印! – 2011-12-11 16:11:37