categories: [js]

tags: []

toc: true

date: 2021/1/13

Introducing the question: why do the following two pieces of code output different results

function MyConstructor() {}
const myObject = new MyConstructor();
myObject.constructor == MyConstructor; // true
Copy the code
function MyConstructor() {}
MyConstructor.prototype = {};
const myObject = new MyConstructor();
myObject.constructor == MyConstructor; // false
Copy the code

Front knowledge

Objects and the methods

An object in JS is a bunch of named properties that can be read or written, there is no class in JS, functions are first-class citizens in JS (equivalent to ordinary variables), and methods in JS are simply functions that specify a context.

Prototypes

  • Object’s built-in propertiesPrototype, used below[[Prototype]]As a substitute.
  • Pay attention toobj.prototypeAnd the object’s[[Prototype]]These are two different concepts.
  • Js itself does not provide direct access[[Prototype]]The method, however, is supported by most modern browsers__proto__right[[Prototype]]Get and modify.

[[Get]]

The [[Get]] operation is triggered when obtaining a property of an object, such as obj. For the default [[Get]](which is not Proxy), the following steps are performed:

  • Check if the object itself has this property and use it if it does
  • If a is not in OBj, then obj’s will be checked[[Prototype]]Is there an A attribute on
    • Returns if it exists
    • None. Keep checking OBJ’s[[Prototype]]the[[Prototype]], recursive execution
  • [[Prototype]]Is at the end ofObject.prototypeIf not found, undefined is returned. It is worth mentioning that many global methods are obtained in this way, such asvalueOf, toString, hasOwnProperty

[[Set]]

For myObject.foo = ‘bar’

  • Foo exists in myObject.foo, so only changes will be made.
  • Foo does not exist on myObject, will look up on the [[Prototype]] chain similar to the [[Get]] operation.
    • [[Prototype]] if foo is not found on the chain, add a new foo attribute
    • [[Prototype]] foo exists on the chain
      • [[Prototype]] String foo writable true: myObject adds a new property foo
      • [[Prototype]] chain foo writable false: strict mode error, non-strict mode ignored
      • [[Prototype]] setters foo on the chain. Call this setter directly

Get down to business, and analyze the code line by line

Ellipses represent objects and arrows refer to properties of other objects. [[Prototype]] The chain is in green

#1: Define the constructor

function MyConstructor() {}
Copy the code

  • MyConstructor.prototypeConstructor is an automatically created object that has a constructor property referring back to MyConstructor. It’s important to note that,Only function objects have the Prototype attributeTherefore, only function objects have the constructor attribute
  • [[Prototype]] of MyConstructor points to function. Prototype instead of MyConstructor. Prototype.
  • Object. Prototype is the end of the [[prototype]] chain, and Object. Prototype’s [[prototype]] is null

#2: Assign a new Prototype attribute to MyConstructor

MyConstructor.prototype = {};
Copy the code

Set MyConstructor’s prototype to an empty object {} that has no constructor property

#3: Call the constructor to generate a new object

const myObject = new MyConstructor();
Copy the code

Since the new operation sets myObj’s [[Prototype]] to myconstructive. Prototype, which is a plain empty object, So MyConstructor’s [[Prototype]] is associated with object. Prototype

So myObj. Constructor calls, according to the picture green the prototype chain of search, finally found the Object. The prototype. The constructor

Reference:

  • Constructors Considered Mildly Confusing
  • Chapter 5 Prototype you-dont-Know-JS

Write in the last

If you have problems loading images, visit your blog