繁体   English   中英

Javascript中的新对象是否具有原型属性?

[英]Does a new object in Javascript have a prototype property?

对于学术价值来说,这是一个纯粹微不足道的问题:

如果我创建一个新对象,可以通过执行以下操作:

var o = { x:5, y:6 };

要么

var o = Object.create({ x:5, y:6 });

当我查询o.prototype属性时,我得到了undefined 我认为任何新创建的对象都会自动继承Object.prototype原型。

此外,在此对象上调用toString()Object.prototype的方法)工作得很好,这意味着o确实从Object.prototype继承。 那我为什么要undefined

实例与其构造函数之间存在差异。

在创建像{a: 1}这样的对象时,您将创建Object构造函数的实例。 Object.prototype确实可用,并且该原型中的所有函数都可用:

var o = {a: 1};
o.hasOwnProperty === Object.prototype.hasOwnProperty; // true

但是Object.create做了不同的事情。 它创建一个实例(一个对象),但插入一个额外的原型链:

var o = {a: 1};
var p = Object.create(o);

该链将是:

Object.prototype  -  o  -  p

这意味着:

p.hasOwnProperty === Object.prototype.hasOwnProperty; // true
p.a === o.a; // true

要在实例“下”获取原型,可以使用Object.getPrototypeOf

var o = {a: 1};
var p = Object.create(o);

Object.getPrototypeOf(p) === o; // true
Object.getPrototypeOf(o) === Object.prototype; // true

(以前,您可以使用o.__proto__访问实例的原型,但这已被弃用。)

请注意,您还可以按如下方式访问原型:

o.constructor === Object; // true

所以:

o.constructor.prototype === Object.prototype // true
o.constructor.prototype === Object.getPrototypeOf(o); // true

这对Object.create创建的对象失败,因为它们没有构造函数(或者更确切地说,它们的构造函数是Object而不是传递给Object.create因为构造函数不存在)。

不是一个直接的答案,而是知道每个人在Javascript中处理继承都应该有。

Javascript中的原型继承是一个棘手的概念。 到目前为止,创建一个空对象是不可能的(通过空表示我的意思是通过原型缺少表单对象的属性)。 所以这意味着创建一个新对象总是有一个指向原始Object原型的链接。 但是,根据规范,对象实例的原型链是不可见的,但是一些供应商决定实现他们自己的专有对象属性,以便您可以遵循它,但强烈建议不要在生产代码中使用它。

以下示例代码仅演示了创建对象实例的两种方法。

var someObject = {};
var otherObject = new Object();
var thirdObject = Object.create({});

即使您没有手动将对象属性添加到空花括号,您仍然会自动添加原型链。 第二个例子也是如此。 要更好地可视化,您可以在Chrome控制台中键入这些行,然后输入someObjectotherObjectthirdObject以查看详细信息。 Chrome通过添加专有属性__proto__来显示原型链,您可以展开该属性以查看继承的内容以及它的来源。 如果你执行了类似的事情

Object.prototype.sayHello = function() {
  alert('hello');
};

您可以通过执行otherObject.sayHello()在所有实例上调用它。

但是,使用最近实现的东西(因此并不是所有浏览器都支持),您实际上可以创建一个真正空的对象实例(甚至不从Object本身继承)。

var emptyObject = Object.create(null);

当您将其输入Chrome控制台然后展开emptyObject以查看它的原型链时,您可以看到它不存在。 因此,即使您将sayHello函数实现为Object原型,也无法调用emptyObject.sayHello()因为emptyObject不会从Object原型继承。

希望它对一般的想法有所帮助。

JavaScript有两种类型的对象:函数对象和非函数对象。 从概念上讲,所有对象都有一个原型不是原型性质 )。 在内部,JavaScript将对象的原型命名为[[Prototype]]

获取任何对象(包括非函数对象)的[[prototype]]有两种方法: Object.getPrototypeOf()方法和__proto__属性。 许多浏览器和Node.js都支持__proto__属性。 它将在ECMAScript 6中进行标准化。

只有一个函数(一个可调用的)对象具有prototype属性 这个prototype属性是一个常规属性,与函数自己的[[prototype]]没有直接关系。 当用作构造函数(在new运算符之后)时,函数的prototype属性将被赋值给新创建的对象的[[Prototype]]。 在非函数对象中,prototype属性是未定义的。 例如,

var objectOne = {x: 5}, objectTwo = Object.create({y: 6});

objectOne和objectTwo都是非函数对象,因此它们没有prototype属性

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM