This is the 8th day of my participation in the More text Challenge. For details, see more text Challenge

preface

As a front-end developer, the prototype chain is a tall order. Interviewers like to ask questions about the prototype chain. For example, if a property of the constructor is changed, does it affect the currently constructed instance object? If the prototype is modified, does it affect the new instance object of the constructor new? Can instance objects modify constructor properties?

At this point, you will notice that the prototype chain is so zigzag that you can’t help but sigh: the prototype chain is so boring!

Today, Ice is staying up to talk more about prototype chains. From the __proto__ attribute, constructor attribute and so on 11 aspects in detail let you thoroughly understand it!

1. __proto__attribute

Any object has a __proto__ property, which refers to the constructor’s prototype property. Such as:

/ / case 1:

// Create the constructor
function Person(){}// Declare the instance object
var p = new Person()

// Prototype of instance object and prototype of constructor
console.log(p.__proto__ === Person.prototype) // true


/ / case 2:[] [] = =//false

// Push comes from Array prototype, [] is created by new Array, [] is an instance of Array
console.log([].push === [].push) // true
Copy the code

There are two ways to access prototype objects:

  1. Access to the prototype through the constructor: the constructor’sprototype
  2. Access to stereotype via instance object: of instance object__proto__

Points for attention:

Do not use instance objects to change things on the prototype (things starting with __ are private properties of the browser, do not want to be changed, and have browser compatibility issues).

// This is not recommended
// p.__proto__.age = 18

// Modify prototype members -- recommend
// Person.prototype.age = 18
Copy the code

2. The constructor property

The default property in the prototype refers to the current constructor.

function Person(){}console.log (Person) prototype) is as follows:Copy the code

console.log (Person) prototype) constructor) is as follows:Copy the code

Let’s see if constructor (instance) and constructor (constructor) are equal:

var p = new Person()
console.log(p.constructor == Person)  // true
console.log(p.constructor == Person.prototype.constructor) // true
Copy the code

Conclusion:

Understanding the prototype triangle:

  1. Constructors and prototypes: the spouse constructor (mom) finds the prototype (dad) through the prototype property and the dad finds the mom through the constructor property

  2. Relationship between constructor and instance: the mother and child constructor can create the child, but cannot access the child instance. As a child, can the child access the mother directly? (can’t)

  3. Direct relationship between instance and stereotype: parent and child access parent via __proto__ and child access mother indirectly, instance.proto. Constructor

3. The prototype chain

First, let’s be clear about two things:

1, any object has a __proto__ attribute, which points to the prototype object.

2. A stereotype is an object. A stereotype also has a __proto__ attribute, which points to the stereotype of the stereotype.

The prototype object also has its own prototype object, thus forming a chain structure, called the prototype chain.

// For example, the generated object has a father, a father's father and a father, so the father chain is the prototype chain.

function Person(){}// Person.prototype

// Instance object
var p = new Person()


// person.prototype // Example object prototype
// person.prototype. __proto__ // the parent of the prototype
// person.prototype.__proto__.constructor // the mother of the prototype
// person.prototype.__proto__ === Object

console.log(Object.prototype.__proto__)  // undefined

// Prototype chain for instance object p:
// p ==> Person.prototype ==> Object.prototype ==> null

Copy the code

4. Prototype chain for built-in objects

// Array
var arr = new Array(a)console.log(Array.prototype.__proto__ === Object.prototype) // true
console.log(Array.prototype.__proto__.constructor) Logon Object() {[native code]}

// Prototype chain for instance object arR:
// arr ==> Array.prototype ==> Object.prototype ==> null


// Date
var date = new Date(a)// Example date prototype chain:
// date ==> Date.prototype ==> Object.prototype ==> null


// Math is an object, not a constructor
Math.random()
console.log(Math.__proto__.constructor) Logon Object() {[native code]}

// Math prototype chain:
// Math ==> Object.prototype ==> null
Copy the code

Conclusion:

Object. Prototype is attached to any Object’s prototype chain

5. Search principles for attributes

Attribute lookup (search) principle: search along the stereotype chain.

  1. Object to find a property, first look at the current object itself, if the property is found, directly return
  2. If you don’t find it, you look on the object’s prototype, and if you find it, you just return it
  3. If not, continue up the prototype chain until object.prototype, if found, return
  4. If not found, return undefined
function Person(name){
    this.name = name
}

Person.prototype.name = "Big ice."
Person.prototype.color = "yellow"
Object.prototype.gender = "male"

// the prototype chain of p:
// p ==> Person.prototype ==> Object.prototype ==> null

var p = new Person("Big ice.")
console.log(p.color) // "Big ice"
console.log(p.gender) // male
console.log(p.sex) // undefined
p.toString() // toString is found along the prototype chain up to object.prototype.
Copy the code

Property setting principles:

  1. If the object does not have the property, the property is added, and the value is the assigned value.
  2. If the object has this property, the original value is overridden.

Conclusion:

Attribute search principle: Search along the stereotype chain. Attribute setting principle: if yes, override, if no, add.

6. hasOwnProperty()

Syntax: object.hasOwnProperty (” property “)

Returns true if it is, false if it is not

function Person(name){
    this.name = name
}

Person.prototype.gender = "male"
Object.prototype.sex = "female"

var p = new Person("Big ice.")


console.log(p.hasOwnProperty("name")) // true
console.log(p.hasOwnProperty("gender")) // false
console.log(p.hasOwnProperty("sex")) // false
console.log(p.hasOwnProperty("leg")) // false
console.log(p.hasOwnProperty("hasOwnProperty")) // false
console.log(Object.prototype.hasOwnProperty("sex")) // true
Copy the code

7. Differences between the in operator and hasOwnProperty

Returns true if the property is accessible to the object, whether it is on the object itself or on the prototype chain. Returns false if not.

Syntax: “property” in object

// hasOwnProperty(): determines whether the property belongs to the object itself

function Person(name){
    this.name = name
}

Person.prototype.gender = "male"
Object.prototype.sex = "female"

var p = new Person("Big ice.")


console.log("name" in p) // true
console.log("gender" in p) // true
console.log("sex" in p) // true
console.log("leg" in p) // false
console.log(p.hasOwnProperty("sex")) // false


// hasOwnProperty usage scenario:
// For... Inside the in loop, filter out the properties of the object itself
for(var k in p){
    // Requirements: only traverse the object itself, only print the object itself
    if(p.hasOwnProperty(k)){
        // note that the properties of the variable k are the object itself
        console.log(k)
    }

    // for.. When in traverses an object, it traverses the properties of the object itself as well as the properties of the prototype chain
    console.log(k) // name gender sex
}
Copy the code

8. propertyIsEnumerable():

PropertyIsEnumerable (” property “)

Function: Determine whether the attribute is traversable

  1. Determines whether the attribute is of the object itself
  2. Determining whether an attribute is traversable returns true only if the above two conditions are met
var obj = {
    name: "Big ice.".age: 18.hobby: "Male".gender: "male"
}

for(var k in obj){
    console.log(k)
}

Object.prototype.name = "lw"
for(var k in Object.prototype){
    console.log(k)
}
console.log(Object.prototype) // {name: "lw", constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ,... }

Object. Prototype's built-in members are immutable by default
// Properties added manually to an object are traversable by default

console.log(obj.propertyIsEnumerable("name")) // true
console.log(obj.propertyIsEnumerable("gender")) // false
console.log(Object.prototype.propertyIsEnumerable("hasOwnProperty")) // false
console.log(Object.prototype.propertyIsEnumerable("name")) // true
Copy the code

9. Use of Object.defineProperty

// Requirement: add a non-traversable gender attribute to obj
var obj = {
    name: "Big ice.".age: 20.hobby: "Male"
}

// object.defineProperty (obj, prop, desc)
// Parameter description:
// obj: adds attributes to an object, specifying which object it is
// prop: what properties are added to an object, which is a string
// desc: attribute descriptor, which is an object

// The default gender attribute is non-traversable
Object.defineProperty(obj, "gender", {
    value: "female".// value Sets the default value for this property of the object
    enumerable: true.Enumerable Sets whether the property is traversable. True is traversable
    writable: false          // writable Sets whether the property is modifiable. True modifiable
})

obj.gender = "Unknown"

console.log(obj) / / {name: "ice", the age: 20, hobby: "male", gender: "female"}
console.log(obj.propertyIsEnumerable("gender"))  // true
Copy the code

10. isPrototypeOf

Syntax: object A.isi prototypeof (object B)

Object A is the ancestor of B. Object A is the ancestor of B. Object A is the ancestor of B

function Person(){}var p = new Person()
/ / prototype chain
// p ==> Person.prototype ==> Object.prototype ==> null

// The prototype chain has nothing to do with the constructor
console.log(Person.isPrototypeOf(p)) // false 
console.log(Person.prototype.isPrototypeOf(p)) // true
console.log(Object.isPrototypeOf(p)) // false
console.log(Object.prototype.isPrototypeOf(p)) // true

// All objects have object.prototype on the prototype chain
console.log(Object.prototype.isPrototypeOf([])) // true
Copy the code

11. Instanceof and isPrototypeOf

The instanceof constructor determines whether the prototype property of the constructor is on the prototype chain of the object. If yes, return true (understand instanceof from the point of view of the prototype chain)

// [] the prototype chain:
// [] ==> Array.prototype ==> Object.prototype ==> null

console.log([] instanceof Array)  // true
console.log([] instanceof Object)  // true

// The difference: the effect is the same, the difference is the writing.
// object a.isprototypeof (object B) // determine whether A is on the prototype chain of b. A is A prototype object
// object B instanceof A; // determine if A's prototype property is in B's prototype chain


var date = new Date(a)console.log(Date.isPrototypeOf(date)) // false
console.log(Date.prototype.isPrototypeOf(date)) // true

console.log(date instanceof Date) // true
console.log(date instanceof Object) // true

console.log(date instanceof Date.prototype) // Error: Syntax error

Copy the code

Afterword.

I believe that after the detailed explanation of the 11 aspects, you must have a more profound and clear understanding of the prototype and the prototype chain. If this article is helpful to you, I hope you can give me a like, which is worth my staying up so long to finish this article. If there are mistakes, you are welcome to point them out. Thanks for reading.

PS: today is to participate in the nuggets more text challenge of the 8th day, I did not save draft, today fight to stay up all night or more this article, refueling together ~

Although not many people see it, but also to their own drainage ~ more challenging article catalog is as follows:

  • Flex layout container elements and project elements attributes
  • 2021.06.02 how to play with CSS Gradient Background
  • How to Use SVG to create Text Effects along Arbitrary Paths
  • 2021.06.04 “Front-end code specification of 3 categories and 15 subcategories, let the team code be standardized!”
  • Git Commit Specification for team management: How many people don’t write commit records?
  • 2021.06.06 “How to Control CSS mouse Style and Expand mouse Click area | Weekend study”
  • 2021.06.07 “Pure CSS implementation: imitation gold mining account password login, the red panda wu eye action switch small Egg”