##### Object 对象 ###### 1.1 Object 对象创建方式 ````js const obj = new Object() const foo = {} ```` ###### 1.2 Object.keys() ,Object.getOwnPropertyNames() ````js //Object.keys方法的参数是一个对象,返回一个数组。该数组的成员都是该对象自身的(而不是继承的)所有属性名。 //Object.getOwnPropertyNames方法与Object.keys类似,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名,还返回不可枚举的属性名(Symbol) const obj = { name: 'james', age: 22 } console.log(Object.keys(obj)) // ['name', 'age'] console.log(Object.getOwnPropertyNames(obj)) //['name', 'age'] //以下代码结果大不相同 const obj = { name: "james", age: 22, }; Object.defineProperty(obj, "height", { configurable: true, value: 18, writable: true, enumerable: false }) console.log(Object.keys(obj)) // ['name', 'age'] console.log(Object.getOwnPropertyNames(obj)) // ['name', 'age', 'height'] //获取对象属性值可以采用length console.log(Object.keys(obj).length) //2 console.log(Object.getOwnPropertyNames(obj).length) //3 ```` ###### 1.3 Object.defineProperty() ````js //通过描述对象,定义某个属性 (对象属性是否遍历 可以删除 能否赋值) //Object.defineProperty(对象, 对象属性key, 属性描述) const obj = {} Object.defineProperty(obj, "name", { configurable: true, //true 表示属性可以被删除 默认为false value: "james" ,//属性值 默认为undefined writable: true, //值是否可以被修改 默认为false enumerable: true, //是否可以遍历 枚举 默认false }) ```` ###### 1.4 Object.defineProperties() ````js //通过描述对象,定义多个属性。 const obj = {} Object.defineProperties(obj, { name: { configurable: true, value: "james", writable: true, enumerable: true }, age: { configurable: true, value: 22, writable: true, enumerable: false } }) console.log(obj)// {name: 'james', age: 22} console.log(Object.keys(obj)) //['name'] ```` ###### 1.5 Object.getOwnPropertyDescriptor() ````js //获取对象某个属性的描述对象 const obj = { name: "james", age: 22, }; console.log(Object.getOwnPropertyDescriptor(obj, "name")) /* *{ configurable: true enumerable: true value: "james" writable: true } */ ```` ###### 1.6 Object.getOwnPropertyDescriptors(obj) ````js //方法用来获取一个对象的所有自身属性的描述符。 和 Object.defineProperties() 是不是刚好相反啊 const obj = { name: "james", age: 22, }; console.log(Object.getOwnPropertyDescriptors(obj))//自己打印看看吧 ```` ##### 2 控制对象状态的方法** ###### 2.1 Object.preventExtensions() ````js //让一个对象变的不可扩展,也就是永远不能再添加新的属性。 其规则不可以增加新的属性,但是可以对原有属性进行重新赋值,删除 const obj = { name: "james", age: 22 } Object.preventExtensions(obj) obj.height = 1.98 obj.sno = 0x100 console.log(obj) // {name: 'james', age: 22} //Object.preventExtensions()仅阻止添加自身的属性。但其对象类型的原型依然可以添加新的属性。 obj.__proto__.height = 1.98 console.log(obj.__proto__) //可自行打印 ```` ###### 2.2 Object.seal() ````js //阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变 //等于调用 Object.preventExtensions() ,之后将configurable设置为false //即: 不能增加新属性 不能删除属性 只能修改现有属性值 const obj = { name: "james", age: 22 } Object.seal(obj) obj.height = 1.98 obj.sno = 0x100 delete obj.name delete obj.age obj.name = "lilei" console.log(obj) //{name: 'lilei', age: 22} ```` ###### 2.3 Object.freeze() ````js //被冻结对象自身的所有属性都不可能以任何方式被修改 //等于调用 Object.preventExtensions() ,之后将configurable设置为false, writable设置为false const obj = { name: "james", age: 22 } Object.freeze(obj) //改不了了 ```` ###### 2.4 Object.isFrozen() ````js //判断一个对象是否被冻结 const obj = { name: "james", age: 22 } console.log(Object.isFrozen(obj)) //false console.log(Object.isFrozen(Object.preventExtensions({}))) //true //或者 const o = {} Object.defineProperties(o, { name: { configurable: false, //必须的 value: "james", writable: false, //必须的 enumerable: true }, age: { configurable: false, //必须的 value: 28, writable: false, //必须的 enumerable: true }, }) Object.preventExtensions(o) //必须的 console.log(Object.isFrozen(o)) //true ```` ###### 2.5 Object.isSealed() ````js // 方法判断一个对象是否被密封。 如果这个对象是密封的,则返回 true,否则返回 false。密封对象是指那些不可 扩展 的,且所有自身属性都不可配置且因此不可删除(但不一定是不可写)的对象。 //即: Object.preventExtensions() 和configurable为false const obj = { name: "james", age: 22 } Object.preventExtensions(obj) console.log(Object.isSealed(obj)) //false Object.seal(obj) console.log(Object.isSealed(obj)) //true Object.freeze(obj) console.log(Object.isSealed(obj)) //true ```` ###### 2.6 Object.isExtensible() ````js // 判断一个对象是否是可扩展的(是否可以在它上面添加新的属性) // 新对象默认是可扩展的. const obj = {} Object.preventExtensions(obj) Object.seal(obj) Object.freeze(obj) console.log(Object.isExtensible(obj)) //false ```` ##### 3.Object 的实例方法 ###### 3.1 Object.prototype.valueOf() ````js //回指定对象的原始值 //引入MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf // Object:返回对象本身 var obj = {name: "张三", age: 18}; console.log( obj.valueOf() === obj ); // true // Array:返回数组对象本身 var array = ["ABC", true, 12, -5]; console.log(array.valueOf() === array); // true // Date:当前时间距1970年1月1日午夜的毫秒数 var date = new Date(2013, 7, 18, 23, 11, 59, 230); console.log(date.valueOf()); // 1376838719230 // Number:返回数字值 var num = 15.26540; console.log(num.valueOf()); // 15.2654 // 布尔:返回布尔值true或false var bool = true; console.log(bool.valueOf() === bool); // true var obj = new Object(); obj.valueOf = function () { return 2; }; 1 + obj // 3 ```` ###### 3.2 Object.prototype.toString() ````js //MDN 每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。以下代码说明了这一点: var o = new Object(); o.toString(); // 返回 [object Object] //常用类型检查对象 var toString = Object.prototype.toString; toString.call(new Date); // [object Date] toString.call(new String); // [object String] toString.call(Math); // [object Math] //Since JavaScript 1.8.5 toString.call(undefined); // [object Undefined] toString.call(null); // [object Null] toString.call([]) // [object Array] //上面代码调用空对象的toString方法,结果返回一个字符串object Object,其中第二个Object表示该值的构造函数 数值:返回[object Number]。 字符串:返回[object String]。 布尔值:返回[object Boolean]。 undefined:返回[object Undefined]。 null:返回[object Null]。 数组:返回[object Array]。 arguments 对象:返回[object Arguments]。 函数:返回[object Function]。 Error 对象:返回[object Error]。 Date 对象:返回[object Date]。 RegExp 对象:返回[object RegExp]。 其他对象:返回[object Object]。 ```` ###### 3.3 Object.prototype.toLocaleString() ````js //Object.prototype.toLocaleString方法与toString的返回结果相同,也是返回一个值的字符串形式。 ```` ###### 3.4 Object.prototype.hasOwnProperty() ````js // 回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键) //自身属性和继承属性的区别: const obj = { name: "james", age: 20 } obj.__proto__.height = 1.98 console.log(obj.hasOwnProperty("name")) //true console.log(obj.hasOwnProperty("height")) //false //例如 var foo = { hasOwnProperty: function() { return false; }, bar: 'Here be dragons' }; foo.hasOwnProperty('bar'); // 始终返回 false / 如果担心这种情况, // 可以直接使用原型链上真正的 hasOwnProperty 方法 ({}).hasOwnProperty.call(foo, 'bar'); // true // 也可以使用 Object 原型上的 hasOwnProperty 属性 Object.prototype.hasOwnProperty.call(foo, 'bar'); // true //MDN 链接https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty ```` ###### 3.5 Object.values() ````js //方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 ) const obj = { name: "james", age: 20 } obj.__proto__.height = 1.98 console.log(Object.values(obj)) // ['james', 20] ```` ###### 3.6 Object.entries() ````js //返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组 //Symbol除外 const s1 = Symbol("sym") const obj = { name: "james", age: 20, [s1]: "我是symbol" } obj.__proto__.height = 1.98 console.log(Object.entries(obj)) //[ ["name", "james"], ["age", 20] ] //Object.entries方法的另一个用处是,将对象转为真正的Map结构。 const map = new Map(Object.entries(obj)) console.log(map) // Map(2) {'name' => 'james', 'age' => 20} ```` ###### 3.7 Object.fromEntries() ````js //是Object.entries()的逆操作,用于将一个键值对数组转为对象。 //该方法的主要目的,是将键值对的数据结构还原为对象,因此特别适合将 Map 结构转为对象。 const obj = { name: "james", age: 20, [s1]: "我是symbol" } console.log( Object.fromEntries(Object.entries(obj))) console.log( Object.fromEntries(map)) ```` ###### 3.8 Object.assign() ````js //用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。 浅拷贝 // 属性名为 Symbol 值的属性,也会被Object.assign()拷贝。 // 只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false) // 同名属性的替换 const s1 = Symbol("sym"); const obj = { name: "james", age: 20, [s1]: "我是symbol", }; obj.__proto__.height = 1.98; const foo = Object.assign(obj, { color: "red" },{ color: "blue"}); console.log(foo);// {name: 'james', age: 20, color: 'blue', Symbol(sym): '我是symbol'} ```` ###### 3.9 Object.is() ````js //ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。 // 判断两个值是否为同一个值。 对象和NaN 可以很好判断了 console.log(Object.is(null, null)) //true console.log(Object.is({}, {})) //false const a = {} const b = Object.assign(a, {}) console.log(Object.is(a, b)) //true console.log(Object.is(NaN, NaN)) //true ```` ###### 3.10 Object.setPrototypeOf() ````js // 用来设置一个对象的原型对象(prototype),返回参数对象本身 const obj = { name: "james" } const foo = Object.setPrototypeOf({}, obj) console.log(foo.name) //james ```` ###### 3.11 Object.getPrototypeOf() ````js //用于读取一个对象的原型对象 console.log(Object.getPrototypeOf(foo)) //{name: 'james'} ```` ###### 3.12 Object.create() ````js //创建一个新对象,使用现有的对象来提供新创建的对象的__proto__ const obj = { name: "james" } const foo = Object.create(obj, { age: { configurable: true, value: 22, writable: true, enumerable: true } }) console.log(foo) // {age: 22} console.log(foo.name) //james ```` ###### 3.13 Object.prototype.isPrototypeOf() ````js // 用来判断该对象是否为参数对象的原型 const obj = { name: "james" } const foo = Object.create(obj, { age: { configurable: true, value: 22, writable: true, enumerable: true } }) console.log(obj.isPrototypeOf(foo)) //true ```` ###### 3.14 Object.getOwnPropertySymbols() ````js // 方法返回一个给定对象自身的所有 Symbol 属性的数组 const s1 = Symbol("s1") const obj = { name: "james", [s1]: "symbol" } console.log(Object.getOwnPropertySymbols(obj))// [Symbol(s1)] console.log(Object.getOwnPropertyNames(obj))//['name'] ````