Js OOP programming and jsoop Programming
Let's summarize the object-oriented programming of JavaScript today!
I. Encapsulation
/* 1. original object generation mode */
Var Cat = {name: '', color:''} // two instance objects are generated based on the type of the prototype object. Var cat1 = {}; cat1.name = ""; cat1.color = "yellow"; var cat2 = {}; cat2.name = ""; cat2.color = "black"; // disadvantages: 1. code redundancy 2. there is no association between instances. They belong to objects.
/* 2. Original mode improvement (factory mode )*/
Function Cat (name, color) {return {name: name, color: color }}// use: var cat1 = Cat ("Da Mao", "yellow "); var cat2 = Cat ("two hairs", "black"); // disadvantages: 1. there is no association between instances. They belong to objects.
/* 3. constructor mode */
Function Cat (name, color) {this. name = name; this. color = color;} // use: var cat1 = new Cat ("yellow"); var cat2 = new Cat ("two hairs", "black "); // at this time, cat1 and cat2 will automatically contain a constructor attribute pointing to their constrert (cat1.constructor = Cat); // truealert (cat2.constructor = Cat ); // truealert (cat1 instanceof Cat); // truealert (cat2 instanceof Cat); // true // disadvantage: wasted memory
/* 4. constructor mode and Prototype mode */
Function Cat (name, color) {this. name = name; this. color = color; this. type = "cat"; this. eat = function () {alert ("eat mouse") ;}// usage: var cat1 = new Cat ("Da Mao", "yellow "); var cat2 = new Cat ("two hairs", "black"); // In fact, this is a waste of memory, because the type attribute and the eat method are what all Cat classes should have, // There is no need to allocate space for these two attributes each time they are instantiated. // From this we can see that they are allocated another space: alert (cat1.type = cat2.type); // falsealert (cat1.eat = cat2.eat ); // false // The prototype mode can be used below to solve this problem // javascript stipulates that each constructor has a prototype attribute pointing to another object. // All attributes and methods of this object will be inherited by the constructor instance. // In this way, we can directly define the unchanged attributes and methods in the prototype object. Function Cat (name, color) {this. name = name; this. color = color;} Cat. prototype. type = "Cat"; Cat. prototype. eat = function () {alert ("eat mouse");} // The prototype object is shared by all instances of the same class, which can be used to verify: alert (cat1.type = cat2.type ); // truealert (cat1.eat = cat2.eat); // true // point to the same space
/* 5. prototype mode Verification Method */
1). isPrototypeOf () // used to determine the relationship between a prototype object and an instance. Alert (Cat. prototype. isPrototypeOf (cat1); // truealert (Cat. prototype. isPrototypeOf (cat2); // true2 ). hasOwnProperty () // used to determine whether an attribute is a local attribute alert (cat1.hasOwnProperty ("name"); // truealert (cat1.hasOwnProperty ("type ")); // false // The type property is the property inherited from the prototype object, not the local property, so it is false3 ). the in operator // determines whether an instance contains an attribute, whether it is a local attribute or not. Alert ("name" in cat1); // truealert ("type" in cat1); // true // The in operator can also be used to traverse all attributes of an object. For (var prop in cat1) {alert (cat1 [prop]);}
Ii. Inheritance
/* 1. "constructor" inheritance */
Function Animal () {this. species = 'animal ';} function Cat (name, color) {this. name = name; this. color = color;} // question: how can "Cats" inherit "Animals?
/* 1). Bind the constructor */
Function Cat (name, color) {Animal. apply (this, arguments); // It actually calls the constructor of the parent class this. name = name; this. color = color ;}
/* 2). prototype mode */
Cat.prototype = new Animal();Cat.prototype.constructor = Cat;
/* 3) directly inherit prototype */
// This method is an improvement for the second method. Because Animal objects can directly write the attributes of // unchanged to Animal. prototype, so we can also let Cat () skip Animal (), // directly inherit Animal. prototype // rewrite Animal object: function Animal () {} Animal. prototype. species = 'animal '; // start inheritance: Cat. prototype = Animal. prototype; Cat. prototype. constructor = Cat; // compared with the previous method, this method has the advantage of high efficiency (you do not need to create an Animal instance) and saves memory. // disadvantage: Cat. prototype and Animal. prototype now points to the same object, so any pair of // Cat. modifications to prototype are reflected in Animal. in prototype, this is not what we want
/* 4). Use an empty object as an intermediary */
// Because of the preceding shortcomings, the fourth inheritance method is available. An empty object is used as an intermediary to implement inheritance. Var F = function () {} F. prototype = Animal. prototype; Cat. prototype = new F (); Cat. prototype. constructor = Cat; // F is an empty object, so it hardly occupies the memory. // Encapsulate function extend (Child, Parent) {var F = function () {}; F. prototype = Parent. prototype; Child. prototype = new F (); Child. prototype. constructor = Child; Child. uber = Parent. prototype; // mainly used for extension}
/* 5). Copy inheritance */
// For the parent class, put all its unchanged attributes into its prototype object. Function Animal () {} Animal. prototype. species = 'animal '; function extend2 (Child, Parent) {var p = Parent. prototype; var c = Child. prototype; for (var I in p) {c [I] = p [I];} c. uber = p ;}
/* 2. "Non-constructor" inheritance */
Var Chinese = {nation: 'China'}; var Doctor = {career: 'docker'} // how to make "Doctor" inherit "Chinese ", to get a Chinese doctor? // Note: The two objects here are common objects instead of constructor and cannot be inherited using the constructor method.
/* 1). object () method */
function object(o){function F() {}F.prototype = o;return new F();}
/* 2). Shallow COPY method */
function extendCopy(p){var c = {};for(var i in p){c[i] = p[i];}c.uber = p;return c;}
/* 3). Deep COPY method */
function deepCopy(p,c){var c = c||{};for(var i in p){if(typeof p[i] === 'object'){c[i] = (p[i].constructor === Array) ? [] : {};deepCopy(p[i],c[i]);} else {c[i] = p[i];}}}return c;}