2010-08-10 88 views
7

我有一些对象,比如son,我想从另一个对象father继承。将原型添加到对象文字

当然我可以做一个构造函数的父亲,像

Father = function() { 
    this.firstProperty = someValue; 
    this.secondProperty = someOtherValue; 
} 

然后用

var son = new Father(); 
son.thirdProperty = yetAnotherValue; 

但是这不正是我想要的。由于son将具有许多属性,因此将儿子声明为对象文字将更具可读性。但是,我不知道如何设置它的原型。

做这样的事情

var father = { 
    firstProperty: someValue; 
    secondProperty: someOtherValue; 
}; 
var son = { 
    thirdProperty: yetAnotherValue 
}; 
son.constructor.prototype = father; 

将无法​​正常工作,因为原型链似乎被隐藏,并且不关心constructor.prototype的变化。

我想我可以使用__proto__属性在Firefox,像

var father = { 
    firstProperty: someValue; 
    secondProperty: someOtherValue; 
}; 
var son = { 
    thirdProperty: yetAnotherValue 
    __proto__: father 
}; 
son.constructor.prototype = father; 

但是,据我了解,这是不是语言的标准功能,它是最好不要直接使用它。

有没有一种方法来指定对象文字的原型?

+0

http://stackoverflow.com/questions/1592384/adding-prototype-to-object-literal – 2012-12-01 20:04:36

回答

11

你说得对,__proto__是非标准的属性,你必须设置一个新的对象的[[Prototype]],只有两个标准方法是:

  • 通过使用一个构造函数和new运营商(如你已经提到)。
  • 使用ECMAScript 5 Object.create方法。

Object.createwidely supported尚未(适用于IE9Pre3 +,火狐3.7Alpha +,Chrome浏览器的Safari 5+ 5+,犀牛1.7),但在某些时候所有的实现将符合该规范ES5。

它可以有两个参数,第一个是将用作新对象的[[Prototype]]的对象,第二个是另一个对象,其中可以描述自己的属性(与您的结构相同将使用Object.defineProperties)。

例如:

var father = { 
    firstProperty: 1, 
    secondProperty: 2 
}; 

var son = Object.create(father, { 
    thirdProperty: { 
    value: 'foo' 
    } 
}); 

father.isPrototypeOf(son); // true 
son.firstProperty; // 1 

son内部[[Prototype]]属性将指father,它将包含名为thirdProperty的值属性。

+1

你的答案清除了我所有的疑惑,但遗憾的是Object.create的语法(加上了“value:”)更不可读。 – Andrea 2010-08-10 20:01:56

+1

是的,他们为什么不能创建一个只接受对象字面值的函数。我的意思是,大多数时候我们只关心键和值,而不是像只读属性元数据那样关心。 – 2012-12-01 20:27:16

-1

指定对象文本的原型有点“不可思议”,因为您首先需要使用构造函数语法(例如,新的X())创建的对象上的原型。不要说这是不可能的......但这很奇怪。一个类似的模式被证明是很好的(例如jQuery所使用的),而是将原型定义为对象文字。例如:

var X = function() {}; 
X.prototype = { 
    protoFunc1: function() {}, 
    protoFunc2: function() {} 
}; 
2

这是不正确的jmar777。例如,如果你有

var X = function() {}; 
X.prototype = { 
    protoFunc1: function() { console.log('p1');}, 
    protoFunc2: function() { console.log('p2');} 
}; 

X.protoFunc1(); // is not a function 

这意味着,你在做什么:

X.prototype = {} 

仅仅是创建一个名为原型的对象。不是实际的原型。要使用原型,你必须使用构造函数。

然而,如果你将它修改为这个(构造函数方法)

function X(){}; 
X.prototype.protoFunc1 = function() { 
    console.log('p1'); 
} 
X.prototype.protoFunc2 = function() { 
    console.log('p2'); 
} 

var x = new X(); 
x.protoFunc1(); //'p1' 

它的工作。

要么使用对象字面值方法而不使用原型或使用使用原型的构造器方法。