1

When understanding about the 3 broad type of objects in Javascript i.e. Literal, Function objects and Objects from functions, I had read somewhere that literal objects do not have prototype property like function objects (or constructors). Would that be a true statement ?

Reason I am asking this is since we can do;

var person = {
fn: 'ABC'
}
person.__proto__ = someObj;

Not sure if this setting using "proto" is really allowed across all browsers, which is why the statement is not true ?

Also is the same statement true for "objects from functions" ? i.e. when we do "new SomeFunctionObject()"

copenndthagen
  • 49,230
  • 102
  • 290
  • 442

4 Answers4

1

I had read somewhere that literal objects do not have prototype property like function objects (or constructors).

This sounds like it's referring to the property named .prototype, which is true. A function and a class will automatically receive a .prototype property, which contains one property (constructor, pointing to the class/function itself) and inheriting from Object.prototype.

The statement in your question is true. Only callable class-like objects - classes and functions - automatically receive these sorts of properties. Other objects do not:

class Foo {
}
function Foo2() {
}
const obj = {};

console.log(
  Foo.prototype,
  Foo2.prototype,
  obj.prototype
);

Regarding the code in your question, using __proto__ is permitted, but it's deprecated. As MDN says:

Warning: While Object.prototype.__proto__ is supported today in most browsers, its existence and exact behavior has only been standardized in the ECMAScript 2015 specification as a legacy feature to ensure compatibility for web browsers. For better support, it is recommended that Object.getPrototypeOf() be used instead.

Object.getPrototypeOf should be preferred nowdays.

i.e. when we do "new SomeFunctionObject()"

When you create an instance with new, the internal prototype of the new instance will (usually) be same object as the .prototype property of the constructor. That is, with the following code:

class Foo {
  // anything
}
const f = new Foo();

the internal prototype of the f instance will be the same object as Foo.prototype.

class Foo {
  // anything
}
const f = new Foo();
console.log(
  Object.getPrototypeOf(f) === Foo.prototype,
  f.__proto__ === Foo.prototype,
);

The only time where the internal prototype of an instance will not be the same as the constructor's .prototype would be when the constructor explicitly returns an object, which is somewhat unusual.

class Foo {
  constructor() {
    return {};
  }
}
const f = new Foo();
console.log(
  Object.getPrototypeOf(f) === Foo.prototype,
  f.__proto__ === Foo.prototype,
);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

functions have a prototype property, which inherits from Object.

function Person(last, first, middle){
  // constructors allow private variables that can be shared across methods without the use of `this.` - API developers may accidentally access properties meant to be private in classes, so use constructors
  const proto = Person.prototype;
  if(last !== undefined){
    this.last = last; this.first = first; this.middle = middle;
  }
  this.getFullName = (lastFirst = false)=>{
    const m = this.middle ? ' '+this.middle : ''
    if(lastFirst){
      return this.last+', '+this.first+m;
    }
    return this.first+m+' '+this.last;
  }
  this.setFullName = (last, first, middle)=>{
    proto.last = this.last = last; proto.first = this.first = first; 
    proto.middle = this.middle = middle;
    return this;
  }
}
console.log(typeof Person);
const bob = new Person('Smith', 'Bob', 'Gene');
console.log(bob.getFullName());
const james = new Person('Brown', 'James');
console.log(james.getFullName(true));
bob.setFullName('Static', 'Method', 'like');
const person = new Person;
console.log(person.getFullName()+' -- sort of');
console.log(typeof person);

Note that a new instance of a constructor returns a new Object literal.

StackSlave
  • 10,613
  • 2
  • 18
  • 35
0

You can set prototype using this:

Object.setPrototypeOf(obj, prototype)

You can also read docs here.

aturan23
  • 4,798
  • 4
  • 28
  • 52
0

If you explicitly assign a value to an object's proto, of course now this object has prototype property. When you just assign a value to an object, currently it has no prototype.This property has some problems on compatibility across browsers. An object built by new Con() certainly has prototype property natively.

fengxh
  • 384
  • 2
  • 8
  • But for an object built by new Con(), it's prototype is automatically set to whatever Con.prototype is set to...Isn't it ? OR can it still be set explicitly ? – copenndthagen Mar 09 '20 at 05:17
  • Yes, this is called inheritance in JS. Centainly it can be set explicitly, but it will change the prototype chain when getting some properties or methods from __proto__ – fengxh Mar 09 '20 at 05:28