Ecma-262 defines an object as an unordered collection of attributes.
1. How objects are created
- New Object() via constructor
Var person = new Object() person.name = 'person '; person.age = 30; person.sayName = function () { console.log(this.name); }Copy the code
- By way of literal {}
Var person = {name: 'name ', age: 30, sayName: function () {console.log(this.name); }}Copy the code
Second, the way of inheritance
1. Prototype chain
Function SuperFun() {this.name = 'qb'; this.colors = ['red', 'green']; } SuperFun.prototype.getName = function () { return this.name; } // Function SubFun() {this.age = 30; }; // Subfun. prototype = new SuperFun(); SubFun.prototype.getAge = function () { return this.age; } let obj = new SubFun(); console.log(obj.getName()); // 'qb' console.log(obj.getAge()); / / '30'Copy the code
Subfun.prototype = new SuperFun(); subfun.prototype = new SuperFun(); The instantiated object has a name attribute and a getName method, so obj, instantiated by SubFun, can also get the name attribute and call the getName method.
Existing problems
- 1. The constructor for SubFun points to SuperFun, not the expected SubFun
console.log(obj.constructor === SubFun) // false
console.log(obj.constructor === SuperFun) // true
Copy the code
- 2. Objects instantiated by SubFun share reference data from the stereotype, not each other
obj.colors.push('pink');
console.log(obj.colors); // ["red", "green", "pink"]
let obj2 = new SubFun();
console.log(obj2.colors); //["red", "green", "pink"]
Copy the code
2. Embezzle constructors
Function SuperFun() {this.name = 'qb'; this.colors = ['red', 'green']; } SuperFun.prototype.getName = function () { return this.name; Function SubFun() {superfun.call (this); }; let obj = new SubFun(); obj.colors.push('pink'); console.log(obj.colors); // ["red", "green", "pink"] let obj2 = new SubFun(); console.log(obj2.colors); //["red", "green"]Copy the code
This is done by assigning properties from SuperFun to SubFun using the call method in SubFun, and executing superfun.call (this) every time SubFun is instantiated so that new reference data is generated each time.
Existing problems
- Methods on the SuperFun prototype cannot be accessed in the SubFun instantiation object
console.log(obj.getName());
Copy the code
The result of the above code is:
3. Combinatorial inheritance
Function SuperFun(name) {this.name = name; this.colors = ['red', 'green']; } SuperFun.prototype.getName = function () { return this.name; } function SubFun(name, age) {// (1) superfun. call(this, name); this.age = age; }; Subfun. prototype = new SuperFun(); SubFun.prototype.getAge = function () { return this.age; } let obj = new SubFun('qb', '30'); console.log(obj.getName()); // qb console.log(obj.getAge(30)); // 30 obj.colors.push('pink'); console.log(obj.colors); // ["red", "green", "pink"] let obj2 = new SubFun('qb2', '31'); console.log(obj2.colors); //["red", "green"]Copy the code
The combination of the stereotype inheritance method and the stolen constructor inheritance method solves the problem that objects instantiated by SubFun will share the reference data on the stereotype, so that methods defined on the parent stereotype can be reused and each instance can have its own attributes.
Existing problems
- The problem remains that the constructor for SubFun points to SuperFun instead of the expected SubFun
console.log(obj.constructor === SubFun) // false
console.log(obj.constructor === SuperFun) // true
Copy the code
4. Inheritance of the original type
- To achieve 1
Function object(o) {function F() {}; F.prototype = o; return new F(); } var obj = { name: 'qb', colors: ['red', 'gree'] } var obj1 = object(obj); obj1.colors.push('pink'); console.log(obj1.colors); // ["red", "gree", "pink"] var obj2 = object(obj); console.log(obj2.colors); // ["red", "gree", "pink"]Copy the code
The object function passes in the target object as the prototype of the blank constructor, and then returns the new object by instantiating the blank constructor. The new object is the new object that is the prototype of the target object. However, because the object of the prototype is always O, the reference data on the prototype is shared between newly created instances.
- The 2
var obj = {
name: 'qb',
colors: ['red', 'gree']
}
var obj1 = Object.create(obj);
obj1.colors.push('pink');
console.log(obj1.colors); // ["red", "gree", "pink"]
var obj2 = Object.create(obj);
console.log(obj2.colors); // ["red", "gree", "pink"]
Copy the code
The above implementation of object. create is the same as the implementation of Object.
Existing problems
- Instantiated objects share reference data on the stereotype, not each other
Parasitic inheritance
function createObj(o) { let clone = Object.create(o); SayHi = function () {console.log('hi') is enhanced by defining a method; } return clone; } var obj = { name: 'qb', colors: ['red', 'gree'] } var obj1 = createObj(obj); obj1.colors.push('pink'); // ["red", "gree", "pink"] obj1.sayHi(); // hi console.log(obj1.colors); var obj2 = createObj(obj); obj2.sayHi(); // hi console.log(obj2.colors); // ["red", "gree", "pink"]Copy the code
Existing problems
- As with prototypal inheritance, instantiated objects share reference data from the stereotype rather than being unique to each other
6. Parasitic combination inheritance
Function SuperFun(name) {this.name = name; this.colors = ['red', 'green']; } SuperFun.prototype.getName = function () { return this.name; } function SubFun(name, age) { SuperFun.call(this, name); // (1) inherit: inherit this.age = age; }; SubFun.prototype = Object.create(SuperFun.prototype); / / (2) inheritance: inheritance method SubFun on the prototype. The prototype. The constructor = SubFun; Subfun.prototype. sayAge = function () {return this.age; } var obj = new SubFun('qb', 30); console.log(obj); // {name: 'qb', colors: ['red', 'green'], age: 30} console.log(obj.sayAge()); console.log(obj.getName()); obj.colors.push('pink'); console.log(obj); // {name: 'qb', colors: ['red', 'green', 'pink'], age: 30} var obj2 = new SubFun('qb', 30); console.log(obj2); // {name: 'qb', colors: ['red', 'green'], age: 30}Copy the code
The subclass constructor initializes the code in the parent constructor by superfun.call (this, name). The result is that each instance has its colors attribute and inherits the attributes and methods on the parent constructor’s prototype through Object.create. At this point, the SubFun constructor or SuperFun, again through SubFun. Prototype. Constructor refers back to SubFun = SubFun way.
7. Class class inheritance
class SuperFun { constructor () { this.colors = ['red', 'green'] } } class SubFun extends SuperFun{} let obj = new SubFun(); console.log(obj.colors); // ["red", "green"] obj.colors.push('pink'); console.log(obj.colors); // ["red", "green", "pink"] let obj2 = new SubFun(); console.log(obj2.colors); // ["red", "green"]: console.log(obj.constructor === SubFun) // true: the instantiated object's constructor points to a subclassCopy the code
As you can see, objects instantiated in ES5 inheritance share reference data on the prototype and constructor pointing issues are handled. While class inheritance is a new syntax, it is still essentially a prototype chain.
An object is an unordered set of attributes. Inheritance can make the creation of an object traceable and classable.