Some methods of Object you should know

foreword

Recently, I came into contact with the source code of methods in vue3. Many object methods are used in it. Looking at some methods in it, I want to learn while understanding. I hope to understand the knowledge points and be more impressed when I read it again in the future. Thinking of learning in this way of adding, deleting, and modifying is also convenient for memorization. The following are some object methods that need to be used in the vue3 source code.

In JavaScript, almost all objects are Objectinstances of the type, and they all Object.prototypeinherit properties and methods from , although most properties will be shadowed or overridden, and Objectcan also be created intentionally, but This object is not a "real object".

Object initialization (increment)

Objects can be initialized by methods such as new Object(), Object.create()or by using literal tags (initialization tags).

  • 构造函数new Object() , the constructor wraps the given value into a new object

    • If the given value is nullor undefined, it creates and returns an empty object
let emptyObject = new Object()  // {}
let emptyObject = new Object(undefined) // {}
let emptyObject = new Object(null) // {}

const valueObject1 = new Object({
    
    "name":"沐阳vae"})
console.log(valueObject1) //{name: '沐阳vae'}

const valueObject2 = new Object()
valueObject.name = "沐阳"
console.log(valueObject2) // {name: '沐阳'}
  • 静态方法

    1,Object.assign

    Syntax: Object.assign(target, ...sources), will not sourcesthrow an error when the object value is null or undefined

    const target = {
          
           a: 1, b: 2 };
    const source = {
          
           b: 4, c: 5 };
    const returnTarget = Object.assign(target, source);
    console.log(target) // {a: 1, b: 4, c: 5}
    console.log(returnTarget) // {a: 1, b: 4, c: 5}
    console.log(source) //{ b: 4, c: 5 }
    

    Object.assign() creates a new object by copying one or more objects. Object.assign()The objects created by copying are shallow copies, and only the property values ​​are copied. If the source object is a reference to an object, it will only copy its reference value.

    let obj = {
          
          a: 1, b: {
          
           c: 0}}
    let newObj = Object.assign({
          
          }, obj)
    console.log(newObj) // {a: 1, b: { c: 0}} ,浅拷贝,复制的是引用值,a复制的是1,b复制的就是引用地址了。
    obj.a = 3
    console.log(obj) // {a: 3, b: { c: 0}}
    console.log(newObj) // {a: 1, b: { c: 0}}
    
    // 后面在加上这里obj.b.c = 2,改变之后,整个引用地址里面的属性值也被改变了
    obj.b.c = 2
    console.log(obj) // {a: 3, b: { c: 2}}
    console.log(newObj) // {a: 1, b: { c: 2}}
    
    // 使用JSON.parse(JSON.stringify())进行深拷贝
    let deepObj = JSON.parse(JSON.stringify(obj))
    obj.a = 4
    obj.b.c = 4
    console.log(JSON.stringify(obj3)) // {"a":3,"b":{"c":2}}
    console.log(obj) // {"a":4,"b":{"c":4}}
    

    原型链上attributes and 不可枚举attributes cannot be copied

    const obj = Object.create({ foo: 1 }, { 
      // foo 是对象原型链上的属性.
      notEnum: {
        value: 2  //没有设置enumerable,不可枚举.
      },
      canEnum: {
       value: 3,
       enumerable: true  // enumerable设置是否可以枚举.
      }
     });
    
     const copy = Object.assign({}, obj);
     console.log(copy); // { canEnum: 3 }
    
    

    2,Object.create

    Syntax: Object.create(proto)or Object.create(proto, propertiesObject).
    Object.create()method is used to create a new object, using an existing object as a prototype for the newly created object

    const person = {
      name: 'person',
      printIntroduction: function() {
      console.log('this':this)
      console.log(`this指向新创建的对象${this.name}`);
      }
     }
     
     console.log(person.printIntroduction()) 
     //this: {name: 'person', printIntroduction: ƒ}
     //this指向新创建的对象person
     const mine = Object.create(person)
     console.log(person.printIntroduction()) 
     // this: {}
     // this指向新创建的对象person,新创建的对像上没有name属性时,回在原来的对象是取用,但是此时的this指向新创建的对象
     mine.name = 'mine'
     console.log(mine.printIntroduction() 
     // this: {name: 'mine'} ,
     //this指向新创建的对象mine
    

    Exception:
    protoArgument is null, or wrapper object 基本类型包装对象of primitive type other than对象

    All primitive types except nulland undefinedhave their corresponding wrapper objects

    name explain
    String string primitive type
    Number numeric primitive type
    BigInt big integer primitive type
    Boolean Boolean primitive type
    Symbol Literal primitive types

    An object prototyped nullby because it does not Object.prototypeinherit any object methods from .
    And the lack of Object.prototype.toString()methods often makes debugging very difficult

    const normalObj = {
          
          };   // 普通对象
    const nullProtoObj = Object.create(null) // null作为自己的原型
    console.log(normalObj) // {}
    console.log(nullProtoObj) // {}
    console.log("" + normalObj) // [object Object]
    console.log("" + nullProtoObj) // 报错
    
    alert(normalObj); // 展示 [object Object]
    alert(nullProtoObj) // 报错
    
    normalObj.valueOf() // shows {}
    nullProtoObj.valueOf() // 报错
    
    normalObj.hasOwnProperty("p") // 展示 "false"
    nullProtoObj.hasOwnProperty("p") //报错
    
    normalObj.constructor // 出现 "Object() { [native code] }"
    nullProtoObj.constructor // 出现"undefined"
    

    You can add methods for objects prototyped on null toString, like this:

    nullProtoObj.toString = Object.prototype.toString; // 
    
    console.log(nullProtoObj.toString()); // 展示 "[object Object]"
    console.log("nullProtoObj is: " + nullProtoObj); // 展示 "nullProtoObj is: [object Object]"
    

    In practice, objects prototyped nullon are often used as mapa replacement for . Because Object.prototypethe existence of the prototype's own properties will cause some errors

     const ages = {
          
           '张三': 18, '李四': 27 };
    
      function hasPerson(name) {
          
          
        return name in ages;
      }
    
      function getAge(name) {
          
          
        return ages[name];
      }
      
      hasPerson('李四') //true
      getAge('李四') // 27
      hasPerson("hasOwnProperty") // true
      getAge("toString") // ƒ toString() { [native code] }
    

    Using a null-prototyped object eliminates this potential problem and doesn't introduce too much complex logic to the hasPersonand functions:getAge

    const ages = Object.create(null, {
          
          
    '张三': {
          
           value: 18, enumerable: true },
    '李四': {
          
           value: 27, enumerable: true },
    });
    
     function hasPerson(name) {
          
          
       return name in ages;
      }
    
     function getAge(name) {
          
          
       return ages[name];
     }
    
    hasPerson('李四') //true
    getAge('李四') // 27
    hasPerson("hasOwnProperty") // false
    getAge("toString") // undefined
    

    Objects that do not inherit Object.prototypeprototype methods can also prevent prototype pollution attacks. If a malicious script Object.prototypeadds a property to it, this property will be accessible by every object in the program, while objects prototyped on null will not be affected

Object property delete (delete)

Object itself does not provide a method to delete its own properties ( in Map Map.prototype.delete()can delete its own properties). In order to delete a property on an object, one must usedelete 操作符

  • delete delete on the map prototype
// 创建Map实例
const willDeleteMap = new Map()
// 对willDeleteMap对象设置属性和值
willDeleteMap.set('name', 'value')
// delete删除name属性,删除成功返回true
console.log(willDeleteMap.delete('name')) // true
// has查询对象里面是否还有名为name的属性,没有,结果返回false
console.log(willDeleteMap.has('name')) // false
  • delete operator
// 字面量创建对象
const willDeleteMap = {
    
    
  firstname: '沐',
  lastname: '阳'
}
// 删除成功返回true
delete willDeleteMap.firstname
console.log(willDeleteMap) // {lastname: '阳'}
console.log(willDeleteMap.firstname)// undefined

Compare objects

grammar:Object.is(value1, value2)

Object.is(), method to determine whether two values ​​are the same value. Object.isdoes not coerce the values ​​on either side,

 // Case 1
  Object.is(25, 25);                // true
  Object.is('foo', 'foo');          // true
  Object.is('foo', 'bar');          // false
  Object.is(null, null);            // true
  Object.is(undefined, undefined);  // true
  Object.is(window, window);        // true
  Object.is([], []);                // false
  
  var foo = {
    
     a: 1 };
  var bar = {
    
     a: 1 };
  Object.is(foo, foo);              // true
  Object.is(foo, bar);              // false

  // Case 2: Signed zero
  Object.is(0, -0);                 // false
  Object.is(+0, -0);                // false
  Object.is(-0, -0);                // true
  Object.is(0n, -0n);               // true

  // Case 3: NaN
  Object.is(NaN, 0/0);              // true
  Object.is(NaN, Number.NaN)        // true

Freeze Object Object.freeze()

grammar:Object.freeze(obj)

Object.freeze()method to freeze an object. A frozen object can no longer be modified; when an object is frozen, new properties cannot be added to the object, existing properties cannot be deleted, and the enumerability, configurability, and writability of the existing properties of the object cannot be modified. property, and cannot modify the value of an existing property. Additionally, the prototype of an object cannot be modified after freezing it. freeze()Returns the same object as the passed parameter

const  freezeObj = {
    
    
  prop: function() {
    
    },
  foo: 'bar',
  childObj: {
    
    },
  childArr: []
}
freezeObj.foo = '第一次修改后的foo' //可修改
delete freezeObj.prop // 可删除
freezeObj.childArr.push(0)
freezeObj.addChild = "增加的数据"
console.log(freezeObj) // {foo: '第一次修改后的foo', childObj: {…}, childArr: Array(1), addChild: '增加的数据'}

//进行冻结
 const newObj = Object.freeze(freezeObj); // 作为参数传递的对象freezeObj与返回的对象newObj都被冻结,也不用保存返回的对象(因为两个对象全等)
 newObj === freezeObj // true, 
 newObj.foo = '第二次修改,No改动'
 newObj.childArr.push('第二次修改,可以改动,freeze只冻结第一层')
 newObj.addNewChild = "第二次增加数据,No新增"
 newObj.childObj.addName = "对对象里层的数据修改,可以新增"
 console.log(newObj)
 // {foo: '第一次修改后的foo', childObj: {…}, childArr: Array(2), addChild: '增加的数据'}
 // childArr: (2) [0, '第二次修改,可以改动,freeze只冻结第一层']
 //childObj: {addName: '对对象里层的数据修改,可以新增'}

To make an object immutable, you can recursively freeze every property of type Object (deep freeze)

epilogue

The knowledge points still need to be clarified before they can be mastered. Only by learning can you make continuous progress.

Guess you like

Origin blog.csdn.net/weixin_45701199/article/details/132020562