JS Objects and Prototypes

Keywords: Attribute Vue Google

I. Objects of JS

1.1 Several ways to create objects

1.1.1 Create Objects by Literal Quantity

In js, a pair of {} is actually an object

var person = {
            name: "tom",
            age: 23,
            read: function () {
                console.log(name, ": read book")
            }
        }

1.1.2 via the constructor of the system

Create an empty object through the system's constructor, then use the js dynamic language feature, if an object does not have an attribute or method, click and attach the value

  			var person2 = new Object()
        person2.name = "jerry"
        person2.age = 23
        person2.say = function () {
            console.log(person2.name, ": say hello")
        }

1.1.3 via a custom construction method

Custom constructors are typically capitalized functions

			 function Person(name, age, sex) {
            this.name = name
            this.age = age
            this.sex = sex
            this.say = function () {
                console.log(this.name, " :say hello")
            }
        }

				// When creating objects, use the new keyword
		    p = new Person("tom", 23, "man")
        console.log(p instanceof Person)

Custom construction methods create objects through the following steps

  1. Open up space
  2. Set this as the current object
  3. Initialization properties and methods
  4. Return this

1.1.4 Factory Mode Creation Objects

     function Person(name,age,sex) {
            // new Object as current return value
            var obj  = new Object()
            obj.name = name
            obj.age = age
            obj.sex = sex
            obj.say = function () {
                console.log(this.name," :say hello")
            }
       			// Manually Return Objects
            return obj
        }
				// Factory mode creates objects without using the new keyword
        var p =  Person("tom",23,"man")
        console.log(p instanceof Person) // false

1.2 Constructors and Instance Objects

Take the following example:

   			// Relationships between constructors and instances
        function Person(name) {
            this.name = name
            this.say = function () {
                console.log(this.name," :say hello")
            }
        }

        // Object p was created with a custom constructor, Person
        var p = new Person("tom")

        console.dir(p)
        console.dir(Person)

The printed results are as follows:

  • Instance objects have constructor attributes in their u proto_u attributes, which record their own construction methods.
  • Person is both a construction method and an object, and the result we print directly from Person has an attribute prototype, which also has an attribute called constructor.It records that the construction method is itself.
  • Combining the above examples, we can actually deduce that the constructor in both the prototype properties of the instance object and the prototype properties of the constructor point to the same construction method, and then we can further deduce that p is a Person type.

_u prototype_u is actually a prototype object, which is described in more detail below

As an example above, the following output will help you understand

 			  console.log(p.constructor === Person) // true
        console.log(p.__proto__.constructor == Person) // true
        console.log(p.__proto__.constructor == Person.prototype.constructor) // true
        // Inferred from this, p === Person
        console.log(p instanceof Person) // true

There's a small problem. Look at the first line of console.log (p.constructor == Person) in the code above. We can't see the instance object p-constructor attribute through the code above. How can we use it without error undefined?

In fact, this is the chain of prototypes that involves js objects, (the following chapters will say). Generally speaking, js objects will take precedence over properties and methods in construction methods. If there are no properties and methods we use in the constructor, try to remove the properties and methods in the prototype objects in the corresponding construction methods for this object, and there will be no error.

2. Prototype of JS

2.1 Necessity of introducing prototypes

Why suddenly come back to see the prototype of js?

Since a lot of methods have been added to the vue's prototype in the source code, looking back at the prototype is certainly impossible to avoid.

Usually we use prototypes to save space.

Want to understand what space has been saved?Take a look at this space-saving example below.

  			// Problems with creating objects with constructors
        function Person(name) {
            this.name = name
            this.say = function () {
                console.log(this.name,": say hello")
            }
        }

        var p1 = new Person("tom")
        var p2 = new Person("jerry")

        p1.say()  // tom : say hello
        p2.say() //  jerry : say hello

        // todo returns false, meaning that the say methods of p1 and p2 are not the same, which is actually not a good thing
        console.log(p1.say == p2.say)

The P1 and P2 above are different objects created by a constructor. They all have a say function inside them. When we output p1.say == p2.say, we return false, indicating that there is a say method in each object. Assuming there are 1000 objects, isn't there 1000 say methods?It must be a waste of space.

So is there any way to have a say method for each new object?

Of course, the following:

			 // Shared Function, Derived Prototype
        function Say() {
            console.log(this.name, ": say hellp")
        }

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

        var p1 = new Person("tom")
        var p2 = new Person("jerry")

        p1.say()// tom : say hellp
        p2.say()// jerry : say hellp

        // This saves space, but it's easy to go wrong
        console.log(p1.say == p2.say) // ture

Now we do what we need, but it's not elegant enough, and there's a problem with uniformity. js is a dynamic type of language, so let's assume we don't know there's already a Say function, and then put var Say = "hello" after the Say function, overrides will occur.

2.2 Understanding Prototype

Here's an example: Let's add a say method to the prototype object of the construction method.

Actually, it's not hard to understand. You know, js objects are created by construction methods. We put public methods and attributes in the prototype objects of construction methods, can they share these methods and attributes?

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

        // Add Method to Prototype
        // Why can we say that a prototype is an object?Think about an object in js that can add properties and methods through points, dynamic points?
        Person.prototype.say = function () {
            console.log(this.name,":say hello")
        }

        var p1 = new Person("tom")
        var p2 = new Person("jerry")

        p1.say()//tom :say hello
        p2.say()//jerry :say hello
        console.log(p1.say == p2.say) // true

By printing the instance object and constructor above with console.dir(), the following figure is obtained:

   		  console.dir(p1)
        console.dir(p2)
        console.dir(Person)

As you can see from the figure above, you can draw the following conclusions:

  • Standard attributes directly owned in the instance object, such as name, are attributes that appear directly in the construction method and are private to the js object.
  • The instance object in the figure above has an attribute called: u proto_u, which is used by browsers, not programmers, so we call it a nonstandard attribute.In addition, Google browser supports this property, but in IE8 browser, we make an error when executing this console.log (p1. u proto_u), saying undefined

2.3 What is the relationship between prototypes, instance objects, and constructors?

  1. Instance objects are created with the new constructor, so the constructor is a template for creating instance objects.

  2. The constructor is that capitalized function, and in js we can console.log directly because it is actually an object.

  3. The purpose of prototypes is to extract common methods and store them all in the prototype object of the constructor, while sharing data and saving memory.

  4. The u proto_u of the instance object is both a nonstandard property and an object that points to the prototype property of the construction method.

  5. The prototype property of a construction method is both a standard property and an object for which we add properties and methods by means of the construction method.prototype.property/method= XXX.

  6. When we look through an object.property/method, we prefer to look through the object's construction method. If we can't find it, we try to look through the prototype again. That's why there is an object that clearly doesn't have a corresponding property or method added to it, but the object can be pointed out and used properly.Of course, undefined is a mistake if it doesn't exist in the prototype

2.4 About this object

  • See the first example below

The following this is not hard to understand, it's the object we've just come out of

 			  function Person(name) {
            // Consider who this is?
            this.name = name
            console.log(this)
        }

        var p = new Person("tom")
  • See the second example below

We add a method say to the prototype object of the construction method, and the this object used in this say method refers to the same object that we new out.This is the caller of the method.

      	function Person(name) {
            // Consider who this is?
            this.name = name
            console.log("n10: ",this)
        }

        Person.prototype.say = function () {
            // Who does this refer to in todo?
            // First, the method is to add it to the prototype object. Does this refer to the prototype object?
            // As you can see from the console, this.name is not actually a prototype object, but the caller (instance object) of the say() method
            console.log("n16: ",this.name,": say hello")
        }

        var p1 = new Person("tom")
        var p2 = new Person("jerry")

        p1.say()
        p2.say()
  • Look at the third example below:

Below, when you add a method to the prototype object of a construction method, not only this but also that appears.

The this object remains the object itself that we manually new out.

That also refers to the object that came out of our new est, so we need to go through it because inside the click event of a button, this refers to the button itself.

    // Encapsulating constructors in an object-oriented manner
    function ChangeStyle(btnId, dvId, color) {
        this.btnObj = document.getElementById(btnId)
        this.dv = document.getElementById(dvId)
        this.color = color
    }

    // Add a method to the prototype of a construction method
    ChangeStyle.prototype.init = function () {
        // This this here represents an instance object that calls the init method
        var that = this
        this.btnObj.onclick = function () {
            // Why can't todo use this instead of that in a function in its prototype???
            // todo or ask, who is this in the current function?
            that.dv.style.backgroundColor = that.color
        }
    }

2.5 Writing of Other Prototypes

  • The most common way to write is to add attributes or methods based on the current prototype, as follows
 		function Person(name) {
        this.name = name
    }

    // In the previous example, we all wrote code like the following, which actually adds up the properties of the original prototype object
    // The original prototype object had a property called consturctor
    Person.prototype.say  = function(){
        //todo
    }
  • You can also do the following

If you set the prototype this way, you are actually overwriting the original prototype object, so you need to re-add the constructor's direction as shown below.

I've also tried, of course, to get the right results when we use instanceof to determine whether an instance object is the corresponding constructor type, if we override the original prototype object without adding a guide to the contructor.

   Person.prototype = {
        constructor:Person, // Manually modify the pointing of the constructor
        height:"20",
        weight:"20",
        say:function () {
            // todo
        }
    }

2.6 Inter-access between methods

  • Membership methods in constructors are mutually accessible.
   function Person(name) {
        this.name = name
        this.say = function () {
            console.log("say")
            // From this example, you can see that an object's method can be called directly from its method
            this.eat()
        }
        this.eat = function () {
            console.log("eat")
        }
    }
  • The methods in the prototype are also mutually accessible.
    function Person(name) {
        this.name = name
    }

    Person.prototype.say  = function(){
        console.log("say")
        // Methods in the prototype can also access each other
        this.eat()
    }

    Person.prototype.eat  = function(){
        console.log("eat")
    }

    var p1 = new Person("tom")
    p1.say()

2.7 Overriding methods in built-in object prototypes

This allows you to override the methods in the prototype.

Of course, you can extend the original encapsulation class by adding methods to the prototype.

	  // Doing this on an existing js wrapper class is also a modification of the source code
    String.prototype.myReverse = function () {
        for (var i = 0; i < this.length; i++) {
            console.log("Recursion occurs")
        }
    }
    var str = "123"
    str.myReverse()

Posted by lunarul on Wed, 06 May 2020 18:06:59 -0700