JS专题: Object 重点详解

108 阅读3分钟

重要知识点:

属性

在对象中,属性名永远都是字符串。如果你使用 string(字面量)以外的其他值作为属性 名,那它首先会被转换为一个字符串。即使是数字也不例外,虽然在数组下标中使用的的 确是数字,但是在对象属性名中数字会被转换成字符串,所以当心不要搞混对象和数组中 数字的用法:

1. Object.assign()

浅复制, 会遍历一个或多个源对象的所有 可枚举的自有键, 然后把它们赋值到(使用=)目标对象, 最后返回目标对象

为什么我们说 Object.assign()其实是一个浅复制, 来看一组代码

let myJSON = {
	name: {
		Tom: [{ 1: 1 }, { 2: 2 }],
	},
	age: [{ 3: 3 }, { 4: 4 }],
};

let b = {};
Object.assign(b, myJSON);
b.name.Tom.length = 1; // 此时的 myJSON.name.Tom 也会被影响, 因为是浅复制
delete b.age; // 此时 myJSON.age 还会存在, 因为 b 和 myJSON 是两个不同的对象
console.log(b); // { name: { Tom: [ {1:1} ] } }
console.log(myJSON); // { name: { Tom: [ [{1:1}] ] }, age: [ { 3: 3 }, { 4: 4 } ] }

bmyJSON 是指向两个不同的 object 的指针, 但是他们里面的复杂对象(object or array), 这里是 name, age 则还是指向的同一个指针, 所以改变一个另一个也会跟这变. 但是,如果我们只改变最外层则不会受到影响, 因为 bmyJSON 还是两个不同的对象

2. 属性描述符

属性描述符是用来表示该对象内的属性的'配置'

Object.defineProperty( myObject, "a", {
	value: 2,
	writable: true,
	configurable: true,
	enumerable: true
	}
);

  1. value 是属性a对应的值
  2. writable 表示该属性是否可以修改(相当于是否有 setter)
  3. configurable 表示该属性的属性描述符是否可以配置, 相当于 是否可以用 defineProperty()来修改属性描述符, 同时如果configurable=flse, 该属性不能用 delete 删除

这里提一个面试的问题: obj.a = nulldelete obj.a 有什么区别???

答: 当 configurableflase 的时候如果 delete 语句, 那么还是不会删除,还依旧存在, 不会被垃圾回收. 但是, 如果是 obj.a =null 如果 writabletrue. 那么, 可以是被垃圾回收的

  1. enumerable 表示该属性是否是可枚举(在 for...in... , for...of... 的时候是否会被遍历到)

3. 属性不变性

  • 对象常量: 结合writable:falseconfigurable:false 可以创建一个真正的常量属性, 不能修改, 重定义, 删除
  • 禁止扩展:
    • Object.preventExtensions(obj), 当使用这个方法之后, 我们往 obj 里面添加属性, 也不会生效
    • Object.seal(obj) 会对obj 中的所有的现有对象调用 Object.preventExtensions(..), 所以在 seal() 之后不仅不能添加新属性, 也不能重新改写属性配置或者删除任何现有属性, 但是 如果 writable = true 则还能修改该属性值
    • Object.freeze(obj), 会创建一个冻结对象, 想当于调用了 Object.seal(obj) 并且, 属性的 writable = false;

举例:

var myObjcet = {
	a:2
};
Object.preventExtensions(myObject);
myObject.b =3;
myObject.b // undefined;

4. Object.hasOwnProperty()

  • 用来确定某个属性是否在该对象中, 不会检查[[Prototype]]链

5. in

  • in操作符会在可以通过对象访问指定属性时返回true, 无论该属性是在实例上还实在其原型链中
  • 属性在枚举顺序上不定
  • 在数组中[1,3,5,6], 遍历的是 0,1,2

是在原型上

6. Object.keys()

  • 只返回该实例对象上的 key, 而不会去找 原型对象 上的 key
  • 返回的枚举顺序不定