显示原型模式不适用于Array

时间:2013-09-19 21:45:35

标签: javascript prototype

当我写http://jsfiddle.net/XJwvP/):

时,它会起作用
var Person = function(name) { this.name = name; }
Person.prototype = function () {
   var sayHello = function (name) {
         alert("Hello, " + name);
   };

   return {
      sayHello: sayHello
   };
}();

var person = new Person("Max");
person.sayHello("James");

我写http://jsfiddle.net/ZKd4R/)后无效:

Array.prototype = function () {
   var sayHello = function (name) {
         alert("Hello, " + name);
   };

   return {
      sayHello: sayHello
   };
}();

var array = new Array();
array.sayHello("James");

错误

Uncaught TypeError: Object [object Array] has no method 'sayHello' 

为什么我不能对Array对象使用相同的方法?

2 个答案:

答案 0 :(得分:3)

像您一样替换Array.prototype不会影响新的Array实例,因为Array构造函数在语言中很特殊(它是内置构造函数 )。规范在15.4.2.1

  

新构造对象的[[Prototype]]内部属性设置为原始Array原型对象,即 Array.prototype 15.4.3.1)的初始值

如果您选中15.4.3.1,则会注意到Array.prototype也不是[[可写]]。我刚刚在Chrome控制台中对其进行了测试:

var ap = Array.prototype;
Array.prototype = {};
ap == Array.prototype; // true

答案 1 :(得分:1)

@bfavaretto已经解释了为什么它不起作用。以下是您应该使用的模式来避免此类问题:

function Person(name) { this.name = name; }
(function(proto) {
   function sayHello(name) {
         alert("Hello, " + name);
   }

   proto.sayHello = sayHello;
}(Person.prototype));

var person = new Person("Max");
person.sayHello("James");

(function(proto) {
    function sayHello(name) {
        alert("Hello, " + name);
    }

    proto.sayHello = sayHello;
}(Array.prototype));

var array = []; // or `new Array();`
array.sayHello("James");

我们称之为mixin原型模式: - )