🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 基本类型 string、number、boolean、null、undefined、object,除object外,其他5个均不是对象,即便`typeof null`结果为object。 ### 内置对象 String、Number、Boolean、Object、Function、Array、Date、RegExp、Error `"I am string"`本身不是对象,`"I am string" instanceof String`结果为false。获取长度、访问某个字符等字符串操作必须在String对象上操作,之所以我们能直接使用,是因为js内部帮我们将字符串转换成了String对象,Number同理。 ### 内容 obj[xx]中的xx永远是字符串,即便你传入的不是也会被转换成字符串: ``` var obj = {}; obj[true] = "foo"; obj[3] = "bar"; obj[obj] = "baz"; obj["true"]; //foo obj["3"]; //bar obj["[object Object]"]; baz ``` 你完全可以给数组绑定key value,并且可以通过key访问到value,也就是说你可以把数组当作一般对象使用(因为数组本身就是对象),但这不会影响到数组本身的数据(如果key是一个数字或字符串数字数组就会修改了): ``` var arr = [1, 2, 3]; arr.a = 4; arr.length; //3 arr.a; //4 arr["3"] = 99; //[1, 2, 3, 99] arr.length; //4 arr[3]; //99 ``` 潜复制:复制基本类型,引用类型仍然在引用 深复制:复制整个对象 ``` var obj1 = {}; var obj2 = {}; var obj = { a: 2, o1: obj1, o2: obj2 } var newObj = Object.assign({}, obj); newObj.o1 === obj1; //true newObj.o2 === obj2; //true ``` #### 属性描述 ``` var obj = {a: 2}; Object.getOwnPropertyDescriptor(obj, "a"); //{value: 2, writable: true, enumerable: true, configurable: true} ``` 你也可以使用Object.defineProperty来添加或修改属性,这个方法一般不会用到,除非修改writable(是否可以修改该属性)、enumerable(是否可以被枚举)、configurable(是否可以配置)。 ``` Object.defineProperty(obj, "a", {writable: false}); obj.a = 3; obj.a; //2 ``` ``` Object.defineProperty(obj, "a", {configurable: false}); Object.defineProperty(obj, "a", {configurable: true}); //TypeError,不可配,无法再修改了 delete obj.a; obj.a; //2 //不可配置的obj属性无法被删除 ``` ``` var obj = {a: 1, b: 2, c: 3} Object.defineProperty(obj, "b", {enumerable: false}); for(var key in obj) console.log(key); //a, c ``` #### 对象不变性 ``` //即便使用const,对于引用类型来说仅仅是地址不变而不是内容 const obj = {a: 2, foo: [1, 2, 3]}; obj.a = 3; obj.a; //3 obj.foo.push(4); obj.foo; //[1, 2, 3, 4] ``` 如何让a和foo不可变呢?答案是foo始终都是可变的,而a可以做到不可变 1. writable和configurable: ``` var obj = {}; Object.defineProperty(obj, "a", {value: 2, writable: false, configurable: false}); ``` 2. 禁止扩展 Object.preventExtensions ``` var obj = {a: 2}; Object.preventExtensions(obj); obj.b = 3; obj.b; //undefined ``` 3. 密封 Object.seal,相当于调用了preventExtensions并且把该对象的所有属性都设置了configurable为false 4. 冻结 Object.freeze,相当于调用了seal并且把该对象的所有属性都设置了writable为false #### Getter和Setter 使用了Getter或Setter后,js就会忽略该属性的value值以及writable是否为true,取而代之的是全部参考自getter和setter。也就是说,getter和setter会覆盖原本的对象取值和赋值操作。因此,它们两个最好是成对出现的,否则可能会出现意外行为。 ``` var obj = { get a() {return 2} } obj.a = 3; obj.a; //2 ``` ``` var obj = { get a() {return this._a] set a(v) {this._a = v * 2} } obj.a = 2; obj.a; //4 ``` #### 存在性 in:属性、原型链都会查找 hasOwnProperty:只会查找属性 二者均检查的是属性key,而不是value ``` 4 in [2, 4, 6]; //false //key是0, 1, 2 //enumerable为false并不影响in和hasOwnProperty的结果,它仅仅是不允许枚举 //Object.keys只会将可枚举的属性push var obj = { a: 1, b: 2 } Object.defineProperty(obj, 'a', {enumerable: false}); Object.keys(obj); //['b'] Object.getOwnPropertyNames(obj); //['a', 'b'] ``` ### 遍历 for...in...遍历的是key for...of...遍历的是value