“This is the 28th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

A question leads to the processing mechanism of JS prototypes and prototype chains

function Fn(x, y) {
    let sum = 10;
    this.total = x + y;
    this.say = function () {
        console.log('My sum is:The ${this.total}`);
    };
}
let f1 = new Fn(10.20); 
console.log(f1.sum);
console.log(f1.total);
Copy the code
  • This code checks if a property is a ‘private property’ of an object.
    • F1 is an instance of class Fn, which is also an instance of class Object
    • Object. The prototype. The hasOwnProperty method is used to detect a private property
     console.log(f1.hasOwnProperty('say')); //=>true: it must be a private property of the property.
     console.log(f1.hasOwnProperty('hasOwnProperty')); //=>false
    Copy the code
  • Just want to check if it’s a property [private or public]
     console.log('say' in f1); //=>true
     console.log('hasOwnProperty' in f1); //=>true
     console.log('sum' in f1); //=>false
    Copy the code
  • Requirement: Check whether this property is its public property.

The schema -> is its property, but it cannot yet be private

function hasPubProperty(obj, attr) {
    return (attr inobj) && ! obj.hasOwnProperty(attr); }console.log(hasPubProperty(f1, 'say')); //=>false
console.log(hasPubProperty(f1, 'hasOwnProperty')); //=>true
console.log(hasPubProperty(f1, 'sum')); //=>false

// toString is both private and public
f1.toString = function () {};
console.log(hasPubProperty(f1, 'toString')); //=>false  ? */
// How to check the toString attribute? We first introduce the prototype and prototype chain mechanism in JS to solve this problem

/* // instanceof: check whether the current instance is an instanceof a class console.log(f1 instanceof Fn); //=>true console.log(f1 instanceof Object); //=>true console.log(f1 instanceof Array); //=>false */
Copy the code
  • JS prototype and prototype chain processing mechanism
    • prototype

    Most of the “function datatypes” have the “prototype” property, which is itself an object for which “browsers by default allocate a heap of common properties and methods that instances can call.” The “prototype object” in the browser’s default heap has a default property “constructor”, the value of which is the current function/class itself!!

    • Function data type
      • Normal functions (real-name or anonymous functions)
      • Arrow function
      • Constructor/Class “Built-in class/Custom class”
      • Generator function
      • .
    • There is no prototype function
      • Arrow function
      • Es6-based quick operation to assign a function value to a member of an object
      • .
    • __proto__

    Each “object datatype” value has an attribute “__proto__ (prototype chain/implicit prototype)” that points to the “prototype of its own class”.

    • Object data type value
      • Ordinary objects
      • Special objects: array, re, date, Math, Error…
      • The function object
      • Instance objects
      • Constructor. Prototype
  • The following code is used as an example
function Fn() {
    this.x = 100;
    this.y = 200;
    this.getX = function () {
        console.log(this.x);
    }
}
Fn.prototype.getX = function () {
    console.log(this.x);
};
Fn.prototype.getY = function () {
    console.log(this.y);
};
let f1 = new Fn;
let f2 = new Fn;
console.log(f1.getX === f2.getX);
console.log(f1.getY === f2.getY);
console.log(f1.__proto__.getY === Fn.prototype.getY);
console.log(f1.__proto__.getX === f2.getX);
console.log(f1.getX === Fn.prototype.getX);
console.log(f1.constructor);
console.log(Fn.prototype.__proto__.constructor);
f1.getX();
f1.__proto__.getX();
f2.getY();
Fn.prototype.getY();
Copy the code

  • The relationship between Function and Object in the prototype chain

  • Requirements:objBefore, if it was an array, we created a new array; If it is a re, a new re is created. If it is an object, a new object is created; .
    • obj.constructorNormally, you get the class of the obJ real column object
    • let obj2 = new obj.constructorObj2 is the desired object
  • Eg: Code analysis
  function C1(name) {
      if (name) {
          this.name = name; }}function C2(name) {
      this.name = name;
  }
  function C3(name) {
      this.name = name || 'join';
  }
  C1.prototype.name = 'Tom';
  C2.prototype.name = 'Tom';
  C3.prototype.name = 'Tom';
  alert((new C1().name) + (new C2().name) + (new C3().name));
  // 'Tom' + undefined + 'join' => 'Tomundefinedjoin'
Copy the code
  • Go back above to detect the problem with public attributes
    • Example: hasPubProperty Regardless of whether it is private or not, we only see if it is public. As long as it is public, the current property is the public property of the object
    • Object.getprototypeof (obj) Gets the prototype of an Object (instance) : the prototype Object __proto__ points to
Object.prototype.hasPubProperty = function hasPubProperty(attr){
  // this -> obj specifies the object to process
  // Find the current Object's prototype and keep looking up until you find Object.prototype; If an object has ATTR in it, then it is a public property of the object.
  let proto = Object.getPrototypeOf(this)
  while(proto){
    if(proto.hasOwnProperty(attr)) return true
    proto = Object.getPrototypeOf(proto)
  }
  return false
}
let obj = {
  name:'obj'.toString(){}
}
obj.hasPubProperty('name') // => false
obj.hasPubProperty('toString') // => true
Copy the code