12

我刚开始阅读 Douglas Crockford 的“ Javascript The Good parts ”,他解释了增强基本类型。

Function.prototype.addMethod=function(name,func) {
    this.prototype[name]=func; 
    return this; 
};

完成此操作后,addMethod可用于所有基本对象,如StringNumber等。这让我感到困惑

  1. 当我没有将它添加到Object.prototype时,为什么会发生这种情况?

  2. 为什么向Function.prototype添加方法会反映在所有基本对象中?

4

3 回答 3

16

他可能的意思是在这样做之后,addMethod 对所有基本对象 对象类型(如 String、Number 等)都可用。这是因为 String 对象是一个函数(但由 String 创建的对象不是)。

例如,给定

var s = '';

你可以做

String.addMethod(...);

但不是

s.addMethod(...);

JavaScript 类型系统的简要说明如下:

JavaScript 没有类的正常概念。相反,您可以通过在调用任何函数时将 new 关键字放在它前面来将其转换为构造函数来实现相同的效果。

例如:给定

function MyFunction(x) { this.myX = x; }

如果你像这样调用它

var myObj = new MyFunction(10);

它将创建一个名为 myObj 的对象。该对象将有一个名为 myX 的成员变量。函数 MyFunction 被认为是对象的构造函数(并存储在“构造函数”属性中。

(额外的问题:如果你在没有 new 关键字的情况下调用上面的函数会发生什么,即var x = MyFunction(10)。答案可能会让任何明智的人感到惊讶。)

现在您已经了解了如何将任意函数转换为构造函数。内置对象完全相同,字符串对象由函数String创建,数字由函数Number创建,等等。

正如那些内置对象是由函数创建的一样,这些函数中的每一个也是由“函数”函数创建的(哎呀!)。

现在到原型。

在上面的例子中,如果你在某处写

MyFunction.prototype.someNewMethod = function() {}

MyFunction 构造函数/函数创建的所有对象似乎都有一个名为 someNewMethod 的额外成员函数。你可以用原型做很多其他时髦的事情,比如替换原型,或者替换原型的原型,但我不是这方面的专家。

于 2009-09-03T11:26:54.537 回答
1

在面向对象的 javascript 中,函数可以用作类和构造函数。因此,如果您的类被命名为 MyObject,您可以执行以下操作:

// create a class/constructor
function MyObject() {
   // ...
}

// add a static method to the MyObject class
MyObject.someFunction = function() {
   // ...
}

// add an instance method to the MyObject Class
MyObject.prototype.someFunction = function() {
   // ...
}

在您的示例中, addMethod 作为实例方法添加到 Function 类,这意味着它可用于 Function 的所有实例。MyObject 函数/类/构造函数是 Function 的一个实例,因此您可以在其上调用 addMethod。这适用于大多数任何对象类型,但不适用于 IE 和其他一些浏览器中的 HTMLElements。

于 2009-09-03T11:55:03.017 回答
1
  1. JavaScript 中的函数是对象。所有对象都有一个指向 Object.prototype 的隐藏链接。因此对于第一个声明:

    > `Function.prototype.addMethod=function(name,func) {}
    

    您已经声明了一个链接到 Function.prototype 的函数,该函数本身链接到 Object.prototype。

  2. 对于第二部分,它只是一个赋值,您将名称值对设置为 Object.prototype,并将 add 方法返回给所有 String、Number 对象,因为它都在原型中声明。
于 2012-05-12T13:39:55.260 回答