On JavaScript Object and Inheritance

  • 2021-07-02 23:09:27
  • OfStack

JavaScript is the second programming language I came into contact with after C. When I was a freshman, I found a Chinese JavaScript program design in the library. At that time, it was almost white in programming. In addition, the book didn't mention the programming mechanism of JavaScript at all, and there were some misleading words. Since then, there has been a deep misunderstanding of JavaScript, and JavaScript is only an object-oriented language running on a browser. It is worth writing down the confusing and misleading places in JavaScript. Of course, limited to the author's limited level, there is no development experience, so it is inevitable that there are omissions, but also hope to criticize and correct.

Objects for JavaScript

What is the object

new keywords can be seen everywhere in JavaScript code, which makes people misunderstand that JavaScript is a language based on class inheritance like Java1. But this is not the case. There are no classes in JavaScript, so what is the object of JavaScript that is not a class? In a sense, the object of JavaScript is the dictionary (hash table) in Python, which is actually a key-value pair like this:


me={
  "fisrtName" : "seek",
  "lastName" : "truth" ,
  "getName" : function(){
    return this.firstName+this.lastName; //this Equivalent to a pointer to this object 
  }
}

This is a misunderstanding place, which is a little incomprehensible when I first saw it, but it is reasonable to use 1 carefully. We can use the [] operator to get elements like Python1, and we can also use the. operator to get elements:


me.firstName // => seek
me["lastName"] //=> truth
me.getName() // => seektruth

new operator

Since there are no classes in JavaScript, what is the new operator doing? This is one of the most misleading aspects of JavaScript design. JavaScript is a functional programming language, the function in JavaScript is a first-class citizen, and the function in JavaScript is also an object. When the function object is created, it will be added with calling attributes. Compared with the pit, JavaScript function has two calling methods, one is called with new keyword, and the other is called without new keyword. The former will return an object, while the latter will return the contents of return statement. Consider the following 1-segment function:


function Obj(name){
  this.name=name;
  return name;
}

If we use the new operator to call:

obj = new Obj ("seektruth")//obj will be one object: {"name": "seektruth"}

If we call directly:

obj = Obj ("seektruth")//obj will be a string: "seektruth"

Indeed, the design is quite poor. When we call, we need to distinguish whether we need to use new. Generally speaking, functions that need to be called with new keyword will start with uppercase.

Even worse, if the return value is 1 object:


function Obj(name){
  this.name=name;
  return {};
}

This returns the value in the return statement whether we call it with or without the new operator:


new Obj("seektruth") //=> {}
Obj("seektruth") //=> {}

What the hell is the design......

Object inheritance

Prototype

As mentioned earlier, there is no class in JavaScript, so how does JavaScript realize inheritance? The answer is through the prototype chain. In JavaScript, each object will have a prototype. When creating an object, if not explained, the prototype inherited by the object is Object. prototype, and the function object will inherit ES90prototype (Function. prototype inherits Object. prototype):


Object.prototype // => {}
Function.prototype // => [Function]

We can see the prototype of the object through its __proto__ familiarity:


a={}
a.__proto__ // => {}

JavaScript realizes inheritance by specifying the prototype of an object. There are three main ways to specify the prototype of an object. 1 is to specify the prototype in the constructor, 2 is to directly modify the __proto__ attribute of the object, and 3 is to use the Object. create function. Let's look at 1 in turn

Specify the prototype in the constructor

We can specify the prototype of the object in the constructor:


me={
  "firstName" : "seek",
  "lastName" : "truth" ,
  "getName" : function(){
    return this.firstName+this.lastName; //this Equivalent to a pointer to this object 
  }
}

function Obj(name){
  this.firstName = name;
  this.__proto__ = me; // Specifies that the prototype is me Object 
}

After specifying the prototype, we can access the properties of the prototype after creating a new object:


obj = new Obj("foo"); // => { firstName: 'foo' }
obj.firstName // => foo
obj.lastName // => truth
obj.getName() // => "footruth"

When accessing an object, you will first try to find the attribute in the modified object, and if not, go back to the prototype until Object. prototype. If we override the properties (methods) in the prototype in a new object, the new properties (methods) will override the definitions in the prototype in actual use, which is a bit like function overloading in a class-based language.

Note that if the lastname property of the prototype me object changes because the obj object is looking for properties in the prototype, the lastname property of the obj object will also change:


me.lastName = "me"
obj.lastName // => "me"
obj.getName() // => "foome"

Directly change the prototype of an object

We can also specify (change) the prototype of the object directly:


me.firstName // => seek
me["lastName"] //=> truth
me.getName() // => seektruth
0

Use the Object. create function

Although the first two methods can solve the problem, these two writing methods are not elegant, because JavaScript is not a class-based language, and the first writing method is easy to misunderstand. Crockford, the author of JavaScript, thinks that new should not appear in JavaScript, and recommends using Object. create function to create objects based on prototypes. The use of the Object. create function is simple:


me.firstName // => seek
me["lastName"] //=> truth
me.getName() // => seektruth
1

obj3 = Object. create (me) and obj2 = {}; obj 2. proto = me is equivalent, but the first one is more elegant and easier to understand.

Summarize

As a prototype-based and functional programming language, JavaScript has many elegance and strength in design, but at the same time, it has many dross and pits. Officially, JavaScript is also the most misunderstood language. After learning the object inheritance mechanism of JavaScript, I feel that my level is still greatly improved.


Related articles: