3

我遇到的问题涉及向现有String 构造函数添加新方法的应用程序。在 Stoyan Stefanov 的 Object Oriented Program for Javascript 中,有一个使用Array 构造函数的 .reverse()方法为String 构造函数创建一个示例。这是示例:

String.prototype.reverse = function() {
     return Array.prototype.reverse.apply(this.split('')).join('');
}

我以为 Array 的.reverse()方法直接属于 Array 的对象。实际上,当我尝试使用以下语句执行第二段代码时:

String.prototype.reverse = function() {
     return Array.reverse.apply(this.split('')).join(''); //WITHOUT the .prototype
}

var rev = "karunesh".reverse(); //applying the code here

我在 Firebug 控制台中收到一条错误消息:"TypeError: missing argument 0 when calling function Array.reverse"。这对我来说没有任何意义。

当然,如果我在.prototype中添加回来,它工作得非常好。

另外,如果我必须调用原型才能从Array 对象访问.reverse() 方法,那么我是否必须对 Javascript 中的任何内置对象执行此操作?

我在这里先向您的帮助表示感谢!

4

2 回答 2

3

是不是我必须调用原型才能从 Array 对象访问 .reverse() 方法

不。要访问对象上的方法,只需使用点符号访问它。你想做的只是

return this.split('').reverse().join('');

这正是apply(或call)所做的:

var arr = this.split('');
return arr.reverse.apply(arr).join('');

最后arr.reverse === Array.prototype.reverse,因为那是Array对象继承的地方。您不是在访问构造函数对象本身的reverse方法,而是通过它们的原型Array访问所有Array 实例共享的属性。然而,您几乎不需要显式使用原型对象,只有当您处理不是Array实例(不共享原型)的对象时,例如arguments对象或NodeLists。

TypeError: missing argument 0 when calling function Array.reverse. 这对我来说没有任何意义。

Array.reverse是一种非标准的Array泛型方法,仅在 Firefox 中可用。它的目的是简化在其他对象上应用 Array 原型方法的构造,并且它确实将类数组对象作为它的第一个参数。一个例子:

Array.reverse([0, 1]) // [1, 0]

这相当于

Array.prototype.reverse.apply([0, 1]);

但是,你在做

Array.reverse.apply([…]/*, undefined*/)

这是使用(不相关)Array.reverse的数组调用函数并且没有实际参数,相当于this

Array.prototype.reverse.apply(undefined)

这引发了正当的例外。

于 2013-09-08T11:10:53.613 回答
1

Array.reverse未定义(至少在 Chrome 29 中)-Array.prototype.reverse是一个函数,它将反转调用它的“可迭代”的顺序。

这里要注意的关键是它Array不是像 Java 中那样的类 - 而是一个构造函数

[].constructor === Array;
// true

prototype属性Array实际上是为 的任何特定实例提供行为的原因Array

Object.getPrototypeOf([]) === Array.prototype;
// true

// Bad idea, just for an example
var guys = ['Tom', 'Harry', 'Richard'];
Array.prototype.exclaim = function() {
    return this.join(", ") + "?!?!?!";
}; 
guys.exclaim();
// Tom, Harry, Richard?!?!?!

这里的关键是 JavaScript 使用基于原型的面向对象模式,而不是您可能更熟悉的经典模式。JavaScript 没有包含所有行为但与实例不同的“类”,而是有对象,这些对象可以是其他对象的“原型”,为子对象提供数据和行为。

// Totally licit OO pattern in JavaScript
var prototypeClass = {
    method1: function() { console.log("Hello from method 1!"); },
    method2: function() { console.log("Hello from method 2!"); },
    classData: 42 
};

var prototypeInstance = Object.create(prototypeClass);

prototypeInstance.method1()  // Hello from method 1!
prototypeInstance.classData  // 42

// And you can modify the class after
// instantiating instances and the changes
// will be picked up by the instances
prototypeClass.happyPrimes = "Don't they teach recreational mathematics anymore?";

prototypeInstance.happyPrimes // The quote from 42
于 2013-09-08T03:54:30.780 回答