Source: Http://www.jianshu.com/p/a6c005228a75
Opening
从‘严格‘意义上说,javascript并不是一门真正的面向对象语言。这种说法原因一般都是觉得javascript作为一门弱类型语言与类似java或c#之类的强型语言的继承方式有很大的区别,因而默认它就是非主流的面向对象方式,甚至竟有很多书将其描述为‘非完全面向对象‘语言。其实个人觉得,什么方式并不重要,重要的是否具有面向对象的思想,说javascript不是面向对象语言的,往往都可能没有深入研究过javascript的继承方式,故特撰此文以供交流。
Why you need to implement inheritance with JavaScript
The performance of the early PC machine did not compliment, all the pressure on the server side, the client browser is purely equipment. In addition, the popular table layout and the way the telephone line online led to browse a page very card; now the internet era of rapid development, personal computer hardware has been greatly improved, the performance of the client browser is also very sour, the Web development model is also quietly changing: the service is not as "hard" as before, Instead of allowing the browser to take on more tasks as much as possible, so that the pressure spread to each client, the enterprise not only saves costs, but also makes web front-end development more interesting-more and more front-end framework, and even the front-end MVC model. In this context, the role of JavaScript is definitely not just to do some simple verification, send some requests or manipulate some DOM, more need to assume a role similar to the routing layer and the business layer. In contrast, JavaScript requires a lot of logical tasks, including the extraction of foreground data (i.e. model), and only the use of object-oriented thinking in order to be very good at extracting data processing, so inheritance is very important here.
Start with a simple need
Now from the foreground of a model named person, which has the basic properties of name and age, by default everyone will speak, so the function of speech say on the prototype object, for each instance to enjoy. Now for man, it needs to inherit the basic attributes of the person, and on top of that, add its own unique properties.
function person (name, age) { this.name = name; This.age = age;} Person.prototype.say = function () { console.log (' Hello, my name is ' + this.name);}; Function Man () { //my own properties}
Here are some of the main ways to inherit. 1. Prototype chain inheritance
function person (name, age) { this.name = name; This.age = age;} Person.prototype.say = function () { console.log (' Hello, my name is ' + this.name);}; Function Man () {}man.prototype = new person (' pursue '), var man1 = new Man (); Man1.say (); Hello, my name is Pursuevar man2 = new Man (); Console.log (Man1.say = = = Man2.say);//trueconsole.log (Man1.name = = = Man2.nam e);//true
This kind of inheritance is very straightforward, in order to get Person
all the property methods (on the instance and prototype), the parent class's instance new Person(‘pursue‘)
is directly assigned to the child class prototype, in fact, the subclass of the instance man1,man2
itself is a completely empty object, all the properties and methods have to go to the prototype chain to find, So the attribute methods found are the same.
So the direct use of the prototype chain inheritance is unrealistic.
2. Using constructor inheritance
function person (name, age) { this.name = name; This.age = age;} Person.prototype.say = function () { console.log (' Hello, my name is ' + this.name);}; function man [name, age] { person.apply (this, arguments);} Man.prototype = new Person (' pursue '), var man1 = new Man (' Joe '), var man2 = new Man (' David '), console.log (man1.name = = = Man 2.name);//falseman1.say (); Say is not a function
The subclass in the constructor using apply to call the parent class constructor, so as to achieve the effect of inheriting the parent class properties, more than the direct use of the prototype chain is much better, at least each instance has its own resources, but this method can only inherit the parent class instance properties, and therefore cannot find the Say method, In order to inherit all the properties and methods of the parent class, the prototype chain is modified to introduce a combination of inheritance.
3. Combining inheritance
function person (name, age) { this.name = name; This.age = age;} Person.prototype.say = function () { console.log (' Hello, my name is ' + this.name);}; function man [name, age] { person.apply (this, arguments);} Man.prototype = new Person (), var man1 = new Man (' Joe '), var man2 = new Man (' David '); Console.log (Man1.name = = = Man2.name);// Falseconsole.log (Man1.say = = = Man2.say);//trueman1.say (); Hello, my name is Joe
It is important to note that the man1和man2
instance properties actually override the prototype properties, but do not overwrite the methods on the prototype say
(because they are not), so this man1.say === man2.say
still returns true, so you need to be very careful not to overwrite the stereotype properties because it is common to all instances.
4. Parasitic combination inheritance
Honestly, I don't know if this is the name, but it's really the most popular and classic way of inheriting JavaScript.
In fact, you just need to understand the structure of the prototype object:
function person (name, age) { this.name = name; This.age = age; } Person.prototype.say = function () { console.log (' Hello, my name is ' + this.name);}; function man [name, age] { person.apply (this, arguments);} Man.prototype = Object.create (person.prototype);//a.man.prototype.constructor = Man;//b.var man1 = new Man (' pursue '); var man2 = new Man (' Joe '); Console.log (Man1.say = = Man2.say); Console.log (man1.name = man2.name);
In fact, the parasitic combination of inheritance and the above combination of inheritance is only the way to construct the subclass prototype object ( a.和b.
), here is the Object.creat(obj)
method, the method will be a shallow copy of the incoming obj object, similar to:
function create(obj){ function T(){}; T.prototype = obj; return new T();}
As a result, the prototype a.
object of the subclass is well connected to the prototype object of the parent class, rather than being copied directly to the prototype of the subclass as the general combination inherits (for example Man.prototype = new Person();
), so it is only violent to overwrite the property. However, the inheriting method of the parasitic combination inherits the instance attribute and the prototype attribute, which is more reasonable in realization.
注意:
Code B. Does not change the results of instanceof, but it is more rigorous for scenarios where construcor are needed.
-----Finished-----
Go Some of the more popular ways to inherit from JavaScript