Hello, my name is Yiyi Lin, this is an article about THE things in JS prototypes and prototype chains. Before you know about prototypes and prototype chains, you need to know something about OOP in JS. You can also jump directly to prototypes and prototype chains. Let’s start reading. 😝

1. Mind map of this paper

Object Oriented Programming (OOP)

  • Process oriented: it is to analyze the steps needed to solve the problem, and then use functions to implement these steps step by step, when using one by one can be called.

  • Object orientation: it is the decomposition of the transaction that constitutes the problem into various objects. The purpose of building objects is not to complete a step, but to describe the behavior of something in the whole step of solving the problem.

  • Procedural advantages: Higher performance than object-oriented, because class invocation needs to be instantiated, the overhead is relatively large, more consumption of resources; For example, SCM, embedded development, Linux/Unix and so on generally adopt process-oriented development, performance is the most important factor. Disadvantages: No object-oriented easy maintenance, easy reuse, easy to expand

  • Advantages of object-oriented: easy to maintain, easy to reuse, easy to expand, because object-oriented has the characteristics of encapsulation, inheritance, polymorphism, can design a low coupling system, make the system more flexible, more easy to maintain disadvantages: lower performance than process oriented

3. Everything in JS is an object

  • The wrapper at the bottom of each data type is created based on Object. Reference types such as Function(), Function Array(), Date(), Math(), String(), Number(), and other basic types, nodeLIst node sets, window, and so on

  • Create a custom class based on constructor

// the literal form
function fn(){}
var obj = {}

// Constructor mode
var f = new fn()    // ==> new fn
console.log(f)

var obj = new Object(a)console.log(obj)
Copy the code

Using the new keyword uses the constructor to create an instance, which is a class. The other is the literal form

  • Object is a factory method that converts the incoming type to the corresponding original wrapper type
var num = Object(12)
console.log(num instanceof Number)  // true

var str = Object('12')
console.log(str instanceof String)  // true

var boolean = Object(true)
console.log(boolean instanceof Boolean)  // true
Copy the code
  • Differences in how values of primitive types are created
var a = 12
console.log(typeof a)   // 'number'
a.toFixed(2)    / / "12.00"

var b = new Number(12)
console.log(typeof b)   // 'object'
b.toFixed(2)    / / "12.00"

var c = new String('12')
console.log(typeof c)  // object
Copy the code

One thing to noteSymbol()Does not supportnewSyntax, browser does not thinkSymbolIs a constructor.

thinking

Q: Why can primitive values also use properties or methodsa.toFixed? A primitive value is a value with no attributes. Because the new keyword is used to create an instance, and the literal form of a is also an instance, instances have properties and methods. The creation of the literal form actually takes three steps, as shown in the code above

var a = 12
a. toFixed(2)

// It is equivalent to the following
Var a = new Number(12) * 2. Call the method or property on the instance * a.tofixed (2) * 3. Destroy the instance */

a.myPro = '12'
console.log(a.myPro)    // undefined
Copy the code

Note that the instance created with the original value is read-only, so no attributes or methods can be added to the instance. Adding attributes or methods creates a temporary object in the current line that will be destroyed when the current line of code runs, as shown abovea.myProUndefined undefined the Little Red Book 4 P114

How constructors work

function Person(name, age){
    var a = 12
    this.name = name
    this.age = age
}

var person = new Person('Lin Yiyi'.18)
console.log(person)
Copy the code

thinking

1. What happens in the new Person() process

  • Also open up a private scope stack memory, parameter assignment and variable promotion
  • Before the JS code executes, the constructor creates an object in the current private scope that is, opens up a heap of memory, but does not store anything at the moment. The browser makes the body of the function this point to the heap memory address
  • Top down code execution
  • At the end of the code execution, the browser will return the object created in the heap by default, no need to writereturn. I’m going to return an instance

JS variable promotion mechanism

Console. log(person.a) ==> undefined; this is the name of the Person object in ES6.

2. What about forcing the return value in the constructor?

function Person(name, age){
    var a = 12
    this.name = name
    this.age = age
    return 'Lin Yiyi'
    // return {name: 'linyiyi '}
}

var person = new Person('Lin Yiyi'.18)
console.log(person)
Copy the code

Person {name: “forest: forest “, age: 18}, return {name: The return value of ‘linyi ‘} is return {name:’ Linyi ‘}.

  • When the constructor returns a raw value, the browser returns an instance
  • When a created object is forcibly returned, the created object is returned. Does not match that we want to get an instance of a class. So it doesn’t make much sense to use return in the constructor

5. Prototype and prototype chain

Everything is an object in JS. Basic and reference types are created based on the base class Object. Functions are also object types, and prototype values are object types.

  • Fill in one knowledge blind spot: the prototypeFunction.prototypeIs a function, but ordinary functions have the prototypeprototypeIt’s an object
typeof Function.prototype // "function"

function fn(){}
typeof fn.prototype // "object"
Copy the code

1. Prototype vs constructor and __proto__

  • Each function type comes with oneprototypeThe prototype is the object type, and the browser will open up a heap of memory space.
  • The browser will add one to the heap memory spaceconstructorThe value of the property is the constructor itself. None in the constructorconstructorProperty, but from the constructorprototypeLook for,obj.constructor===obj.prototype.constructor
  • There’s one for every object__proto__Property that points to the class being createdprototype.prototypeThere are also objects__proto__This property. Is a function an object? Yeah, so the function also has__proto__This property. If the specified class cannot be determined, then__proto__Will point to Object.
  • Object, the base class__proto__It points to itself,__proto__The final point is zeronull.

But a__proto__Not instance properties or constructor properties, and most browsers support this kind of informal access. In fact__proto__fromObject.prototypeWhen usingobj.__proto__, can be interpreted as returnObject.getPrototypeOf(obj)

// One line of code parses the above one or two sentences
String.prototype.constructor === String   // true

function Fn(){}
var fn = new Fn()

// The third sentence above
fn.__proto__ === Fn.prototype   // true

//
fn.__proto__.__proto__.__proto__ === null   // true
Copy the code

The above code works because the constructor value in the heap memory stores the function itself

2. Prototype

  • Each class stores common properties and methods on the stereotype for instance invocation.
  • Prototype the class you createdprototypeAdding properties and methods is adding common methods to the instance.
 Object.prototype.myName = 'Lin Yiyi'
 var obj = new Object(a)console.log(obj.myName)
Copy the code

3. Search process of prototype chain mechanism

The prototype chain is based on__proto__The lookup up mechanism of. When an instance operates on a property or method, it looks in its current scope, and when it finds it, the search ends. Not found on the prototype object based on the created class__proto__Keep looking up until you find the base classObject.prototypeSo far, if still not found, directundefined

The blue line is the prototype chain

4. Consider the question, what are the output of the following results and why?

function Fn(){
    var a = 12
    this.getName = function(){
        console.log('private getName')
    }
}

Fn.prototype.getName = function (){
      console.log('public getName')}var fn = new Fn()
var fn1 = new Fn()
/ / 1, 2
console.log(fn.a)
console.log(fn.getName())
// 3,4,5
console.log(fn.getName === fn1.getName)
console.log(fn.__proto__.getName === fn1.__proto__.getName)
console.log(fn.__proto__.getName === Fn.prototype.getName)
/ / 6, 7
console.log(fn.hasOwnProperty ===Object.prototype.hasOwnProperty)
console.log(fn.constructor === Fn)
Private getName * false * true * true * true * true * true */
Copy the code

answer

If a does not use this, it will not be written to the constructor, and the output is undefined. If fn. GetName () is in the private scope of fn, the output is private getName

The __proto__ of fn and fn1 refers to the same prototype fn. Prototype, so it is true. 5. Same logic.

Prototype: __proto__ hasOwnProperty: __proto__ hasOwnProperty: __proto__ hasOwnProperty: __proto__ hasOwnProperty: __proto__ hasOwnProperty: __proto__ hasOwnProperty: __proto__ hasOwnProperty: So the output is true. 7 Fn does not have a constructor attribute, but looks for fn. Prototype.

5. The constructor added

function Fn(){}var fn = new Fn()
console.log(fn.constructor === Fn.prototype.constructor)  // true
console.log(fn.__proto__ === Fn.prototype)  // true
console.log(fn.__proto__.constructor === Fn)    // true
Copy the code

Constructor, fn has no constructor property and is read from fn’s prototype (fn. Prototype).

6. Thinking Number. The prototype. The constructor. = = = Number equal to the constructor results?

Number.prototype.constructor
// Number() { [native code] }

Number.constructor
// Function() { [native code] }
Copy the code

The result is not equal, the Number. The prototype. The constructor is looking for their Number on the prototype of the constructor, Number. Number no constructor property in the constructor, The __proto__ of the prototype chain looks up the prototype of the next class (in this case Function), and the Function’s constructor points to Function. So different.

reference

JavaScript goes from prototype to prototype chain

A further series of articles has been postedgithub, welcome start or issue

Thanks for reading so far, I’m Lin Yiyi, see you next time.