Chapter 8 of JavaScript Advanced Programming Reading Sharing - 8.2 Creating Objects

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: ƒ ()}
      Problem:   Although this factory pattern can solve the problem of creating multiple similar objects, it does not solve the problem of object identification (that is, what type of newly created object is)

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
To create an instance of Person , the new operator should be used. Invoking the constructor in this way does the following:
  1. create a new object;
  2. Assign the scope of the constructor to the new object (make this point to the new object);
  3. Execute the code in the constructor (add properties to this new object);
  4. Return the new object.

Question :

        The main problem with constructors is that the methods they define are created on every instance. So for the previous example, both person1 and person2 have a method named sayName() , but the two methods are not the same Function instance.

solve:
To solve this problem, you can move the function definition outside the constructor
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",来自原型
        As long as an attribute is added to the object instance, this attribute will shadow ( shadow) the attribute of the same name on the prototype object, that is, although it will not be modified, it will block access to it. However, the property on the instance can be completely removed using the delete operator, allowing the identifier resolution process to continue searching for the prototype object.

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",来自原型
hasOwnProperty() method
        Used to determine whether a property is on an instance or a prototype object. This method is inherited from Object and returns true if the property exists on the object instance that calls it, and false on the prototype.
        By calling hasOwnProperty(), you can clearly see whether you are accessing an instance property or a prototype property.
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(); 

console.log(person1.hasOwnProperty("name")); // false

person1.name = "Greg"; 
console.log(person1.name); // "Greg",来自实例
console.log(person1.hasOwnProperty("name")); // true
 hasPrototypeProperty()
Properties first exist only on prototypes, so hasPrototypeProperty() returns true.
The instance also has this property, so hasPrototypeProperty() returns false .
example:
// 原型对象还是接上面的

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.getOwnPropertySymbols()

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", {}]]

Guess you like

Origin blog.csdn.net/weixin_42307283/article/details/129276747