向对象字面量添加原型

8
我是一个有用的助手,可以将文本翻译成中文。
我有一个对象,比如说儿子,我想让它继承另一个对象父亲
当然,我可以为父亲创建一个构造函数,例如:
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;

无法工作,因为原型链似乎被隐藏起来,并且不关心构造函数.prototype的更改。
我认为我可以在Firefox中使用__proto__属性,例如:
var father = {
  firstProperty: someValue;
  secondProperty: someOtherValue;
};
var son = {
  thirdProperty: yetAnotherValue
  __proto__: father
};
son.constructor.prototype = father;

但是据我所了解,这不是语言的标准特性,最好不要直接使用它。
有没有一种方法可以指定对象字面量的原型?

https://dev59.com/InI-5IYBdhLWcg3w99kH - Camilo Martin
4个回答

11

你说得对,__proto__是一个非标准的属性。你可以通过以下两种标准方法之一设置新对象的[[Prototype]]

  • 使用构造函数和new操作符(正如你已经提到的那样)。
  • 使用 ECMAScript 5 的Object.create方法。

Object.create 目前不被广泛支持(只能在 IE9Pre3+、Firefox 3.7Alpha+、Chrome 5+ 和 Safari 5+、Rhino 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
你的回答解决了我所有的疑惑,但遗憾的是,带有“value:”的Object.create语法似乎更不易读。 - Andrea
1
是的,为什么他们不能编写一个简单接受对象字面量的函数呢?我的意思是,大多数情况下我们只关心键和值,而不是像使其只读这样的属性元数据。 - Camilo Martin

3
那是不正确的,jmar777。例如,如果您有以下内容:
var X = function() {};
X.prototype = {
  protoFunc1: function() { console.log('p1');},
  protoFunc2: function() { console.log('p2');}
};

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

那意味着你正在做的事情是:
X.prototype = {}

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

但是,如果您将其修改为这样(构造方法)

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

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

它会起作用。

可以选择不使用原型的对象字面量方法,或者使用构造函数方法并使用原型。


-1
使用ES2015及更高版本,您可以使用字面量__proto__作为属性名称,在对象字面量中设置原型。因此,您可以针对您的情况执行以下操作:
const father = {
  firstProperty: someValue,
  secondProperty: someOtherValue,
};
const son = {
  __proto__: father,
  thirdProperty: yetAnotherValue,
};

这里有一篇很好的文章关于这个话题。


-2

为对象字面量指定原型有些“奇怪”,因为您主要希望在使用构造函数语法(例如new X())创建的对象上使用原型。并不是说这不可能...但这很奇怪。一个经过充分验证的类似模式(例如,jQuery使用的模式)是将原型定义为对象字面量。例如:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接