Foreword: This article is roughly excerpted from: 54645430 This csdn blogger writes very good, the logic is very strong. The following " how to safely extend a built-in object" is what I added. By the way, the blogger's detailed JS in the Extend function and call and apply the analysis excerpt.
Prototype inheritance: The use of members in the prototype can be shared with its related objects, can implement inheritance, this implementation of inheritance is called prototype inheritance.
Prototype inheritance is an inheritance of JS, what is the meaning of prototype inheritance, in fact, it is said that the constructor and sub-constructors, or between the class and sub-class (of course, there is no class in JS), the only way to pass the inheritance is through the prototype, not other languages directly through the extends ( Of course ES6 's grammatical sugar appeared extends). So you need handwriting prototype. (The method of encapsulating handwritten prototype see my other article on the Extend function in JS) Let's look at a simple example first.
See the example in detail:
1 function Parent () {2 This. Job ='Teacher';3 }4Parent.prototype.showJob =function () {5Alert This. Job);6 }7 varChild =NewParent ();8Child.showjob ();//' Teacher '
Obviously, the child in this example gets the attribute job and a method showjob, why is it obtained? Now look at what new Parent () did.
1 var obj = {}; // obj Gets the This reference of the parent 2 ' Teacher ' ; 3 obj.__proto__ = Parent.prototype; 4 var child = obj;
So why does the child get the property job because he executes the constructor and gets the property job on the child object. And why the child gets the method showjob because there is a hidden prototype __proto__ on the object, which points to parent.prototype. When we call the method on the object child, it first checks to see if the object has this method, and there is no way to search for its own hidden prototype.
So, what is the prototype inheritance, and its essence is to change the __proto__ of other objects, or let it enrich, to get the parent constructor or ancestor constructor method, see the code.
1 function Parent () { 2 } 3 Parent.prototype.showJob = function () {} 4 function child () { 5 } 6 child.prototype = new Span style= "COLOR: #000000" > Parent (); 7 Child.prototype.constructor = child; 8 var grandchild = new Child ();
At this time grandchild obtained the Showjob method, because it has a showjob method in its __proto__, and why it has this method in its implicit prototype, because the new child () grandchild.__proto__ Point to the child's prototype, as to why there is Showjob method in the prototype of child, because child.prototype.__proto__ equals Parent.prototype.
As for why there is such a sentence
1 Child.prototype.constructor = child;
This is because there is a constructor attribute in Child.prototype that points to child itself, when executing child.prototype = new Parent (), Child.prototype.constructor point to the parent, or the next time new child, the point of constructor will not be correct, of course, this in the actual development of the immediate leakage will not be a big problem, Because we seldom read and write to constructor.
The above code has another question, why do we have to write showjob this method on the Parent.prototype, if written as follows
1 function Parent () {2 this. Showjob = function () {}3 }4 function child () { 5 }6 new Parent ();
Of course, this can be written, Child.prototype object on the Showjob method, rather than child.prototype.__proto__, which for our prototype chain inheritance has no effect. However, the more methods you write, the more methods you have on the Child.prototype object, and if you have new multiple times, you will consume more memory than you would write on the prototype.
So in the actual development, how to implement object-oriented prototype inheritance it. Normal when we get the demand, if the demand logic is complex, and there are similar logic in multiple pages, we will think of using object-oriented, because object-oriented solution is the logical encapsulation and reuse.
Assuming that the same logic exists in page A, page B, and page C, we can encapsulate the parent constructor object
1 function Parent () {}2Parent.prototype = {3 method1:function () {},4 method2:function () {},5 ...6 }7function A () {//Page A8 This. A =A;9 }TenA.prototype =NewParent (); OneA.prototype.othermethod =function () {}; A - varA =NewA ();//Working with Objects -A.init ...
First of all, page A, page B, page C in the same logic, the same logic can be the same AJAX request to return data, or data formatting and so on the same operation. These methods are defined in Parent.prototype, as in the A,b,c page's own method, as defined in A.prototype. This solves our problem in a very good way, with clear logic and strong code reuse. If you add a callback callback to the parent method parameter, and you want to invoke the child function method or property in callback, you can refer to my other blog post. Call and apply Get started analysis
hasOwnProperty
The hasOwnProperty method can detect whether a property exists in an instance or exists in a prototype.
1 function Parent () {2 This. Name ='Sysyzhyupeng';3 }4Parent.prototype.job ='Teacher';5Parent.prototype.showJob =function () {6 }7 varParent =NewParent ();8Parent.hasownproperty ('name');//true9Parent.hasownproperty ('Job');//falseTen //method can also OneParent.hasownproperty ('Showjob');//falseInch
The in operator differs from hasOwnProperty, as long as it exists on the prototype or returns true on the object
1 function Parent () {2 This. Name ='Sysyzhyupeng';3 }4Parent.prototype.job ='Teacher';5Parent.prototype.showJob =function () {6 }7 varParent =NewParent ();8 'name' inchParent//true9 'Job' inchParent//trueTen for(_keyinchparent) { OneConsole.log (_key);//' name ', ' job ', ' Showjob ' A}
When using the for-in loop, all the enumerable properties that can be accessed through the object are returned. All developer-defined properties are enumerable, except for IE8 and earlier versions.
Object.keys
ES5 's Object.keys method can return all enumerable properties on an object (note that only the object, not inherited from the prototype)
How to safely extend a built-in object
New members and methods for built-in objects, called extended built-in objects. This kind of behavior is undesirable. Because the native built-in object itself has some methods and properties, in a project, if you replace these methods, others will not be used, easy to cause code crashes, not appropriate maintenance.
How to safely extend a built-in object? Just like the built-in object array, we want to use some of its own methods, and we want to add a SayHello () method to it. How is this going to work?
Let's start by creating an object that inherits the built-in object array so that the methods inside the array array can be used in the objects we create, and then add our custom methods to the objects we create. This will not affect the built-in objects, no matter how we modify the methods inside the objects we create .
1function MyArray () {//define your own function object MyArray2 //properties that I define myself3 This. Name ="I am an array";4 This. SayHello =function () {5Console.log ("my method of SayHello");6 }7 }8 9 vararr =NewArray (); Built-in Objects array objects created by ArrTen OneMyarray.prototype = arr;//Replace prototype object, i.e. prototype objectto inherit an array, I have all the properties and methods of the native array object in my array AMyArray.prototype.hello =function () { -Console.log ("Hello Everyone, I'm a myarray in the prototype of a custom object."); - } the - varMyarr =NewMyArray ();//Myarr This object is inherited from Arr - -Myarr.push ( -);//native built-in object array Auto Push method +Myarr.push (2,3,4,5) - Console.log (Myarr); + Myarr.sayhello (); AMyarr.hello ();
JS-Prototype inheritance and application