The inheritance and polymorphism _js object-oriented of JavaScript object-oriented new practice

Source: Internet
Author: User
Tags anonymous eval function definition function prototype inheritance
1 is also a few basic concepts
Why do you say it again?
In discussing inheritance, we have listed some basic concepts that are closely related to encapsulation, and the basic concepts we are going to discuss today are mainly about inheritance and polymorphism, but they are also associated with encapsulation.
1.1 Defining and assigning values
Variable definition refers to the use of
var A;
This form to declare variables.
function definition refers to the use of
Function A (...) {...}
This form to declare a function.
var a = 1;
is two processes. The first procedure is to define the variable A, and the second procedure is to assign a value to the variable A.
Same
var a = function (...) {};
is also two processes, the first process is to define variable A and an anonymous function, the second process is to assign the anonymous function to the variable A.
Variable definitions and function definitions are completed before the execution of the entire script, and variable assignments are performed in the execution phase.
The function of a variable definition is simply to indicate its scope to the variable being declared, and the variable definition does not give the variable an initial value, any variables that are not defined directly, or a variable that defines but does not assign a value, and their values are undefined.
The function definition also defines the function body structure, in addition to declaring the function outside the function. The process is recursive, that is to say, the definition of a function body includes the definition of variables and functions in the body of a function.
We can understand this more clearly with the following example:
Copy Code code as follows:

alert (a);
alert (b);
alert (c);
var a = "a";
function A () {}
Function B () {}
var B = "B";
var c = "C";
var c = function () {}
alert (a);
alert (b);
alert (c);

Guess what the result of this program is? Then take a look at whether it's the same as you think, and if it's the same as you think, it means you already understand what it says.
The results of this program are interesting, although the first alert (a) is at the front, but you will find that its output value is function A () {}, which means that the function definition is actually complete before the execution of the program.
Again, B, the function B is defined before variable B, but the first alert (b) is still function B () {}, which shows that the variable definition does not do anything with the variable, just declare its scope, it does not overwrite the function definition.
Finally, C, the first alert (c) output is undefined, which indicates that var c = function () {} is not defined on function C, just defines a variable c and an anonymous function.
Looking at the second alert (a), you'll see that the output is actually a, which means that the assignment statement is actually done during execution, so it overrides the definition of function A.
The second alert (b) is, of course, the same, and the output is B, which means that assigning a variable with the same name as a function always overrides the function definition, regardless of whether the assignment statement was written before the function definition or after the function definition.
The second alert (c) outputs the function () {}, which indicates that the assignment statement is executed sequentially and that the subsequent assignment overrides the previous assignment, regardless of whether the assigned value is a function or another object.
Understanding the above, I think you should know when to use function x (..) {...}, when should I use var x = function (...) {...} , huh?
Finally, note that if you have variable definitions and function definitions in eval, they are done in the execution phase. So, don't use eval! unless you have to. Also, if you want to use eval, don't use local variables and local methods inside!
1.2 This and execution context
We have contacted this before we discussed encapsulation in the previous discussion. In the discussion of encapsulation, we see this as the instantiation object itself that represents the class in which this is located. Is that really the case?
Let's take a look at the following example:
Copy Code code as follows:

var x = "I ' m a global variable!";
Function method () {
alert (x);
alert (this.x);
}
function Class1 () {
Private field
var x = "I ' m a private variable!";
Private method
function Method1 () {
alert (x);
alert (this.x);
}
var method2 = method;
public field
this.x = "I ' m a object variable!";
Public method
This.method1 = function () {
alert (x);
alert (this.x);
}
This.method2 = method;
Constructor
{
This.method1 (); I ' m a private variable!
I ' m A object variable!
THIS.METHOD2 (); I ' m a global variable!
I ' m A object variable!
Method1 (); I ' m a private variable!
I ' m a global variable!
Method2 (); I ' m a global variable!
I ' m a global variable!
Method1.call (this); I ' m a private variable!
I ' m A object variable!
Method2.call (this); I ' m a global variable!
I ' m A object variable!
}
}
var o = new Class1 ();
Method (); I ' m a global variable!
I ' m a global variable!
O.method1 (); I ' m a private variable!
I ' m A object variable!
O.METHOD2 (); I ' m a global variable!
I ' m A object variable!

Why is this the result?
So let's take a look at what is the execution context. So what is the execution context?
If you are currently executing a method, the execution context is the object that the method is attached to, and if you are currently executing a procedure that creates an object (that is, created by new), the object created is the execution context.
If a method is not explicitly attached to an object at execution time, its execution context is a global object (the top-level object), but it is not necessarily subordinate to the global object. Global objects are determined by the current environment. In a browser environment, the global object is the Window object.
Global variables and global functions defined outside all functions are subordinate to global objects, and local variables and local functions defined within the function are not attached to any object.
Does the execution context have anything to do with the scope of the variable?
The execution context is different from the scope of the variable.
When a function is assigned to another variable, the scope of the variable used inside the function does not change, but its execution context becomes the object that the variable is attached to (if the variable has a subordinate object).
The call and apply method on the function prototype can change the execution context, but it does not change the scope of the variable.
To understand these words, you only need to remember one point:
The scope of a variable is determined at definition, it will never change, and the execution context is determined at execution time, and it can be changed at any time.
So it's not hard to understand the example above. THIS.METHOD1 () This statement (note that this is not yet entered into the function body) is being created, the current execution context is the object being created, so this is also the object being created, in This.method1 () When this method executes (this is the entry into the function body), the object being attached to the executing method is also the object being created, so this is the same object as the this.x in it, so the output you see is the I ' m a object variable! Out.
While executing the METHOD1 () (refers to the function body), method1 () is not explicitly attached to an object, although it is defined in Class1, but he is not attached to the Class1, nor is it attached to the Class1 instantiated object, But its scope is limited to the Class1. Therefore, its subordinate object is actually a global object, so when it is executed to alert (this.x), this.x becomes the X of the value "I ' m a global variable!" defined in the global environment.
METHOD2 () is defined in Class1, but method () is defined outside of Class1, and method is assigned to METHOD2 without changing the scope of method, so when METHOD2 executes, it is still in the Metho D is executed within the scope defined, so what you see is two I ' m a global variable! The output. Similarly, when THIS.METHOD2 () is invoked, alert (x) outputs I ' m a global variable! And that's the reason.
Because call changes the execution context, the this.x becomes the I ' m a object variable! through Method1.call (this) and Method2.call (this). But it does not change the scope, so X is still the same as the result of not using the call method.
And when we execute O.METHOD1 (), when alert (x) does not use this to indicate the execution context of x, then x represents the most recently defined variable in the scope of the currently executing function, so the output is I ' m a private variable!. The last output I ' m a object variable! I don't think I'm going to tell you why, you know?
2 Inheritance and polymorphism
2.1 Starting from encapsulation
As we said earlier, the purpose of encapsulation is to implement data hiding.
But on a deeper level, there are several benefits to encapsulation in javascript:
1, stealth implementation details, when the implementation of the private part is completely rewritten, do not need to change the behavior of the caller. This is also the main purpose of other object-oriented languages to implement encapsulation.
2, JavaScript, local variables and local functions to access faster, so the private field with local variables to encapsulate, the private approach to the local method of encapsulation can improve the execution efficiency of the script.
3, for JavaScript compression obfuscation (as far as I know, the best JavaScript analysis, compression, obfuscation is JSA), local variables and local function names can be replaced, and global variables and global function names can not be replaced (in fact, for This is also true of the JavaScript script parser when it works. Therefore, whether for open source or non-open-source JavaScript programs, when the proprietary and private methods use encapsulation technology, the code can be written with long enough ideographic names to increase the readability of the Code, and when published, they can be replaced with some very short names (typically single character names). This will allow for full compression and confusion. and reduce the bandwidth consumption, but also to achieve the real details of the hidden.
So, encapsulation is very useful for JavaScript!
So what is the purpose of implementing inheritance in JavaScript?
2.2 Why to inherit
In other object-oriented programming languages, inheritance, in addition to reducing the number of duplicated code, is most useful to achieve polymorphism. This is especially true in strongly typed languages:
1. In strongly typed languages, a variable cannot be given two values of different types, unless the two types are compatible with the type of the variable, and the compatible relationship is implemented by inheritance.
2. In a strongly typed language, an existing type cannot be expanded and rewritten directly, and the only way to extend a type is to inherit it and expand and rewrite it in its subclasses.
Therefore, for strongly typed object-oriented languages, the implementation of polymorphism relies on the implementation of inheritance.
For JavaScript languages, inheritance is less important for implementing polymorphism:
1. In the JavaScript language, a variable can be given any type of value, and you can invoke the same method on objects of any type in the same way.
2. In JavaScript language, the existing types can be directly expanded and rewritten by means of prototypes.
So, in JavaScript, the main function of inheritance is to reduce the coding of repetitive code.
The next two approaches to implementing inheritance may be familiar, one is the prototype inheritance method, the other is invoking the inheritance method, neither of which has a side effect. Our main discussion is the nature of the two methods and the places to be noted.
2.3 Prototype Inheritance Method
In JavaScript, each class (function) has a prototype that is passed to the class's instantiated object when the class is instantiated. There is no prototype on the instantiated object, but it can be a prototype of another class (function), and when instantiated by a class that is a prototype of that object, the member on that object is passed on to the instantiated object of the class that it is a prototype. This is the essence of archetypal inheritance.
Prototype inheritance is also the inheritance method used by many native objects in JavaScript.
Copy Code code as follows:

function ParentClass () {
Private field
var x = "I ' m a parentclass field!";
Private method
function Method1 () {
alert (x);
Alert ("I ' m a ParentClass method!");
}
public field
this.x = "I ' m a ParentClass object field!";
Public method
This.method1 = function () {
alert (x);
alert (this.x);
Method1 ();
}
}
ParentClass.prototype.method = function () {
Alert ("I ' m a ParentClass prototype method!");
}
Parentclass.staticmethod = function () {
Alert ("I ' m a parentclass static method!");
}
function Subclass () {
Private field
var x = "I ' m a subclass field!";
Private method
function Method2 () {
alert (x);
Alert ("I ' m a subclass method!");
}
public field
this.x = "I ' m a subclass object field!";
Public method
THIS.METHOD2 = function () {
alert (x);
alert (this.x);
Method2 ();
}
This.method3 = function () {
Method1 ();
}
}
Inherit
Subclass.prototype = new ParentClass ();
SubClass.prototype.constructor = subclass;
Test
var o = new Subclass ();
Alert (o instanceof parentclass); True
Alert (o instanceof Subclass); True
alert (o.constructor); function Subclass () {...}
O.method1 (); I ' m a parentclass field!
I ' m a subclass object field!
I ' m a parentclass field!
I ' m a parentclass method!
O.METHOD2 (); I ' m a subclass field!
I ' m a subclass object field!
I ' m a subclass field!
I ' m a subclass method!
O.method (); I ' m a parentclass prototype method!
O.method3 (); Error!!!
Subclass.staticmethod (); Error!!!

The above example is a good reflection of how to use the prototype inheritance method to implement inheritance.
Related Article

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.