Then the last progress, began to look at the 6th chapter.
The 6th Chapter object-oriented programming
Understanding objects
The simplest way to create a custom object is to create an instance of an object and then add properties and methods to it.
var person = new Object ();p erson.name = ' xxx ';p Erson.say = function () {alert (this.name);} Equivalent to the object literal var person = {name: ' xxx ', say:function () {alert (this.name);}}
There are two types of properties in ECMAScript: Data Property accessor Properties
The Data property contains the location of a data value that can be read and written in this location. To modify the properties default attribute, you must use the object.defineproperty() method defined by ECMAScript 5. This method receives 3 parameters: the object where the property resides, the name of the property, and a Descriptor object (configurable, enumerable, writable, value).
var person = {};object.defineproperty (person, "name", { writable:false, value: "Nicholas"}); alert ( Person.name); Nicholasperson.name = "Michael"; alert (person.name); Nicholas//object.defineproperty (person, "name", { configurable:false, value: "Nicholas"});
The accessor property does not contain a data value and contains a pair of getter setters. Accessor properties cannot be defined directly and must be defined using DefineProperty ().
Properties of the Read attribute
The Getownpropertydescriptor () method in ECMAScript 5 can get the descriptor of the property. This method receives 2 parameters: the object where the property resides, and the name of the property to read the descriptor.
Creating objects
Although the object constructor or object literal can create a single object, there are drawbacks: creating many objects with the same interface creates a lot of duplicate code.
1. Factory mode
Factory mode function Createperson (name, age, Job) { var o = new Object (); O.name = name; O.age = age; O.job = job; O.sayname = function () { alert (this.name); }; return o;} var person1 = Createperson ("Nicholas", "Software Engineer"), var person2 = Createperson ("Greg", "Doctor");p Erson1. Sayname (); "Nicholas" Person2.sayname (); "Greg"
2. constructor Mode
constructor mode function person (name, age, Job) { this.name = name; This.age = age; This.job = job; This.sayname = function () { alert (this.name); }; } var person1 = new Person ("Nicholas", "Software Engineer"), var person2 = new Person ("Greg", "Doctor");p Erson1.sayna Me (); "Nicholas" Person2.sayname (); "Greg"
Constructors should start with a capital letter, and non-constructors should start with a lowercase letter.
To create a new instance, you must use the new operator.
General Experience 4 steps:
1). Create a new object
2). Assigns the scope of the constructor to the new object (this points to the new object)
3). Execute the code in the constructor (add properties, methods to the new object)
4). Returns the new object
The new object created has a constructor (constructor) property that points to the constructor for that new instance.
The instanceof operator is used to detect object types.
Constructoralert (Person1.constructor = = person); Truealert (Person2.constructor = = person); True//instanceofalert (Person1 instanceof Object); Truealert (person1 instanceof person); Truealert (Person2 instanceof Object); Truealert (person2 instanceof person); True
Constructors are also normal functions, and any function that is called by the new operator can be used as a constructor.
The new operator calls Var person as a constructor = new person ("Nicholas", "Software Engineer");p erson.sayname (); "Nicholas"//as normal function call person ("Greg", "Doctor"); Adds to Windowwindow.sayname ();
3. prototype mode
Each newly created function has a prototype (prototype) attribute, which is a pointer to an object that is used to contain properties and methods that can be shared by all instances of a particular type.
Prototype mode function person () {}person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { alert (this.name);}; var person1 = new Person ();p erson1.sayname (); "Nicholas" var person2 = new Person ();p erson2.sayname (); "Nicholas" alert (person1.sayname = = person2.sayname); True
Understanding prototype Objects
Whenever a new function is created, a prototype property is created for the function based on a specific set of rules, which points to the prototype object of the function. By default, all prototype objects automatically get a constructor property that contains a pointer to the function where the prototype property is located.
When a custom constructor is created, its prototype object only obtains the constructor property by default, and the other method inherits from object. when the constructor is called to create a new instance, the inside of the instance contains a pointer (internal property [[prototype]]) that points to the constructor's prototype object. (in some browsers this property is __proto__ )
Instance of person: Person1, Person2, these 2 instances all contain an internal property (in some browsers: __proto__), which points to person.prototype. (In other words, this internal property is not directly related to the constructor)
You can use the isprototypeof() method to determine whether this relationship exists between objects (instance internal properties [[[prototype]] points to constructor prototypes)
Alert (Person.prototype.isPrototypeOf (Person1)); Truealert (Person.prototype.isPrototypeOf (Person2)); True
Use the hasOwnProperty () method to detect whether a property exists in an instance or exists in a prototype.
Detection attribute function person () {} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { alert (this.name);}; var person1 = new Person (), var person2 = new Person (), Alert (Person1.hasownproperty ("name")); Falsealert ("name" in Person1); Trueperson1.name = "Greg"; alert (person1.name); "Greg" –from Instancealert (Person1.hasownproperty ("name")); Truealert ("name" in Person1); Truealert (person2.name); "Nicholas" –from Prototypealert (Person2.hasownproperty ("name")); Falsealert ("name" in Person2); Truedelete Person1.name;alert (person1.name); "Nicholas"-From the Prototypealert (Person1.hasownproperty ("name")); Falsealert ("name" in Person1); True
Judging prototype Properties function Hasprototypeproperty (object, name) { return!object.hasownproperty (name) && (name in object);} var person = new person (); Alert (Hasprototypeproperty (person, "name")); Trueperson.name = "Greg"; alert (Hasprototypeproperty (person, "name"));
When using the for-in loop, the return is all the enumerable properties that can be accessed through the object, including the properties of the instance, the properties of the prototype. To get all the enumerable instance properties of an object, you can use the Object.keys () method in ECMAScript 5. This method receives an object that returns an array of strings that contain enumerable properties.
Property enumeration Function Person () {}person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { alert (this.name);}; var keys = Object.keys (Person.prototype); alert (keys); "Name,age,job,sayname" var person1 = new Person ();p erson1.name = ' xxx ';p erson1.age = 50;var Person1keys = Object.keys (PE Rson1); alert (Person1keys);
This can be extended:
if (! object.create) {object.create = function (o) {function F () {}f.prototype = O;return new F ();}} if (! Object.keys) {Object.keys = function (o) {var k = [], p;for (P in O) {if (Object.prototype.hasOwnProperty.call (o,p)) {K.push ( p);}} return k;}}
Simpler prototype Syntax
function person () {} Person.prototype = { name: "Nicholas", age:29, job: "Software Engineer", Sayname:function () { alert (this.name); }}; var friend = new person (); alert (friend instanceof Object); Truealert (friend instanceof person); Truealert (Friend.constructor = = person); Falsealert (Friend.constructor = = Object); True
The dynamic nature of prototypes
Since the process of finding values in a prototype is a search, any changes made to the prototype object can be immediately reflected from the instance, immediately after the instance is created and the prototype is changed.
The dynamics of the prototype function person () {} Person.prototype = { Constructor:person, name: "Nicholas", age:29, job: "Software Engineer", sayname:function () { alert (this.name); }}; var friend = new person (); Person.prototype.sayHi = function () { alert ("HI");}; Friend.sayhi ();
If you override the entire prototype object, the pointer in the instance is severed (the call constructor adds a pointer to the original prototype [[prototype]]) to the original prototype.
Rewrite the prototype function person () {}var friend = new person (); Person.prototype = { Constructor:person, name: "Nicholas", age:29, job: "Software Engineer", C16/>sayname:function () { alert (this.name); }}; Friend.sayname (); Error
Prototypes of native objects
The importance of prototype patterns is not only in creating custom types, but in all native reference types, but also in prototype mode. All native reference types (Object, Array, String ...) Methods are defined on the prototype of their constructors.
Native object of the prototype alert (typeof Array.prototype.sort); "Function" alert (typeof String.prototype.substring); "function" String.prototype.startsWith = function (text) { return this.indexof (text) = = 0;}; var msg = "Hello world!"; Alert (Msg.startswith ("Hello")); True
Problem with prototype mode
The prototype pattern omits the process of passing initialization parameters to the constructor, causing all instances to get the same property value by default. all the attributes in the prototype are shared by many instances, and the instances generally have their own attributes.
Prototype problem function person () {}person.prototype = { Constructor:person, name: "Nicholas", age:29, job: " Software Engineer ", friends: [" Shelby "," Court "], sayname:function () { alert (this.name); }}; var person1 = new Person (), var person2 = new Person ();p Erson1.friends.push ("Van"); alert (person1.friends) ; "Shelby,court,van" alert (person2.friends); "Shelby,court,van" alert (person1.friends = = = Person2.friends); True
4. combining the constructor pattern with the prototype mode
The most common way to create custom types is by combining the constructor pattern with the prototype pattern. constructors are used to define instance properties, and prototype patterns are used to define methods and shared properties. such a combination, each instance has its own instance of the attribute, but also share the reference to the method, the maximum memory savings.
Combination constructor pattern and prototype mode function person (name, age, Job) { this.name = name; This.age = age; This.job = job; This.friends = ["Shelby", "Court"];} Person.prototype = { Constructor:person, sayname:function () { alert (this.name); }}; var person1 = new Person ("Nicholas", "Software Engineer"), var person2 = new Person ("Greg", "Doctor");p Erson1.frien Ds.push ("Van"); alert (person1.friends); "Shelby,court,van" alert (person2.friends); "Shelby,court" alert (person1.friends = = = Person2.friends); Falsealert (Person1.sayname = = = Person2.sayname); True
This combination of constructors and prototypes is currently the most widely accepted method of creating custom types. This is a default pattern that is used from a defined type.
5. Dynamic Prototyping mode
The dynamic prototype pattern encapsulates all information in a constructor, while preserving the advantages of using constructors and prototypes while initializing prototypes in constructors.
Dynamic prototype mode function person (name, age, Job) {//attribute this.name = Name;this.age = Age;this.job = job;//method if (typeof this.sayname! = "function") { Person.prototype.sayName = function () { alert (this.name);} ;}} var friend = new Person ("Nicholas", "Software Engineer"); Friend.sayname ();
Using the dynamic prototype pattern, you cannot rewrite the prototype using object literals.
6. Parasitic constructor mode
7. Secure Constructor Mode
Inherited
Many OO languages support two types of inheritance: interface inheritance, implementation inheritance. Interface inheritance inherits only the method signature, and the implementation inherits the actual method. Interface inheritance cannot be implemented in ECMAScript because the function is not signed. So ECMAScript only supports the implementation of inheritance, the implementation of inheritance is mainly based on the prototype chain to achieve.
1. prototype chain
The basic idea of a prototype chain is to have a reference type inherit the properties and methods of another reference type using the prototype .
Constructor, prototype, instance relationship: Each constructor has a prototype object, and the prototype object contains a pointer to the constructor ( constructor ), and the instance packages an internal pointer to the prototype object ( [[prototype]] __ Proto__ ).
If you make the prototype object equal to an instance of another type, the prototype object will contain a pointer to another prototype, and another prototype contains a pointer to another constructor. If another prototype is another type of example, this relationship is still established, such a level of progression, constitutes an example and prototype chain. This is the basic concept of the so-called prototype chain.
Prototype chain//supertypefunction supertype () { this.property = true;} SuperType.prototype.getSuperValue = function () { return this.property;};/ /subtypefunction subtype () { this.subproperty = false;} inherited the Supertypesubtype.prototype = new Supertype (); SubType.prototype.getSubValue = function () { return this.subproperty;};/ /instancevar instance = new subtype (); alert (Instance.getsupervalue ()); true//the relationship between the prototype and the instance 1alert (instance instanceof Object); Truealert (instance instanceof supertype); Truealert (instance instanceof subtype); true//the relationship between prototype and instance 2alert (Object.prototype.isPrototypeOf (instance)); Truealert (SuperType.prototype.isPrototypeOf (instance)); Truealert (SubType.prototype.isPrototypeOf (instance)); True
Prototype chain diagram
All reference types inherit Object, and this inheritance is implemented through the prototype chain.
Subtype Inherits Supertype, Supertype inherits the object. When Instance.tostring () is called, it is actually called the ToString () method saved in Object.prototype.
Prudent method of definition
Subtypes sometimes need to rewrite a method in a superclass, or add a method that does not exist in the superclass, and the code that adds the method to the prototype chain must be placed after the statement that replaced the prototype.
Problems with the prototype chain
The problem with the prototype chain is function supertype () { this.colors = ["Red", "Blue", "green"];} Function subtype () {}subtype.prototype = new supertype (); var Instance1 = new subtype (); Instance1.colors.push ("Black"); alert (instance1.colors); "Red,blue,green,black" var instance2 = new subtype (); alert (instance2.colors); "Red,blue,green,black"
The Subertype constructor defines a colors property, subtype inherits an instance of Supertype through the prototype chain, so Subtype.prototype becomes an instance of Supertype and has its own colors property. All subtype instances share this property. Changes to the instance1.colors will also be reflected through instance2.colors.
When you create an instance of a subtype, you cannot pass parameters to a super-type constructor. There is actually no way to pass parameters to a superclass's constructor without affecting all object instances.
2. borrowing Constructors
3. Combining Inheritance
4. prototype Inheritance-' modern ' no-Class inheritance mode
function Object (o) {function F () {}f.prototype = O;return new F ();} if (! object.create) {object.create = function (o) {function F () {}f.prototype = O;return new F ();}}
ECMAScript added the Object.create () method to normalize the stereotype inheritance. This method introduces two parameters: an object that is used as a prototype for a new object, and an object that defines additional properties for the new object. In the case of passing in a parameter, the Object.create () and the Object () methods are similar.
5. Parasitic Inheritance
6. Parasitic combined inheritance
function Object (o) {function F () {} f.prototype = O; return new F (); function Inheritprototype (subtype, supertype) {var prototype = object (Supertype.prototype); Create Object prototype.constructor = subtype; Augment object subtype.prototype = prototype; Assign Object}function supertype (name) {this.name = name; This.colors = ["Red", "Blue", "green"];} SuperType.prototype.sayName = function () {alert (this.name);}; Function subtype (name, age) {Supertype.call (this, name); This.age = age;} Inheritprototype (subtype, supertype); SubType.prototype.sayAge = function () {alert (this.age);}; var Instance1 = new Subtype ("Nicholas"); Instance1.colors.push ("Black"); alert (instance1.colors); "Red,blue,green,black" Instance1.sayname (); "Nicholas"; Instance1.sayage (); 29var Instance2 = new Subtype ("Greg"); alert (instance2.colors); "Red,blue,green" Instance2.sayname (); "Greg"; Instance2.sayage (); 27
In this example, it only invokes the Supertype constructor once, avoiding the creation of unnecessary properties on Subtype.prototype. The prototype chain also remains intact, and the instanceof and isprototypeof () are used normally. It is generally believed that parasitic combined inheritance is the most ideal way to inherit the reference type.
The 6th chapter mainly introduces the object-oriented related knowledge. Create objects: Factory mode, constructor mode, prototype mode, combined use of constructor mode and prototype mode ... Implementation of inheritance: prototype, parasitic, parasitic combined ... This chapter requires a profound The solution, is the JS can go farther of the important foundation.
Reading time "JavaScript Advanced Programming" II: Object-oriented