"JS Basics" Javascript "Inheritance"

Source: Internet
Author: User

It's time to write "inherit", why quote, because when you finish reading this article, you will know that inheritance is actually inaccurate.

First, class
1. Classes in the traditional class-oriented language:
Class/Inheritance Describes the organizational form of a code. As an example:
"Cars" can be seen as a special case of "transportation".
We can define a Vehicle class and a Car class to describe this relationship.
The definition of Vehicle may include engines, manned capabilities, and so on, which is a common feature description for all modes of transport, such as airplanes, trains, and automobiles.
When defining the car class, it makes no sense to repeat the definition of "manned capacity", and we just need to declare that the car class inherits the base class of Vehicle. Car is actually a specialization of the generic Vehicle definition.
Car is just a class, and when we visualize it more, say Porsche, Mercedes-Benz, it's a process of instantiation.
It is also possible to define a method in Car that is the same as in Vehicle, which is a subclass that overrides the parent class for a particular method, in order to be more specialized and more compliant with the description of the subclass, which is called polymorphism.

These are classes, inheritance, instantiation, and polymorphism.

One more example: the building of houses
Architects designed the blueprints, and the builders built the real buildings according to the blueprints. Architecture is a physical example of a blueprint, which is essentially a copy of a building blueprint. Then the construction worker can go to the next place, repeat all the work, and create a copy.
The relationship between architecture and blueprint is indirect. You can understand the structure of the building through blueprints, and only observe that the building itself is unable to obtain this information. But if you want to open a door, you have to touch the real building-the blueprint can only indicate where the door should be, but not the real door.
A class is a blueprint. In order to get a truly interactive object, we must construct (instantiate) a thing according to the class, which is often referred to as an instance. This object is a copy of all the attributes described in the class.

In the traditional class-oriented language, class inheritance, instantiation is actually copied, with a picture:

The arrows indicate the copy operation.

The subclass Bar is a separate and completely different class from the parent class Foo. The subclass contains a copy of the behavior of the parent class, or it can overwrite an inherited behavior by defining the same method name in the parent class in the subclass, which does not affect the methods in the parent class, and the two methods do not affect each other. The same is true for class Bar and instance B1, B2, which is instantiated as an object form through a copy operation.

2. Classes in JavaScript
JavaScript does not actually have a class concept, but we have been used to thinking about classes, so JavaScript also provides some approximate classes of syntax that we use to simulate classes, but this "class" is different from a class in a traditional class-oriented language.
In the process of inheritance and instantiation, the object mechanism of JavaScript does not automatically perform replication behavior. In short, there are only objects in JavaScript, and there is no "class" that can be instantiated. An object will not be copied to other objects, they will only be associated, that is, the copy is actually a reference. (For copy reference, you can see the "JS basic" depth copy of the article, the first part)


Second, JavaScript prototype chain, "class" and inheritance
1. [[[[Prototype]] built-in properties for objects in [Prototype]]:javascript] are references to other objects in fact. What is his role?
When you try to access an object's properties, it triggers the object's built-in operation [[Get]],[[get]] to find the property you want from the object. But how did he find it?
Example:

1 var testobject = {2     a:23};4 console.log (TESTOBJECT.A)//2

In the above code, when you console, the [[Get]] action is triggered to find the A property in Testobject. for the default [[Get]] operation, the first step is to check whether the object itself has this property, and if so, use it directly. In the second step, if a is not in testobject, that is, the desired property cannot be found in the object itself, it will continue to access the [[prototype]] chain of the object.

Example:

1 var anotherobject  = {2     a:23};4 5 var testobject  = object.create (anotherobject); 6 7 Console.log (testobject . a); 2

The Object.create () method creates an object and associates the [[prototype]] of the object with the specified object (anotherobject).
example, the [[prototype]] of the Testobject object is associated to the anotherobject. The testobject itself does not have a property, but it can still console out testobject.a to 2, which is [[Get]] found from Testobject's [[prototype]] chain, which is the attribute a in Anotherobject 。 But if there is no attribute a in anotherobject, and [[prototype]] is not empty, it will continue to be searched. The process continues until a matching property name is found, or the full bar [[prototype]] chain is not found, and the return value of the [[Get]] operation is undefined.

So where is the end of the prototype chain?
All of the normal [[prototype]] chains will eventually point to the built-in Object.prototype.

2, "class": In the previous part of the content, we have said that JavaScript in fact there is no traditional sense of "class", but we have been trying to imitate the class, mainly using a function of a special feature: all functions by default will have a named prototype A public and non-enumerable property that points to another object.
Example:

1 function foo () {2     //... 3}4 5 Foo.prototype; {}6 7 var a = new Foo (); 8 object.getprototypeof (a) = = = Foo.prototype;//true

This object is created when you call new Foo () and is then associated to the Foo.prototype. As in the example, when you call new Foo (), A is created, and the [[prototype]] link inside a is linked to the object that Foo.prototype points to.

In traditional class-oriented languages, classes can be duplicated multiple times, and each instantiation is replicated at once. However, there is no similar replication mechanism in JavaScript. You cannot create multiple instances of a class, you can create more than one object, and their [[prototype]] associations are the same object. Because, by default, replication does not occur, these objects are not completely lost, and they are interrelated.

Just like the example above, new Foo () generates a new object called a, and the internal [[prototype]] of the new object is associated with the Foo.prototype object. Finally we get two objects, and they relate to each other. We do not really initialize a class, and we do not actually copy any behavior from the "class" into an object, but to associate two objects with each other.

Again: In JavaScript, you do not copy an object ("class") to another object ("instance"), but simply associate them. Look at a diagram:

arrows indicate associations.
This diagram expresses the [[prototype]] mechanism, which is the prototype inheritance.
But inheritance is inaccurate because inheritance in a traditional class-oriented language implies a copy operation, and JavaScript (default) does not copy object properties, but instead creates an association between two objects that can delegate access to the properties and functions of another object. Delegates can more accurately describe the association mechanism of objects in JavaScript.


3. (prototype) inheritance
Let's look at an example:

1 function foo (name) {2     this.name = name; 3} 4  5 foo.prototype.myName = function () {6     return this.name; 7} 8  9 function Bar (name,label) {     foo.call (this,name);     This.label = label;12}13 14//created a new Bar.prototype Object and associates it to the Foo.prototype. Bar.prototype = Object.create (foo.prototype); Bar.prototype.myLabel = function () {     return this.label;19} var a = new Bar ("A", "obj a"), Console.log (a.name)//"A" console.log (A.label)//"Obj a"

When declaring function bar () {}, bar will have a default. prototype associated to the default object, but this object is not the foo.prototype we want. So we created a new object by Object.create () and linked it to the object we wanted, namely Foo.prototype, to discard the original associated object directly.

If you say why not use the following method of association?

Bar.prototype = Foo.prototype

Because this approach does not create a new object that is associated to foo.prototype, it simply lets bar.prototype refer to Foo.prototype directly. So when you execute a Bar.prototype.myLabel assignment statement, the Foo.prototype object itself is modified directly.

Or, why not new?

Bar.prototype = new Foo ();

This does create a new object that is associated to the Foo.prototype. But it also executes a call to the Foo function, and if the Foo function has a property added to this, a modified state, a write log, and so on, it will affect the "Descendants" of Bar ().

Add two points here for new, easy to understand:

function foo () {    console.log ("Test");} var a = new Foo (); Test

When you execute var a = new Foo (); That is, using new to invoke the function, the following four steps are performed:
1. Create a new object
2. This new object will be executed [[Prtotype]] Connected
3. This new object is bound to this on the function call
4, if the function does not return a value, then the function call in the new expression will automatically return the new object.

Another point when you execute var a = new Foo (); When the console hits test. Foo is just a normal function, and when called with new, it creates a new object and assigns a value to a, which of course calls itself.

In conclusion, the best way to create an appropriate association object is to use Object.create (), which has the disadvantage of creating a new object, discarding the old object, and not modifying the default existing object directly.
Object.create () Creates an object that has an empty [[prototype]] connection. It's a new approach to ES5, let's look at how it's implemented in an old environment:

if (! Object.create) {    object.create = function (o) {        function F () {}        f.prototype = O;        return new F ();}    }

We used an empty function F, by rewriting its. Prototype property to point to the object that you want to associate, and then using new F () to construct a new object to associate with.


Three, class-type inheritance design patterns and commissioned design patterns
Both of these patterns are used to implement inheritance, which is essentially an association.

1, class-style inheritance design mode:
This should be the most familiar, the main thing is to use the constructor and prototype chain to achieve inheritance, that is, the so-called object-oriented style.

1 function Foo (WHO) {2     this.me = who; 3} 4  5 Foo.prototype.identify = function () {6     return "I am" + this.me; 7} 8  9 function Bar (WHO) {     foo.call (this,who);}12 bar.prototype = Object.create (Foo.prototype); R.prototype.speak = function () {     alert ("Hello," + this.identify () + "."); }18 var B1 = new Bar ("B1"), var b2 = new Bar ("B2"); B1.speak (); B2.speak ();

The subclass Bar inherits the parent class Foo, and then generates two instances of B1 and B2. B1 inherited the Bar. Prototype, Bar.prototype inherited the Foo.prototype.

2. Commissioned design mode
Object Affinity Style:

1 Foo = {2     init:function (WHO) {3         this.me = who;   4     }, 5     identify:function () {6         return "I Am" +this.me; 7     } 8}; 9 Bar = Object.create (Foo); bar.speak = function () {     alert ("Hello," + this.identify ())};14 var B1 = object.create (Bar), B1.init ("B1"), + var b2 = O Bject.create (Bar), B2.init ("B2"); B1.speak (); B2.speak ();

The code also uses [[prototype]] to delegate the B1 to bar and delegate the bar to Foo, which, like the previous code, implements the association of three objects.


3, the above two modes have achieved three objects of association, then what is the difference between them?
The first is the different ways of thinking:
Class inheritance design pattern: Defines a common parent class that can be named task, defining the behavior of all tasks in a task. Then the subclass A and B are defined, and they all inherit the child Task, and some special behaviors are added to handle the corresponding character. Then you instantiate the subclasses, which have a common method for the parent Task and a special behavior for subclass A.

Delegate design pattern: First define an object named task that contains the behavior that all tasks can use. Then for each task A and B, an object is defined to store the corresponding data and behavior. Performing task A requires two sibling objects (task and a) to work together, but allows a object to be delegated to a task when some common behavior is required. In the example above, Bar is passed object.create (Foo); Created, and its [[prototype]] delegate to the Foo object. This is the style of an object association. Delegate behavior means that some objects (bars) delegate this request to another object (Foo) When a property or method reference is not found.

"JS Basics" Javascript "Inheritance"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.