什么是Javascript中的调用模式参考函数调用模式,我该如何使用它? 使用此调用模式有什么好处。
答案 0 :(得分:24)
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
参数({{1 }})。
' world.'
和call
都改变了被调用函数中执行函数(apply
关键字)的上下文,但它们之间的差异是使用this
,您可以发送一个数组或类似数组的对象作为要执行的函数的参数,这非常有用,例如:
apply
这可以避免一些非常hacky,糟糕(和常见)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
另一个例子,eval('sum(' + args.join() +')');
和Math.max
方法,这些方法可以接收任意数量的参数,如:
Math.min
但是如果你有一个数字数组呢?
var max = Math.max(2,4,6,8); // 8
另请注意,当var numbers = [2,4,6,8];
numbers.push(10);
var max = Math.max.apply(null, numbers); // 10
或null
用作undefined
或this
call
参数时,apply
对象会引用到全局对象(类似于情况#2,正常函数调用)。
对于this
示例,上下文并不真正相关,因为它们就像“static”方法一样,Math.max
关键字未在内部使用...
答案 1 :(得分:1)
您还可以使用call / apply进行继承。
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);
这将使用Client
创建的this
实例执行new WebClient
。因此,当
this.id = id;
this.name = "Client" + id;
在Client
内执行,WebClient
实例正在为这些属性分配。
答案 2 :(得分:0)
我不知道任何名为The Apply Pattern的设计模式,所以我并不认为这与设计模式有任何关系。但是,javascript中有一个函数对象的apply方法(以及相应的调用方法),所以我将解释这些。
apply和call方法基本上允许对象从另一个对象“窃取”方法。你会看到,在javascript中,方法很晚才会被绑定:在调用时。仅在调用方法时才解析'this'
的值。在正常的方法调用中:
some_object.do_something();
do_something中的'this'
关键字指的是some_object。通过应用和通话,您可以重新分配'this'
。例如:
some_object.do_something.apply(another_object);
do_something中的'this'
关键字现在指的是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);
还有另一个使用案例,这是申请和通话工作方式不同的结果。如果你有一个数组中的所有参数,并且函数需要单独的参数,你可以使用apply来传递数组并让函数看到数组的内容作为单独的参数:
function some_function (first,second) {
alert(first+second);
}
var argument_array = ['hello','world'];
some_function.apply(null, argument_array);