JavaScript inheritance in detail (iv)

Source: Internet
Author: User

In this chapter, we will analyze an implementation of Douglas Crockford about JavaScript Inheritance-Classical inheritance in JavaScript.
Crockford is the most well-known authority in the JavaScript development community, the father of JSON, JSLint, Jsmin and Adsafe, the author of Javascript:the good Parts.
Now is Yahoo's senior JavaScript architect, participated in the design and development of Yui. Here is an article detailing the life and writings of Crockford.
Of course, Crockford is also the object of my junior cult.

Invocation mode

First let's look at the invocation method using Crockford Inheritance:
Note: The method, inherits, and Uber are all custom objects in the code, and we'll explain them in the code analysis that follows.

 
//defines the person class function person (name) {this.name = name;        }//define the person's prototype method Person.method ("GetName", function () {return this.name;                  });            Defines the Employee class function employee (name, EmployeeID) {this.name = name;        This.employeeid = EmployeeID;        }//Specifies that the Employee class inherits Employee.inherits (person) from the person class;        Defines the prototype method for Employee Employee.method ("Getemployeeid", function () {return this.employeeid;        }); Employee.method ("GetName", function () {///Note, the prototype method of the parent class can be called in a subclass return "Employee Name:" + This.uber ("        GetName ");        });        Instantiate sub-class var Zhang = new Employee ("Zhangsan", "1234");   Console.log (Zhang.getname ()); "Employee Name:zhangsan" 

There are several shortcomings that have to be mentioned:

    • The code that the subclass inherits from the parent class must be done after both the subclass and the parent class are defined, and must precede the subclass prototype method definition.
    • Although a method of the parent class can be called in the subclass method body, the constructor of the subclass cannot invoke the constructor of the parent class.
    • The writing of the code is not elegant, such as the definition of the prototype method and the method of invoking the parent class (not intuitive).

Of course, the implementation of Crockford also supports methods in subclasses that call the parent class with parameters, as in the following example:

  function person (name) {            this.name = name;        }        Person.method ("GetName", function (prefix) {            return prefix + this.name;        });        function Employee (name, EmployeeID) {            this.name = name;            This.employeeid = EmployeeID;        }        Employee.inherits (person);        Employee.method ("GetName", function () {            ///Note that the first parameter of Uber is the name of the function to invoke the parent class, and the following arguments are the parameters of this function            // Personally, it's not as intuitive as calling it this way: This.uber ("Employee Name:")            return This.uber ("GetName", "Employee Name:");        });        var Zhang = new Employee ("Zhangsan", "1234");        Console.log (Zhang.getname ());   "Employee Name:zhangsan"

Code Analysis

The first definition of the method function is simple:

<pre name= "Code" class= "javascript" >function.prototype.method = function (name, func) {            //This points to the current function, That is typeof (this) = = = "function"            this.prototype[name] = func;            return this;        };
Pay special attention to the point of this here. When we see this, we can't just focus on the current function, but we should think about how the current function is called. For example, the method in this example is not called by new, so this in method refers to the current function.

The definition of the inherits function is somewhat complex:

       
 Function.method (' Inherits ', function (parent) {//key is this paragraph: this.prototype = new parent (), where a reference to the prototype is implemented                        var d = {}, p = (This.prototype = new parent ());                The Uber method is only added to the prototype of the subclass, where the closure is to know the prototype of the parent class of the current class (also known as the variable-V) this.method (' Uber ', function uber (name)} when calling the Uber function Consider here if name is a function name that exists in Object.prototype//such as "ToString" in {} = = = True if (!)                Name in D)) {//through D[name] count, do not understand the specific meaning d[name] = 0;                } var F, r, T = D[name], v = parent.prototype;                        if (t) {while (t) {v = v.constructor.prototype;                    T-= 1;                } f = V[name];                    } else {//personally think this piece of code is a bit cumbersome, since the meaning of Uber is the function of the parent class, then f directly points to v[name] can be f = p[name]; if (f = = This[name]) {f = V[Name];                }} D[name] + = 1; Executes the function name in the parent class, but the this in the function points to the current object//While noting that arguments is truncated using Array.prototype.slice.apply (because arguments is not a standard array, no                Slice method) R = f.apply (this, Array.prototype.slice.apply (arguments, [1]));                D[name]-= 1;            return R;            });        return this; });

Note that there is also a small bug in the Inherits function, which is that there is no redefinition of the constructor, so the following error occurs:
       var Zhang = new Employee ("Zhangsan", "1234");         Console.log (Zhang.getname ());   "Employee Name:zhangsan"        console.log (zhang.constructor = = = Employee);    False        console.log (zhang.constructor = = = person);      True
Recommendations for improvement

According to the previous analysis, the individual felt that the method function is not necessary, but easy to confuse the line of sight. And the Inherits method can do some slimming (because Crockford may consider more cases, the original text describes several ways to use the inherits, and we only focus on one of them), and fixed the constructor of the pointing error.

Function.prototype.inherits = function (parent) {            This.prototype = new parent ();            This.prototype.constructor = this;            This.prototype.uber = function (name) {                f = parent.prototype[name];                Return f.apply (this, Array.prototype.slice.call (arguments, 1));};        };      
Call Mode:
function person (name) {            this.name = name;        }        Person.prototype.getName = function (prefix) {            return prefix + this.name;        };        function Employee (name, EmployeeID) {            this.name = name;            This.employeeid = EmployeeID;        }        Employee.inherits (person);        Employee.prototype.getName = function () {            return This.uber ("GetName", "Employee Name:");        };        var Zhang = new Employee ("Zhangsan", "1234");        Console.log (Zhang.getname ());   "Employee Name:zhangsan"        console.log (zhang.constructor = = = Employee);   True
It's interesting.

At the end of the article, Crockford actually released the words:

I had been writing JavaScript for 8 years now, and I had never once found need to the use of an Uber function. The super idea was fairly important in the classical pattern, but it appears to being unnecessary in the Prototypal and Functi Onal patterns. I now see my early attempts to support the classical model in JavaScript as a mistake.
It is visible that Crockford is not in favor of implementing object-oriented programming in JavaScript, and that JavaScript should be programmed according to the pattern of prototypes and functions (the Prototypal and functional patterns).
But personally, it's much easier to have an object-oriented mechanism in a complex scenario.
But who can vouch for it, even projects like the jquery UI don't work for inheritance, and on the other hand, like ExtJS and Qooxdoo, they strongly advocate an object-oriented JavaScript. Even the cappuccino project invented a Objective-j language to practice object-oriented JavaScript.

JavaScript inheritance in detail (iv)

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.