Explanation
- Then JavaScript -> [study notes] & appreciated observer pattern & factory model objects & constructor mode
- Instance on a constructor pattern created with a method different instances are not equal, in order to solve this problem. Appeared prototype model
1. The archetypal pattern
- In practice, the information defining the object instance is not the constructor, but to add this information directly to
原型对象
the
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();
person1.sayName(); // "Nicholas"
var person2 = new Person();
person2.sayName(); // "Nicholas"
console.log(person1.sayName == person2.sayName); // true
1.1 understand the prototype object
1.1.1 prototype properties and constructor property
- Create a function (Person), will create a prototype property (Person.prototype) according to a set of rules
- prototype above but also a constructor property (will bring skills), it (Person.prototype.constructor) pointing function Person
- All methods and properties on prototype property are all instances (person1, person2) using the new operator production sharing
- Examples person1, person2 by
new Person
obtained, there will be a [[the Prototype]] pointer (__proto__ accessed through a browser), which points Person.prototype
1.1.2 reading order of a property
- Read attribute simulation function is as follows:
// obj是某个对象, attr是该对象的属性
const getVal = (obj, attr) =>{
// 如果对象中存在该属性则返回
if(obj[attr]) {
return obj[attr]
} else if (obj.constructor === Object) {
// 是Object
return undefined
} else{
// 不是Object,检查其constructor指向的函数
if(obj.constructor[attr]){
return obj.constructor[attr]
} else {
// constructor指向的函数中不存在,顺着 __proto__ 属性找下去.
getVal(obj.__proto__, attr);
}
}
}
Description:
- All function by function declarations are inherited from Function
- Function inherited from Object
1.1.3 talk
By order of the prototype to find the property above, you can know:
- When
new Person
the time to generate an instance (PERSON1) of, person1 have a pointer to the __proto__ Person.prototype - When accessing a property or method of person1, starting with examples start looking, if found is returned, otherwise it will follow __proto__ looking up
Is from 1.2 to distinguish one attribute Prototype
You need to understand the following two points:
- Using the
in
operator will return all or a method on an object - Use hasOwnProperty may determine whether a property of the object from Example
// 判断一个熟悉是否来自原型
const fromPrototype = (obj, attr) {
return !obj.hasOwnprototype && (attr in obj);
}
1.3 Object.defineProperty
Object.defineProperty
: You can add properties to an object, and the described property- Use as follows:
Object.defineProperty(Person.prototype, "constructor", {
enumerable: false,
value: Person
})
1.3.1 Access data attributes and properties
- JS attribute type is divided into: the data access attributes and properties
- Data attributes include:
- [[Configurabal]]: whether to be
delete
deleted - [[Numerable]]: whether you can
for-in
access the property cycle - [[Writeble]]: Can be modified
- [[Value]]: value of the property
- Access Properties: Configurable, Numerable, Get (trigger to read), (trigger when modifying) Set
1.3.2 Object.defineProperty use
- When using object literal assignment of function prototypes, it will lose the original constructor property
- Use
Object.defineProperty
it together with the constructor property
function Person () {}
Person.prototype = {
name: 'marron',
age: 18
}
Object.defineProperty(Person.prototype, constructor, {
numerable: false,
value: Person
})
- constructor can not be
for-in
iterate to - Direct assignment in the literal and will be
for-in
circulating to visit
1.4 dynamic prototype
- After the first instance you can create a modified prototype
function Person () {};
cosnt friend = new Person();
Person.prototype.sayHi = () => { console.log('SayHi') };
friend.sayHi();
- The above code changes as the following:
- Person.prototype.sayHi = () => { console.log('SayHi') };
+ Person.prototype = {
+ sayHi: function () {
+ console.log('SayHi');
+ }
+ }
- At this time, the call
friend.sayHi
will complain:Uncaught TypeError: p1.sayHi is not a function
the following reasons:
- When using the new operator: the establishment of a pointer proto , which points Person.prototype (this is the default set up), it is assumed in the space A, i.e. this time person1 start taking their own data space, if not then go to A, Find
- When Person.prototype be literal assignment, it changes the pointer to point Person.prototype, in the above series of operations is actually in the space B.
- Upon the completion of the literal Person.prototype assignment, which is equivalent to the Person of the prototype object has opened up a new space B. At a time when the __proto__ person1 it or not visit B to point A.
Note: Rewrite the prototype object cut the link between the existing prototype object instances with any previously exist.