Learning notes of javascript advanced programming | 8.2 create object

Posted by purencool on Thu, 17 Feb 2022 08:28:28 +0100

follow [front end Xiaoao] , read more original technical articles

create object

  • Create a single Object: Object constructor and Object literal
  • Disadvantages: using one interface to create many objects produces a lot of duplicate code

Relevant code →

Factory mode

  • Create a specific interface according to a specific object creation process
function createPerson(name, age, job) {
  var o = new Object()
  o.name = name
  o.age = age
  o.job = job
  o.sayName = function () {
    console.log(this.name)
  }
  return o
}
var person1 = createPerson('Nicholas', 29, 'Engineer')
var person2 = createPerson('Greg', 27, 'Doctor')
console.log(person1)
console.log(person2)
  • Factory pattern solves the problem of creating multiple similar objects, but it does not solve the problem of object recognition (how to know the type of an object)

Constructor Pattern

  • In addition to native constructors such as Object and Array, you can also create custom constructors
  • Constructor mode vs factory mode
    • Do not explicitly create objects
    • Assign properties and methods directly to this object
    • No return
function Person(name, age, job) {
  this.name = name
  this.age = age
  this.job = job
  this.sayName = function () {
    console.log(this.name)
  }
}
var person1 = new Person('Nicholas', 29, 'Software Engineer')
var person2 = new Person('Greg', 27, 'Doctor')
  • The constructor starts with a capital letter and uses the new operator when creating an instance
  • After constructor new an object:
    • A new object (instance) was created
    • The [[prototype]] attribute inside the new object is assigned as the prototype attribute of the constructor (pointing to the prototype together)
    • Assign the scope of the constructor (i.e. this) to the new object
    • Execute the code in the constructor (that is, add a new attribute to this object)
    • Returns a new or non empty object
  • The created Object (instance) is both an instance of the Object and an instance of the constructor, and its constructor attribute points to the constructor
  • You can ensure that instances of custom constructors are identified as specific types, which is where the constructor pattern outperforms the factory pattern
console.log(person1.constructor === Person) // true, the constructor attribute points to the constructor
console.log(person2.constructor === Person) // true, the constructor attribute points to the constructor
console.log(person1 instanceof Object) // true, person1 is an instance of Object
console.log(person1 instanceof Person) // true, person1 is an instance of Person
console.log(person2 instanceof Object) // true, person2 is an instance of Object
console.log(person2 instanceof Person) // true, person2 is an instance of Person
  • The constructor can also be expressed by function expression. When instantiation does not pass parameters, the parentheses behind the constructor can be added or not
var PersonExpression = function () {
  // Function expression of constructor
  this.name = 'Jake'
  this.sayName = function () {
    console.log(this.name)
  }
}
var personNoBrackets = new PersonExpression() // Instantiation does not pass parameters, and parentheses are not required

Constructors are also functions

  • The only difference between constructors and ordinary functions is that they are called in different ways: constructors are called with the new operator, and ordinary functions are not used
  • By default, this when calling the function points to the Global object (pointing to the window object in the browser)
var person3 = new Person('Nicholas', 29, 'Software Engineer') // Creating objects with constructors
person3.sayName() // 'Nicholas'
Person('Greg', 27, 'Doctor') // 'Greg', instead of using the new operator, call directly
global.sayName() // Call the function directly, and this points to the Global object (pointing to the window object in the browser)

var o = new Object() // New object o
var p = new Object() // New object p
Person.call(o, 'Kristen', 25, 'Nurse') // Specify object o as this value inside Person(), and call() passes in each parameter separately
Person.apply(p, ['Kristen', 25, 'Nurse']) // Specify the object o as the value of this inside Person(), and pass in the parameter array with apply()
o.sayName() // 'Kristen'
p.sayName() // 'Kristen'

Constructor problem

  • The defined method will be created on each instance. Every time a Function is defined, an object will be instantiated. It is not necessary to create two Function instances to complete the same task
function Person2(name, age, job) {
  this.name = name
  this.age = age
  this.job = job
  this.sayName = new Function(console.log(this.name)) // Equivalent to declaring Function logic, a Function instance must be created every time an object is created
}
console.log(person1.sayName === person2.sayName) // false, the scope chain and identifier resolution of the two methods of the new object are different
  • Move the method of the object outside the constructor to avoid creating Function instances multiple times
function Person3(name, age, job) {
  this.name = name
  this.age = age
  this.job = job
  this.sayName = sayName
}
function sayName() {
  console.log(this.name) // Set sayName to global function
}
var person4 = new Person('Nicholas', 29, 'Software Engineer')
  • The problem that the constructor is still unsolved: (1) the global function created is actually only called by an object. ② If the object has multiple methods, you need to create many global methods

Prototype mode

  • Each function has a prototype attribute, which is a pointer to the prototype object of the function (the object instance created by calling the constructor)
  • The advantage of using a prototype object is that all its object instances share the properties and methods it contains
function PersonPrototype() {}
PersonPrototype.prototype.name = 'Nicholas' // Add properties to the prototype object of PersonPrototype
PersonPrototype.prototype.age = 29 // Add properties to the prototype object of PersonPrototype
PersonPrototype.prototype.job = 'Software Engineer' // Add the property of prototype object as person
PersonPrototype.prototype.sayName = function () {
  // Add a method to the prototype object of PersonPrototype
  console.log(this.name)
}

var person5 = new PersonPrototype()
var person6 = new PersonPrototype()

person5.sayName() // 'Nicholas'
person6.sayName() // 'Nicholas'
console.log(person5.sayName === person6.sayName) // true, the properties and methods created on the prototype object are shared by all instances

Understanding prototype objects

  • As long as a function is created, the prototype attribute will be created for the function to point to the prototype object. By default, the prototype object will automatically obtain the constructor attribute and point back to the constructor associated with it
console.log(PersonPrototype.prototype.constructor) // PersonPrototype constructor. The constructor attribute of the prototype object points to the constructor associated with it
console.log(PersonPrototype === PersonPrototype.prototype.constructor) // true, both point to the constructor
  • The instance contains a [[Prototype]] pointer to the Prototype object of the instance constructor, but there is no standard way to access [[Prototype]]
  • In the browser, available__ proto__ Attribute implements the function of [[Prototype]]
console.log(person5.__proto__) // Prototype object, personprototype {Name: 'Nicholas', age: 29, job:' Software Engineer ', sayname: [function]}
console.log(person5.__proto__ === PersonPrototype.prototype) // true, both point to the prototype object
console.log(person5.__proto__.constructor) // Function: PersonPrototype constructor
console.log(person5.__proto__ === person6.__proto__) // true to share the same prototype object
  • instanceof checks whether the prototype of the specified constructor is included in the prototype chain of the instance
console.log(person5 instanceof PersonPrototype) // true, person5 is an instance of PersonPrototype
console.log(person5 instanceof Object) // true, person5 is an instance of Object
console.log(PersonPrototype.prototype instanceof Object) // true, all instance objects and prototype objects are instances of Object
  • The isPrototypeOf() method of the prototype object detects whether there is a pointer to the prototype object in the instance
console.log(PersonPrototype.prototype.isPrototypeOf(person5)) // true, person5 contains a pointer to the prototype object of PersonPrototype
console.log(PersonPrototype.prototype.isPrototypeOf(person1)) // false, person1 does not contain a pointer to the prototype object of PersonPrototype
  • Object.getPrototypeOf() method (the parameter is generally an instance) returns the value of [[Prototype]] of the parameter (generally a Prototype object)
console.log(Object.getPrototypeOf(person5)) // Prototype object
console.log(Object.getPrototypeOf(person5) === person5.__proto__) // true, both point to the prototype object
console.log(Object.getPrototypeOf(person5) === PersonPrototype.prototype) // true, both point to the prototype object
console.log(Object.getPrototypeOf(person5).name) // 'Nicholas'
console.log(Object.getPrototypeOf(person5).constructor) // Function: PersonPrototype constructor
  • Object.setPrototypeOf() method writes a new value (parameter 2) to [[Prototype]] of the instance (parameter 1), thus rewriting the Prototype inheritance relationship of an object
var biped = {
  numLegs: 2,
}
var person = {
  name: 'Matt',
}
Object.setPrototypeOf(person, biped)
console.log(person.name) // 'Matt'
console.log(person.numLegs) // 2
console.log(person.__proto__) // {numLegs: 2}, the [[Prototype]] pointer of person points to the biped
  • To avoid object Setprototypeof() may seriously affect the code performance. You can use object Create() creates a new object and assigns a prototype (parameter) to it
var biped2 = {
  numLegs: 3,
}
var person = Object.create(biped2)
console.log(person.numLegs) // 3
console.log(person.__proto__) // {numLegs: 3}, the [[Prototype]] pointer of person points to biped2

Prototype level

  • Search process for reading object properties by code:

    • 1. Search the object instance itself - > have attribute → return attribute value - > end
    • 2. The object instance itself has no attribute - > search prototype object → have / no attribute → return attribute value / undefined → end
  • You can access the value of the property in the prototype through the instance (such as the constructor property), but you cannot override the value of the property in the prototype through the instance

  • If the added instance property has the same name as the property of the prototype, the instance property masks the property in the prototype

var person7 = new PersonPrototype()
person7.name = 'Greg'
console.log(person7.name) // 'Greg', from instance
console.log(person5.name) // 'Nicholas', from prototype
  • Delete the instance property with the same name to restore the properties of the masked prototype
delete person7.name
console.log(person7.name) // 'Nicholas', from prototype
  • Use the hasOwnProperty() method to check whether the property exists in the instance (return true if it exists), and the parameter is the property to be detected
var person8 = new PersonPrototype()
var person9 = new PersonPrototype()
console.log(person8.hasOwnProperty('name')) // false, name does not exist in the instance of person8
person8.name = 'Simon'
console.log(person8.name) // 'Simon ', from instance
console.log(person8.hasOwnProperty('name')) // true, name exists in the instance of person8
console.log(person9.name) // 'Nicholas', from prototype
console.log(person9.hasOwnProperty('name')) // false, name does not exist in the instance of person8
delete person8.name
console.log(person8.name) // 'Nicholas', from prototype
console.log(person8.hasOwnProperty('name')) // false, the name attribute of the person8 instance has been deleted
  • Object can be called on the prototype object Getownpropertydescriptor(), get the descriptor of the prototype property
console.log(Object.getOwnPropertyDescriptor(person8, 'name')) // undefined, there is no name attribute on the person8 instance
console.log(Object.getOwnPropertyDescriptor(person8.__proto__, 'name')) // {value: 'Nicholas',writable: true,enumerable: true,configurable: true}, name attribute descriptor of prototype object

Prototype and in operator

  • Use the in operator alone: if the object can access the specified attribute, it returns true, regardless of whether the attribute is in the instance or prototype
function PersonIn() {}
PersonIn.prototype.name = 'Nicholas'
PersonIn.prototype.age = 29
PersonIn.prototype.job = 'Software Engineer'
PersonIn.prototype.sayName = function () {
  console.log(this.name)
}
var person9 = new PersonIn()
var person10 = new PersonIn()

console.log(person9.hasOwnProperty('name')) // false, the instance person9 does not contain the name attribute
console.log('name' in person9) // true, you can access the name attribute through person9

person9.name = 'Greg'
console.log(person9.name); // 'Greg', from instance
console.log(person9.hasOwnProperty('name')) // true, the instance person9 contains the name attribute
console.log('name' in person9) // true, you can access the name attribute through person9
console.log(person10.name); // 'Nicholas', from prototype
console.log(person10.hasOwnProperty('name')) // false, the instance person10 does not contain the name attribute
console.log('name' in person10) // true. You can access the name attribute through person10

delete person9 'name'
console.log(person9.name); // 'Nicholas', from prototype
console.log(person9.hasOwnProperty('name')) // false, the instance person9 does not contain the name attribute
console.log('name' in person9) // true, you can access the name attribute through person9
  • Use hasOwnProperty() and the in operator at the same time to determine whether the property exists in the instance or prototype
function hasPrototypeProperty(object, name) {
  return !object.hasOwnProperty(name) && name in object // Does not exist in the instance & & can access → exists in the prototype
}
var person11 = new PersonIn()
console.log(hasPrototypeProperty(person11, 'name')) // true,!false && true
person11.name = 'Greg'
console.log(hasPrototypeProperty(person11, 'name')) // false,!true && true
  • For in loop: returns all accessible and Enumerable properties of the object (whether from the instance or prototype), shielding properties that cannot be enumerated ([[Enumerable]] is false) (such as the constructor of the prototype and the prototype of the constructor)
for (var attr in person11) {
  console.log(`${attr}:${person11[attr]}`)
  /*  
    name:Greg
    age:29
    job:Software Engineer
    sayName:function () {
      console.log(this.name)
    } 
  */
}
  • Object. The keys () method returns an array of enumerable properties of the object (itself), and the parameter is the object
var keys = Object.keys(PersonIn.prototype) // All enumerable properties of the prototype object
console.log(keys) // [ 'name', 'age', 'job', 'sayName' ]
var person12 = new PersonIn()
person12.name = 'Bob'
person12.age = 31
var p12keys = Object.keys(person12) // All enumerable properties of person12
console.log(p12keys) // [ 'name', 'age' ]
  • Object.getOwnPropertyNames() returns an array of all properties (whether enumerable or not) of the object (itself), and the parameter is the object
var keys = Object.getOwnPropertyNames(PersonIn.prototype) // All properties of prototype object, including non enumerable
console.log(keys) // ['constructor', 'name', 'age', 'job', 'sayName'], prototype objects contain constructor properties, pointing to constructors
var p12keys = Object.getOwnPropertyNames(person12) // All attributes of person12, including non enumerable
console.log(p12keys) // [ 'name', 'age' ]
console.log(Object.getOwnPropertyNames(PersonIn)) // [ 'length', 'name', 'arguments', 'caller', 'prototype' ]
  • ES6 added object Getownpropertysymbols() method returns an array of all symbol key properties (whether enumerable or not) of the object (itself), and the parameter is the object
var k1 = Symbol('k1')
var k2 = Symbol('k2')
var o = {
  [k1]: 'k1', // As an attribute, the symbol needs to use the "calculate attribute" syntax, i.e. [attribute name]
  [k2]: 'k2',
}
console.log(Object.getOwnPropertySymbols(o)) // [ Symbol(k1), Symbol(k2) ]

Attribute enumeration order

  • For in loop and object The order of keys () attribute enumeration is uncertain, which depends on the JS engine of the browser
  • Object.getOwnPropertyNames(),Object.getOwnPropertySymbols() and object Assign() determines the order of attribute enumeration:
    • First enumerate the numeric keys in ascending order
    • Then enumerate strings and symbol keys in insertion order
var k1 = Symbol('k1')
var k2 = Symbol('k2')
var o = {
  1: 1,
  first: 'first',
  [k2]: 'sym2',
  third: 'third',
  0: 0,
}
o[k1] = 'sym1'
o[3] = 3
o.second = 'second'
o[2] = 2
console.log(Object.getOwnPropertyNames(o)) // [ '0', '1', '2', '3', 'first', 'third', 'second' ]
console.log(Object.getOwnPropertySymbols(o)) // [ Symbol(k2), Symbol(k1) ]

Object iteration

  • ES7 added object Values () and object The entries () method receives the parameter object and returns the object value and the object key / value pair array respectively
var o = {
  foo: 'bar',
  baz: 1,
  qux: {},
}
console.log(Object.values(o)) // ['bar', 1, {}], iteration value
console.log(Object.entries(o)) // [['foo ',' bar '], ['baz', 1], ['qux ', {}]], iterative key value pairs
  • Non string properties are converted to strings, and the method performs a shallow copy of the object
var o = {
  qux: {},
}
console.log(Object.values(o)) // [ {} ]
console.log(Object.entries(o)) // [ [ 'qux', {} ] ]
console.log(Object.values(o)[0] === o.qux) // true, shallow copy, copy the reference of the object
console.log(Object.entries(o)[0][1] === o.qux) // true, shallow copy, copy the reference of the object
  • Symbol properties are ignored
var sym = Symbol()
var o = {
  [sym]: 'foo', // Symbol attribute
}
console.log(Object.values(o)) // [], symbol attribute ignored
console.log(Object.entries(o)) // [], symbol attribute ignored

Other prototype syntax

  • Rewrite the entire prototype object with a new object literal that contains all properties and methods
function PersonLiteral() {}
PersonLiteral.prototype = {
  name: 'Nicholas',
  age: 29,
  job: 'Software Engineer',
  sayName: function () {
    console.log(this.name)
  },
}
  • Set the prototype property of the constructor to create a new Object in the literal form of the Object, and its constructor property no longer points to the original constructor, but the constructor property of the new Object, that is, the Object constructor
var friend = new PersonLiteral()
console.log(friend instanceof Object) // true, friend is an instance of Object
console.log(friend instanceof PersonLiteral) // true, friend is an instance of PersonLiteral
console.log(friend.constructor === PersonLiteral) // false, the constructor property becomes a new object -- the constructor of the object literal
console.log(friend.constructor === Object) // true, the constructor of the new Object points to the Object constructor
  • You can set the constructor property in the object literal to point to the original constructor
  • Setting the constructor attribute in this way belongs to the attribute defined directly on the object, which will cause the [[Enumerable]] of the constructor attribute to be true and can be enumerated
function PersonLiteral2() {}
PersonLiteral2.prototype = {
  constructor: PersonLiteral2, // Directly define the constructor on the object and point to the original constructor
  name: 'Nicholas',
  age: 29,
  job: 'Software Engineer',
  sayName: function () {
    console.log(this.name)
  },
}
var friend2 = new PersonLiteral2()
console.log(friend2.constructor === PersonLiteral2) // true, the constructor points to the original constructor again
console.log(friend2.constructor === Object) // false
console.log(Object.keys(PersonLiteral2.prototype)) // ['constructor', 'name', 'age', 'job', 'sayName'], because a constructor is a "property defined directly on an object" and can be enumerated
  • Instead of setting the constructor property within the object literal, use object Defineproperty() modifies the properties of the constructor property in the object literal to be compatible with the JavaScript engine
Object.defineProperty(PersonLiteral2.prototype, 'constructor', {
  enumerable: false,
  value: PersonLiteral2,
})
console.log(Object.keys(PersonLiteral2.prototype)) // ['name', 'age', 'job', 'sayName'], enumerable of constructor has been set to false

Dynamics of prototype

  • Any changes made to the prototype object are immediately reflected on the instance, even if the instance is created first and then the prototype is modified
function Person4() {}
var friend3 = new Person4() // Create instance first
Person4.prototype.sayHi = function () {
  // Modify prototype object after
  console.log('Hi')
}
friend3.sayHi() // 'Hi', the instance is affected, and the instance points to the prototype
  • Rewriting the entire Prototype will cut off the connection between the constructor and the original Prototype. The [[Prototype]] pointer of the instance (created before rewriting the Prototype) points to the original Prototype (the instance created after rewriting the Prototype points to the new Prototype)
Person4.prototype = {
  // Rewrite prototype
  constructor: Person4,
  name: 'Nicholas',
  age: 29,
  job: 'Software Engineer',
  sayName: function () {
    console.log(this.name)
  },
}
console.log(friend3.__proto__) // Person4 {sayhi: [function]}, friend3 is created before rewriting the Prototype, and [[Prototype]] points to the original Prototype object
console.log(friend3.__proto__ === Person4.prototype) // false, rewriting the entire prototype cuts off the connection between the constructor and the original prototype
friend3.sayName() // error:friend3.sayName is not a function

Native object prototype

  • All native reference types (Array, Object, String...) are created in prototype mode, and methods are defined on the prototype of its constructor
console.log(Array.prototype) // View the prototype object of Array in the browser, including methods such as sort()
console.log(String.prototype) // View the prototype object of Array in the browser, including substring() and other methods
  • You can modify the prototype of a native object and add or delete methods just as you can modify the prototype of a custom object
  • Modifying the prototypes of native objects is not recommended, which may cause conflicts or override native methods
String.prototype.startsWith = function (text) {
  // Add the startsWith method to the prototype object of String
  return this.indexOf(text) === 0
}
var msg = 'Hello World'
console.log(msg.startsWith('Hello')) // true
console.log(msg.startsWith('World')) // false
delete String.prototype.startsWith
console.log(msg.startsWith('Hello')) // error

Prototype problem

  • The biggest problem of the prototype pattern is caused by its sharing nature. Especially for the attributes containing reference types, adding, deleting, modifying rather than redefining the attributes of reference types such as instance arrays and objects will affect the reference type attributes of the prototype
function PersonProblem() {}
PersonProblem.prototype = {
  constructor: PersonProblem,
  name: 'Nicholas',
  age: 29,
  job: 'Software Engineer',
  friends: ['Shelby', 'Court'],
  sayName: function () {
    console.log(this.name)
  },
}
var person13 = new PersonProblem()
var person14 = new PersonProblem()
person13.name = 'Greg' // Redefine and mask the properties of the prototype in the instance
person13.friends.push('Van') // Instead of redefining, add a string to the array of prototypes
console.log(person13.name) // 'Greg', obtained from the instance
console.log(person14.name) // 'Nicholas', obtained from the prototype
console.log(person13.friends) // ['Shelby', 'Court', 'Van'], obtained from the prototype
console.log(person14.friends) // ['Shelby', 'Court', 'Van'], obtained from the prototype
console.log(person13.friends === person14.friends) // true
var person15 = new PersonProblem()
person15.friends = [] // Redefine and mask the properties of the prototype in the instance
console.log(person15.friends) // [] obtained from instance
console.log(person13.friends) // ['Shelby', 'Court', 'Van'], obtained from the prototype
console.log(person14.friends) // ['Shelby', 'Court', 'Van'], obtained from the prototype

Summary & ask questions

create objectprocessshortcoming
Object constructorObject 1. Create instance Add properties and methodsMultiple objects are created in the same interface, and a large number of duplicate codes are generated
Object Literal Directly create objects that contain properties and methodsMultiple objects are created in the same interface, and a large number of duplicate codes are generated
Factory mode1. Encapsulate the process of creating an Object instance with a function (adding attributes and methods and returning the instance Object) 2 Call this functionIt does not solve the problem of object recognition, that is, how to know the type of an object
Constructor Pattern 1. Constructor encapsulation (creation object, attribute and method not shown are assigned to this object, no return) 2 New calls the constructorThe method is re created for each instance, and the Function object with the same mechanism is instantiated multiple times
Prototype mode1. Constructor encapsulation (empty, no attributes and methods) 2 Add properties and methods to the prototype object 3 New calls the constructorModifying rather than redefining the reference type property of an instance from the prototype will affect the prototype
objectattributeDefault pointingusage
Any functionprototypePrototype objectPerson.prototype → prototype object of constructor
Examples, prototypesconstructorConstructorperson1.constructor === Person.prototype.constructor === Person
example[[Prototype]]Prototype objectperson1.__proto__ === Person.prototype (there is no standard way to access [[prototype]], but _proto _)
Operatormeaningusage
newCreate an instance of the constructor (four steps)var person = new Person()
deleteDelete instance propertiesdelete person.name
inWhether the property can be accessed through the object (whether the property is in the instance or prototype)console.log('name' in person)
for-inReturns all enumerable properties that can be accessed through the object (whether the property is in the instance or prototype)for(var attr in person){console.log(attr)}
methodmeaningparameterReturn value
isPrototypeOf()Does the instance have a pointer to the prototype objectexampletrue/false
Object.getPrototypeOf()Get the value of instance [[Prototype]]examplePrototype object
Object.setPrototypeOf()Write a new value to [[Prototype]] of the instance (specify Prototype)① Instance ② specify prototype
Object.create()Create a new object and assign a prototype to itSpecify prototype
hasOwnProperty()Whether the property exists in the instance (not in the prototype)attributetrue/false
Object.keys()Gets all enumerable properties of the object (itself)objectProperty
Object.getOwnPropertyNames()Get all properties of the object (itself) (whether enumerable or not)objectProperty (the prototype object contains the constructor property)
Object.getOwnPropertySymbols()Gets all symbolic key properties of the object (itself) (whether enumerable or not)objectAttribute (prototype object contains constructor attribute)
Method / operatorEnumeration order
for-inThe enumeration order is uncertain, depending on the JS engine of the browser
Object.keys()The enumeration order is uncertain, depending on the JS engine of the browser
Object.getOwnPropertyNames()Enumeration order determination: first enumerate numeric keys in ascending order, and then enumerate string and symbol keys in insertion order
Object.getOwnPropertySymbols()Enumeration order determination: first enumerate numeric keys in ascending order, and then enumerate string and symbol keys in insertion order
  • What are the ways to create a single object? What are the disadvantages of these methods?
  • How has the factory mode been optimized? What are the disadvantages of this model?
  • What are the differences and advantages of the constructor pattern over the factory pattern? What happened in the process of new?
  • Where does the constructor attribute of the object created by the constructor point to? Which constructor instances are such objects?
  • What are the similarities and differences between constructors and ordinary functions?
  • What are the disadvantages of the constructor pattern? What are the disadvantages of using global functions instead of constructor internal objects?
  • What is the prototype attribute of the function? What are the benefits of using prototype objects? How to understand the constructor attribute of prototype object?
  • How can constructors, instances and prototype objects be obtained from each other? What method is used to detect whether the instance contains a pointer to the prototype object?
  • Object.getPrototypeOf(),Object.setPrototypeOf(),Object. What is the meaning and usage of create() respectively?
  • What kind of search process does the code go through when reading object properties? Can I access and modify the property values in the prototype through the instance?
  • What happens if you add a property with the same name as the prototype in the instance? Delete the new attribute in this instance?
  • What does it mean to use the in operator alone? What is the difference between it and the hasOwnProperty() method?
  • Please write a piece of code to determine whether a property exists in the instance or prototype
  • What is the usage of for in? Which attributes are returned and which attributes are masked?
  • Object.keys(),Object.getOwnPropertyNames(),Object.getOwnPropertySymbols(),Object.values(),Object. What are the usage of entries()?
  • for-in,Object.keys(),Object.getOwnPropertyNames(),Object. What is the difference between the order of getownpropertysymbols() in property enumeration?
  • When rewriting the entire prototype object with a new object literal, what happens to the constructor point of the prototype object?
  • Write a piece of code, rewrite the prototype object of the constructor with the object literal, and the constructor of the prototype object still points to the original constructor, and retain the "non enumerable" property of the constructor attribute
  • If you create an instance and then modify the properties of the prototype, will the instance be affected? Why?
  • After rewriting the entire Prototype object, where does the Prototype of the constructor point? Where does the [[Prototype]] attribute of the instance created before rewriting point to? Why?
  • How are methods of native reference types created? Why not recommend modifying prototypes of native reference types?
  • The "shared" nature of the prototype pattern, what problems will arise when modifying properties that contain reference types?

Topics: Javascript Front-end OOP object