简体   繁体   中英

Does a new object in Javascript have a prototype property?

This is a purely trivial question for academic value:

If I create a new object, either by doing:

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

or

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

when I query the o.prototype property, I get undefined . I thought that any newly created object automatically inherits the Object.prototype prototype.

Furthermore, invoking toString() , (a method of Object.prototype ) on this object works just fine, implying that o does inherit from Object.prototype . So why do I get undefined ?

There is a difference between instances and their constructors.

When creating an object like {a: 1} , you're creating an instance of the Object constructor. Object.prototype is indeed available, and all functions inside that prototype are available:

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

But Object.create does something different. It creates an instance (an object), but inserts an additional prototype chain:

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

The chain will be:

Object.prototype  -  o  -  p

This means that:

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

To get the prototype "under" an instance, you can use Object.getPrototypeOf :

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

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

(Previously, you could access an instance's prototype with o.__proto__ , but this has been deprecated.)

Note that you could also access the prototype as follows:

o.constructor === Object; // true

So:

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

This fails for Object.create -created objects because they do not have a constructor (or rather, their constructor is Object and not what you passed to Object.create because the constructor function is absent).

Not a direct answer, but knowledge that everybody, who deal with inheritance in Javascript, should have.

Prototype inheritance in Javascript is a tricky concept. Up until now, it has been impossible to create an empty object (by empty I mean lacking even properties form Object via prototype). So this means that creating a new object always had a link to the original Object prototype. However, according to the specification, the prototype chain of an object instance isn't visible, but some vendors have decided to implement their own proprietary object properties so that you could follow it, but it's highly recommended not to use it in production code.

The following sample code demonstrates just two ways of creating an object instance.

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

Even though you don't manually add object properties to empty curly braces, you still get automatically added prototype chain. The same goes for the second example. To visualize it better, you can type those lines into Chrome console and then enter either someObject , otherObject or thirdObject to see details. Chrome shows the prototype chain by adding a proprietary property __proto__ which you can expand to see what is inherited and where it's from. If you executed something like

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

you would be able to call it on all instances, by executing otherObject.sayHello() .

However, using something that was implemented quite recently (therefore not supported by all browsers), you can actually create a truly empty object instance (doesn't inherit even from Object itself).

var emptyObject = Object.create(null);

When you enter it into Chrome console and then expand the emptyObject to see it's prototype chain, you can see that it doesn't exist. So even if you implemented the sayHello function to Object prototype, it would be impossible to call emptyObject.sayHello() since emptyObject does not inherit from Object prototype.

Hope it helps a bit with the general idea.

JavaScript has two types of objects: function object and non-function object. Conceptually, all objects have a prototype ( NOT A PROTOTYPE PROPERTY ). Internally, JavaScript names an object's prototype as [[Prototype]] .

There are two approaches to get any object (including non-function object)'s [[prototype]]: the Object.getPrototypeOf() method and the __proto__ property. The __proto__ property is supported by many browsers and Node.js. It is to be standardized in ECMAScript 6.

Only a function (a callable) object has the prototype property . This prototype property is a regular property that has no direct relationship with the function's own [[prototype]]. When used as a constructor ( after the new operator), the function's prototype property will be assigned to the [[Prototype]] of a newly created object. In a non-function object, the prototype property is undefined . For example,

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

Both objectOne and objectTwo are non-function objects therefore they don't have a prototype property .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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