Four rules

  1. Reference types, all with object characteristics, i.e. (freely extensible attributes);
  2. Each reference type has an implicit prototype __proto__ attribute whose value is an ordinary object;
  3. The reference type, the implicit prototype __proto__ property value points to the explicit prototype property value of its constructor;
  4. When you try to get a property of an object, if the object doesn’t have the property itself, it will look in its implicit __proto__(that is, its constructor uses the function’s display prototype);

Reference types: Object, Array, Function, the Date, the RegExp, __proto__ here we called implicit stereotype, no official Chinese unified way;

Rule 1: Reference types have object properties, i.e. (freely extensible attributes) :

const obj = {}
const arr = []
const fn = function() {}

obj.a = 1
arr.a = 1
fn.a = 1

console.log(obj.a) // 1
console.log(arr.a) // 1
console.log(fn.a) // 1
Copy the code

This rule is easy to understand, and it is the same for Date and RegExp.

Rule 2: Reference types have an implicit prototype __proto__ attribute, the value of which is an ordinary object;

const obj = {}
const arr = []
const fn = function() {}

console.log('obj.__proto__', obj.__proto__) // 
console.log('arr.__proto__', arr.__proto__)
console.log('fn.__proto__', fn.__proto__)

Copy the code

Rule 3: Reference type, implicit prototype __proto__ property value points to its constructor display prototype property value;

const obj = {}
const arr = []
const fn = function() {}

console.log('obj.__proto__ === Object.prototype', obj.__proto__ === Object.prototype) // true
console.log('arr.__proto__ === Array.prototype', arr.__proto__ === Array.prototype) // true
console.log('fn.__proto__ === Function.prototype', fn.__proto__ === Function.prototype) // true
Copy the code

Rule 4: When you try to get a property of an object, if the object doesn’t have the property itself, it will look in its implicit prototype __proto__(the explicit prototype of its constructor).

Const obj = {a: 1} console.log(obj.tostring) // ƒ toString() {[native code]}Copy the code

ToString = toString; toString = toString; toString = toString; toString = toString; toString = toString; toString = toString;


A special case

  • I’m trying to override this rule by looking at the following code:
Function Person(name) {this.name = name return this // Var Nick = new Person(' Nick ') console.log(nick.tostring) // ƒ toString() {[native code]} var Nick = new Person(' Nick ') console.log(Nick.Copy the code

Nick is an instance of the Person constructor, and Person prototype doesn’t have a toString method. So why does Nick get the toString method?

Here comes the concept of prototype chain. Nick instance looks for itself first and finds no toString method. The prototype constructor is an object, and the prototype constructor is an object. So find its __proto__, which is the prototype of the Object constructor, so find the toString method under Object.prototype;


A picture

  • Describe the prototype chain with pictures:

The last one is null, which is designed to avoid infinite loops. Object. Prototype’s implicit prototype points to NULL


One way to

  • Instanceof operator: Tests whether the constructor’s Prototype property appears anywhere in the object’s Prototype chain.

Instanceof’s simple tablet looks like this:

Function instance_of(L, R) {function instance_of(L, R) { Const baseType = ['string', 'number', 'Boolean ', 'undefined', 'symbol'] if (basetype.includes (typeof(L))) {return false} let RP = r.prototype L = L.__proto__ // take L implicit prototype While (true) {if(L === null) {return false} if(L === RP) {return true} L = L.__proto__ // If not found, continue up the prototype chain}}Copy the code

Let’s look at this code again

function Foo(name) {
      this.name = name
  }
  var f = new Foo('nick')
  console.log(f instanceof Foo) // true
  console.log(f instanceof Object) // true
Copy the code

The judging process of the above code is roughly as follows:

  1. F instanceof Foo: f’s implicit prototype __proto__ and foo. prototype are equal, so return true
  2. F instanceof Object: the implicit __proto__ of f differs from object. prototype, so keep going. F’s implicit __proto__ refers to foo. prototype, so continue using foo.prototype. __proto__ to compare object. prototype, which will be equal. Because foo. prototype is a normal object;