调用一个JavaScript对象的方法并不总是像您预期的那样简单。不仅有几种方式这么做,但每个人都可能会导致行为的方法不同,甚至意想不到的方式。它是全部的灵活性,在JavaScript中是固有的灵活性。在今天的文章中,我们将看看不同的方式调用对象方法及其后果。
方法和功能
有时似乎函数和方法是一体的。从技术上讲,他们是在JavaScript中,因为所有功能属于一些对象。然而,可以调用的方法没有一个对象点前缀(object.)被认为是函数。因此,他们属于全局命名空间。事实上,所有全局函数属于窗口对象,但它不需要对象点前缀。把它来测试,采取任何全局函数,你能想到的,像alert()、isNaN(),或eval()并在前面加上“窗口”。“对象标识符:
alert('hi there.'); window.alert('hi there.'); //仍然有效
isNaN('test'); //返回true
window.isNaN('test'); //仍然返回true
eval("isNaN('test');"); //还将返回true。
window.eval("window.isNaN('test');"); //真正的和
方法使用函数调用盗用()和应用()
在JavaScript中,函数本身是一个对象,有它自己的方法!其中两个是调用()和应用()。二者都为相同的目的,即允许一个对象使用另一个对象的方法对自己的设计。而整个事情听起来可能有点虚伪的,它使你免除复制方法跨多个对象。这两种方法都接受这个指针作为第一个参数,但是调用()需要每个目标函数参数分别,而应用()期望一个参数数组作为第二个参数:
Function.call(thisArg[, arg1[, arg2[, ...]]])
Function.apply(thisArg[, argArray])
call()方法签名是最适合你的方法参数预先知道。Apply应用(),另一方面,是为方法的参数列表可以更改或是未知的。
一些示例将使明确的区分。在第一个,路易吉是一个浸出谁没有自己的方法。如果他是一个Java c++类的,他的生活将贫瘠的事实上。然而,自从他住在JavaScript中,他可以使用一个函数的方法来执行马里奥的sayHello()方法。因为我们知道,sayHello()方法只需要一个名称参数,我们可以使用call()和 pass名称:
var Mario = {
name: 'Mario',
sayHello: function(name) {
return 'Hi '+name+', I\'m ' + this.name;
var Luigi = {
name: 'Luigi'
alert(Mario.sayHello.call(Luigi, name)); //outputs 'Hi Mario, I'm Luigi'
一个适合使用apply()方法是在对象创建和构造函数链接。原因在于,每一个对象将有一组不同的构造函数参数。在接下来的例子中,我们的createObject()方法添加到函数对象的原型,以便我们可以应用到任何对象的构造函数。person对象的初始化参数设置一个数组对象字面的通过,每个都包含属性的名称和相关联的值。通过使用apply()方法,我们可以通过数组来构造函数。这反过来,解析属性名称和值来设置它们。一旦创建了对象,我们可以访问类成员使用通常的object-dot (person.)表示法:
Function.prototype.createObject = function (aArgs) {
var init = this,
fNewConstr = function () { init.apply(this, aArgs); };
fNewConstr.prototype = init.prototype;
return new fNewConstr();
var args = [{name: "Rob"}, {age: 29}, {liesAboutHisAge: true}]; var person = function() {
for (var i = 0; i < arguments.length; i++) {
var propName = function(obj) { for(var name in obj) { return name; } }(arguments[i]);
this[propName] = arguments[i][propName];
}.createObject(args);
alert(person.name); // alerts "Rob"
调用一个实例方法没有一个实例
是的,你看的没错。不仅call()和应用()方法允许一个对象劫持另一个的方法,但您可以使用它们来调用一个对象的方法,还没有被实例化!我们之所以可以这样做是因为在JavaScript中,内置的对象和数组存储字符串等所有方法在原型属性。所以,尽管字符串和数组技术功能,其原型是对象。这里是一些代码,调用字符串的substr()方法直接而不是访问它槽‘str的实例变量:
alert(typeof String); //显示“函数”
var str = 'the quick brown fox jumped over the log.'; alert(String.prototype.substr.call(str, 4, 5));
你可能会想知道调用一个方法的优势,这种方式。有时候你只是不需要有一个实例的一个特定的对象类型,但需要得到它的一些功能。在我们最后一天的例子,我们有一个实例的参数传递。正如我们可以直接传递参数到函数或方法,他们反过来又可以互相之间传递参数。一个典型的例子就是一个函数使用一些参数,然后通过休息到下一个函数。这可以通过调用数组原型的slice() method:
function function1() {
alert(Mario.sayHello(arguments[0]));
//最后一个参数传递上
function2.apply(arguments[1], Array.prototype.slice.call(arguments, 2)); }
function function2() { //只有一个参数传递
alert(Mario.sayHello.call(this, arguments[0])); }
function1("Luigi", Luigi, Mario.name);
结论
有很多方法可以调用一个对象的方法在JavaScript中,正如许多方法传递参数的方法。通过利用两者,你可以节省很多的方法复制以及减少你的对象实例。尤其是在内置对象而言,您通常可以使用一个对象的方法没有创建实例的对象。
原文地址: