1. Definition of objects
In ECMAScript, an object is an unordered set of properties, where the "property" can be a base value, an object, or a function
2. Data properties and accessor properties
Data properties are properties that have values, can be set property read-only, non-deleted, non-enumerable, and so on
Accessor properties are used to set the getter and setter, with a "_" (underscore) in front of the property name to indicate that the property can only be accessed through accessors (private property), but not to add an underscore to the property to become private, which is only a customary convention of naming way. Accessor properties are useless for the following reasons:
var book={ _year:2004, edition:1}Object.defineProperty(book,"year",{ get:function(){ return this._year; }, set:function(newValue){ if(newValue>2004){ this._year=newValue; this.edition+=newValue-2004; } }});book.year=2005;alert(book.edition);/*for(var attr in book){ showLine(attr + ‘ = ‘ + book[attr]);}*/
The above example code is used in the elevation, the principle is that _year is a data property in the book object's properties, and year is an accessor property, and it sounds good to use gettter and setter to insert read-write control.
The problem is that both _year and edition are enumerable, that is, you can see with the for...in loop, and the accessor attribute year is not enumerable. The accessors that should be exposed are not public, but the private properties that should be hidden are exposed.
In addition, this way of defining accessors is not fully browser compatible, [ie9+] is fully supported, and of course, there are ways to use the old browser (__definegetter__ () and __definesetter__ ()), or rather cumbersome.
In summary, accessor properties are useless.
3. Constructors
function Fun () {} var = new fun (), where fun is a constructor, unlike a normal function without any way of declaring it, it's just a different invocation (called with the new operator).
Constructors can be used to define custom types, such as:
function MyClass(){ this.attr = value;//成员变量 this.fun = function(){...}//成员函数}
There are some similarities to the class declarations in Java, but there are some differences, such as that This.fun is just a function pointer, so it's entirely possible to point to other accessible functions such as global functions, but doing so can break the encapsulation of custom objects
4. Function and prototype prototype
-
Declares a function and also creates a prototype object that holds a reference to the prototype object (Fun.prototype)
-
You can add properties to the prototype object, or you can add properties to the instance object. The difference is that the properties of the prototype object are shared by all instances of the type, and the property of the instance object is not shared by the
-
When it accesses the property of the instance object, it is found in the scope of the instance object, it cannot be located in the scope of the prototype object, Therefore, the properties of the instance can mask the properties of the prototype object with the same name
-
The constructor property of the prototype object is a function pointer to the function declaration
-
Through a prototype you can give the native reference type (Object,array , string, and so on) add a custom method, such as adding a StartsWith method to a string that chrome does not support but FF supports:
var str = ' This is script ';//alert ( Str.startswith (' this ')),//chrome error String.prototype.startsWith = function (strtarget) {return This.indexof ( strtarget) = = = 0;} Alert (Str.startswith (' this '));//No error.
Note: It is not recommended to add a prototype attribute to a native object because it may accidentally override the native method and affect other native code (native code that invokes the method)
-
Can be inherited through prototypes, with the idea that the prototype property of the subclass points to an instance of the parent class to increase the properties accessible by the subclass, so the properties accessible by the
subclass after connecting with the prototype chain = Subclass Instance Properties + Subclass Prototype attribute = Subclass Instance Attribute + Parent class Instance attribute + Parent class prototype attribute = Subclass Instance Attribute + Parent class Instance attribute + Parent Parent class Instance attribute + Parent Class prototype property = ...
Final parent ... The parent class prototype property is replaced with the property of the prototype object pointed to by the Object.prototype
Concrete implementation is Subtype.prototype = new supertype (), which can be called inheritance of the simple prototype chain method
5. The best way to create a custom type (constructor mode + prototype mode)
The instance properties are declared with a constructor, and the shared properties are declared with a prototype, which is implemented as follows:
function MyObject(){ //实例属性 this.attr = value; this.arr = [value1, value2...]; } MyObject.prototype = { constructor: MyObject,//保证子类持有正确的构造器引用,否则子类实例的constructor将指向Object的构造器,因为我们把原型改成匿名对象了 //共享属性 fun: function(){...} }
6. The best way to implement inheritance (parasitic combined inheritance)
function object(obj){//返回原型为obj的没有实例属性的对象 function Fun(){} Fun.prototype = obj; return new Fun();}function inheritPrototype(subType, superType){ var prototype = object(superType.prototype);//建立原型链,继承父类原型属性,用自定义函数object处理是为了避免作为子类原型的父类实例具有实例属性,简单地说,就是为了切掉除多余的实例属性,可以对比组合继承理解 prototype.constructor = subType;//保证构造器正确,原型链会改变子类持有的构造器引用,建立原型链后应该再改回来 subType.prototype = prototype;}function SubType(arg1, arg2...){ SuperType.call(this, arg1, arg2...);//继承父类实例属性 this.attr = value;//子类实例属性}inheritPrototype(SubType, SuperType);
Specific explanations are shown in code annotations, which avoids subtype.prototype = new supertype (); The disadvantages of simple prototype chains:
The subclass instance shares the problem of the reference property of the parent class instance (since the prototype reference property is shared by all instances, the instance property of the prototype chain stepfather class is naturally the prototype attribute of the subclass).
Unable to pass argument to parent class constructor when creating child class instance
7. The most common way to implement inheritance (combination inheritance)
Replace the above Inheritprototype (subtype, supertype) with the following statements:
SubType.prototype = new SuperType();SubType.prototype.constructor = SubType;
The disadvantage of this approach is that there is a redundant instance of the parent class attribute due to the invocation of a 2-time constructor of the parent class, for the following reasons:
First Supertype.call (this); The statement copies a copy of the parent class instance property from the parent class to the subclass as the instance property of the subclass, the second subtype.prototype = new Supertype (), and the parent class instance as the subclass prototype. At this point, the parent instance has another instance attribute, but this one will be masked out by the instance properties of the first copy, so superfluous.
JS best way to create objects