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 Object
instances of the type, and they all Object.prototype
inherit properties and methods from , although most properties will be shadowed or overridden, and Object
can 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
null
orundefined
, it creates and returns an empty object
- If the given value is
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 notsources
throw an error when the object value is null or undefinedconst 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 copiedconst 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)
orObject.create(proto, propertiesObject)
.
Object.create()
method is used to create a new object, using an existing object as a prototype for the newly created objectconst 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:
proto
Argument is null, or wrapper object基本类型包装对象
of primitive type other than对象
All primitive types except
null
andundefined
have their corresponding wrapper objectsname 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
null
by because it does notObject.prototype
inherit any object methods from .
And the lack ofObject.prototype.toString()
methods often makes debugging very difficultconst 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
null
on are often used asmap
a replacement for . BecauseObject.prototype
the existence of the prototype's own properties will cause some errorsconst 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
hasPerson
and 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.prototype
prototype methods can also prevent prototype pollution attacks. If a malicious scriptObject.prototype
adds 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.is
does 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.