JavaScript Advanced Programming (4th Edition) Reading Sharing Note Recording
Applicable to comrades who are just getting started
Create an instance of Object
let person = new Object();
person.name = "Nicholas";
person.age = 29;
person.job = "Software Engineer";
person.sayName = function() {
console.log(this.name);
};
object literal
let Person = {
name:'Tom',
age:28,
job:'Teacher',
sayName(){
console.log(this.name)
}
}
Person.sayName() // Tom
Although it is convenient to create objects using the Object constructor or object literals, these methods also have obvious disadvantages: creating multiple objects with the same interface requires repeated writing of a lot of code.
factory pattern
function createPerson(name,age,job){
let o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name)
}
return o;
}
let person1 = createPerson('Tom',28,'Teacher')
let person2 = createPerson('Jerry',18,'Student')
console.log(person1 ) // {name:'Tom',age:28,job:'Teacher',sayName: ƒ ()}
constructor pattern
function Person(name,age,job){
this.name = name
this.age = age
this.job = job
this.sayName = function(){
console.log(this.name)
}
}
let person1 = new Person('Tom',28,'Teacher')
person1.sayName () //Tom
let person2 = new Person('Jerry',18,'Student')
person1.sayName () //Jerry
The difference between factory pattern and constructor pattern:
- Objects are not explicitly created.
- Properties and methods are directly assigned to this .
- no return
- create a new object;
- Assign the scope of the constructor to the new object (make this point to the new object);
- Execute the code in the constructor (add properties to this new object);
- Return the new object.
Question :
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName() {
console.log(this.name);
}
let person1 = new Person("Nicholas", 29, "Software Engineer");
let person2 = new Person("Greg", 27, "Doctor");
person1.sayName(); // Nicholas
person2.sayName(); // Greg
prototype pattern
function Person(){}
Person.prototype.name = 'Tom'
Person.prototype.age = 28
Person.prototype.job = 'Teacher'
Person.prototype.sayName = function(){
console.log(this.name)
}
let person1 = new Person()
person1.sayName() // Tom
let person2 = new Person()
person1.sayName() // Tom
console.log(person1.sayName == person2.sayName); // true
understand archetypes
Whenever a function is created, a prototype property (pointing to the prototype object) is created for the function according to specific rules. By default, all prototype objects automatically get a property named constructor pointing back to the constructor function associated with them.
The previous example can be understood as:
Person.prototype.constructor oriented Person.
console.log(Person.prototype.constructor === Person); // true
When customizing the constructor, the prototype object will only get the constructor attribute by default, and all other methods inherit from
Object. Every time the constructor is called to create a new instance, the instance's internal [[Prototype]] (__proto__ attribute) pointer will be assigned as the prototype object of the constructor
console.log(Person.prototype.__proto__ === Object.prototype); // true
archetype level
When accessing the properties and methods of an instance, an attribute is first searched on the instance. If this property exists on the instance, so the prototype object will not be searched again. And did not find this property on the instance, so it will continue to search the prototype object and use the property defined on the prototype.
example:
function Person() {}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function() {
console.log(this.name);
};
let person1 = new Person();
let person2 = new Person();
person1.name = "Greg";
console.log(person1.name); // "Greg",来自实例
console.log(person2.name); // "Nicholas",来自原型
example:
function Person() {}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function() {
console.log(this.name);
};
let person1 = new Person();
let person2 = new Person();
person1.name = "Greg";
console.log(person1.name); // "Greg",来自实例
console.log(person2.name); // "Nicholas",来自原型
delete person1.name;
console.log(person1.name); // "Nicholas",来自原型
function Person() {}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function() {
console.log(this.name);
};
let person1 = new Person();
let person2 = new Person();
console.log(person1.hasOwnProperty("name")); // false
person1.name = "Greg";
console.log(person1.name); // "Greg",来自实例
console.log(person1.hasOwnProperty("name")); // true
// 原型对象还是接上面的
let person = new Person();
console.log(hasPrototypeProperty(person, "name")); // true
person.name = "Greg";
console.log(hasPrototypeProperty(person, "name")); // false
Object.keys()
To get all enumerable instance properties on an object
//原型对象接上面的案例
let keys = Object.keys(Person.prototype);
console.log(keys); // "name,age,job,sayName"
let p1 = new Person();
p1.name = "Rob";
p1.age = 31;
let p1keys = Object.keys(p1);
console.log(p1keys); // "[name,age]"
Object.getOwnPropertyNames():
If you want to list all instance attributes, whether enumerable or not, you can use
let keys = Object.getOwnPropertyNames(Person.prototype);
console.log(keys); // "[constructor,name,age,job,sayName]"
object iteration
ECMAScript 2017 adds two new static methods, Object.values() and Object.entries() receive an object
Example:
const o ={
foo: 'bar',
baz: 1,
qux: {}
};
console.log(Object.values(o)); // ["bar", 1, {}]
console.log(Object.entries((o))); // [["foo", "bar"], ["baz", 1], ["qux", {}]]