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 properties
Prototype
, used below[[Prototype]]
As a substitute. - Pay attention to
obj.prototype
And 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.prototype
If 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.prototype
Constructor 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