Object() 对象内置类(每一个对象都是它的实例)
通过在控制台中打印查看Object中提供的方法和属性,使用时直接Object.XXX来调用Object上的属性和方法。
Object
//控制台输出:ƒ Object() { [native code] }
dir(Object)
//控制台输出:ƒ Object() -- 展开如下
/*
arguments: (...)
assign: ƒ assign()
caller: (...)
create: ƒ create()
defineProperties: ƒ defineProperties()
defineProperty: ƒ defineProperty()
entries: ƒ entries()
freeze: ƒ freeze()
fromEntries: ƒ fromEntries()
getOwnPropertyDescriptor: ƒ getOwnPropertyDescriptor()
getOwnPropertyDescriptors: ƒ getOwnPropertyDescriptors()
getOwnPropertyNames: ƒ getOwnPropertyNames()
getOwnPropertySymbols: ƒ getOwnPropertySymbols()
getPrototypeOf: ƒ getPrototypeOf()
is: ƒ is()
isExtensible: ƒ isExtensible()
isFrozen: ƒ isFrozen()
isSealed: ƒ isSealed()
keys: ƒ keys()
length: 1
name: "Object"
preventExtensions: ƒ preventExtensions()
prototype: {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
seal: ƒ seal()
setPrototypeOf: ƒ setPrototypeOf()
values: ƒ values()
__proto__: ƒ ()
[[Scopes]]: Scopes[0]
*/
- Object上常用的方法有: assign、create、defineProperty、entries、freeze、keys…… 在MDN网站上查看这些常用方法的用法
1.1 Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Object.assign(target, …sources)
- target:目标对象。/ sources:源对象。
- 返回值:目标对象。
let target = { a: 1, b: 2 };
let source = { b: 4, c: 5 };
let result = Object.assign(target, source, { c: 6, d: 7 });
console.log(target);//{ a: 1, b: 4, c: 6, d: 7 }
console.log(source);//{ b: 4, c: 5 }
console.log(result);//{ a: 1, b: 4, c: 6, d: 7 }
1.2 Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
Object.create(proto)
- proto:新创建对象的原型对象。
- 返回值:一个新对象,带着指定的原型对象和属性。
let obj = {};
let newObj = Object.create(obj);
console.log(newObj.__proto__ === obj);//true
1.3 Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
tip:应当直接在 Object 构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用。
Object.defineProperty(obj, prop, descriptor)
- obj:要定义属性的对象。
- prop:要定义或修改的属性的名称或 Symbol 。
- descriptor:要定义或修改的属性描述符。
- 返回值:被传递给函数的对象。
在ES6中,由于 Symbol类型的特殊性,用Symbol类型的值来做对象的key与常规的定义或修改不同,而Object.defineProperty 是定义key为Symbol的属性的方法之一。
【描述】该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for…in 或 Object.keys 方法),可以改变这些属性的值,也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)的。
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。
这两种描述符都是对象。它们共享以下可选键值(默认值是指在使用 Object.defineProperty() 定义属性时的默认值):
- configurable
当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
默认为 false。 - enumerable
当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。
默认为 false。
数据描述符还具有以下可选键值: - value
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。
默认为 undefined。 - writable
当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。
默认为 false。
存取描述符还具有以下可选键值: - get
属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。
默认为 undefined。 - set
属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
默认为 undefined。
let obj = {
name:'cat'
};
//给一个对象obj添加一个属性名为age,属性值为2,
Object.defineProperty(obj, 'age', {
value: 2,
writable: false,//不可改写的
enumerable: true//可枚举的
});
console.log(1, obj);//1 { name: 'cat', age: 2 }
//因为writable为false,所以不可修改
obj.age = 3;
console.log(2, obj);//2 { name: 'cat', age: 2 }
for(let key in obj){
console.log(key);
}
/*
name
age
*/
//----------------------------
//如果可枚举属性enumerable设置为false
let obj = {
name:'cat'
};
Object.defineProperty(obj, 'age', {
value: 2,
writable: false,//不可改写的
enumerable: false//不可枚举的
});
for(let key in obj){
console.log(key);
}
/*
name --只会输出可枚举的属性name
*/
//----------------------------
var obj = {}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(obj, "a", {
value: 10,
writable: true,
enumerable: true,
configurable: true
});
Object.defineProperty(obj, "b", {
// 使用了方法名称缩写(ES2015 特性)
// 下面两个缩写等价于:
// get : function() { return bValue; },
// set : function(newValue) { bValue = newValue; },
//获取值的时候可以做的事情,在set函数中
get() { console.log('get获取值') },
set(newValue) { console.log('set设置值' + newValue) },
enumerable: true,
configurable: true
});
//在控制台操作如下
obj;//=>{a: 10}
obj.b=22;//设置值的时候执行的函数打印出"set设置值22",此函数接收的参数就是实际操作中设置的值
obj.b;//获取值的时候执行的get函数中的操作:打印出 “get获取值”
obj.b=30;//=>执行set函数打印出“set设置值30”
obj.b;//获取值的时候执行的get函数中的操作:打印出 “get获取值”
1.4 Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for…in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
Object.entries(obj)
- obj:可以返回其可枚举属性的键值对的对象。
- 返回值:给定对象自身可枚举属性的键值对数组。
Object.entries()返回一个数组,其元素是与直接在object上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。
let obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
// array like object
let obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
// array like object with random key ordering
let anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj));//[ [ '2', 'b' ], [ '7', 'c' ], [ '100', 'a' ] ]
//for in循环
let obj = { foo: 'bar', baz: 42, 100: 'a', 10: 'b', 20: 'c' };
for (let key in obj) {
console.log(key + '--' + obj[key]);
}
/*
10--b
20--c
100--a
foo--bar
baz--42
1.5 Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
Object.freeze(obj)
- obj:要被冻结的对象。
- 返回值:被冻结的对象。
【描述】被冻结对象自身的所有属性都不可能以任何方式被修改。任何修改尝试都会失败,无论是静默地还是通过抛出TypeError异常(最常见但不仅限于strict mode)。
数据属性的值不可更改,访问器属性(有getter和setter)也同样(但由于是函数调用,给人的错觉是还是可以修改这个属性)。如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。数组作为一种对象,被冻结,其元素不能被修改。没有数组元素可以被添加或移除。
这个方法返回传递的对象,而不是创建一个被冻结的副本。
let obj = { name: 'dog', age: 1 }
Object.freeze(obj);
obj.age = 2;
console.log(obj.age);//1
//严格模式下会报错
"use strict"
let obj = { name: 'dog', age: 1 }
Object.freeze(obj);
obj.age = 2;// Uncaught TypeError: Cannot assign to read only property 'age' of object '#<Object>'
console.log(obj.age);//1
1.6 Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
Object.keys(obj)
- obj:要返回其枚举自身属性的对象。
- 返回值:一个表示给定对象的所有可枚举属性的字符串数组。
【描述】Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']
1.7 Object.is() 方法判断两个值是否是相同的值。
Object.is(value1, value2);
- value1:第一个需要比较的值。
- value2:第二个需要比较的值。
- 返回值:表示两个参数是否相同的布尔值 。
【描述】Object.is() 判断两个值是否相同。如果下列任何一项成立,则两个值相同:
两个值都是 undefined
两个值都是 null
两个值都是 true 或者都是 false
两个值是由相同个数的字符按照相同的顺序组成的字符串
两个值指向同一个对象
两个值都是数字并且
都是正零 +0
都是负零 -0
都是 NaN
都是除零和 NaN 外的其它同一个数字
这种相等性判断逻辑和传统的 == 运算不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 “” == false 等于 true 的现象),但 Object.is 不会做这种类型转换。
这与 === 运算符的判定方式也不一样。=== 运算符(和== 运算符)将数字值 -0 和 +0 视为相等,并认为 Number.NaN 不等于 NaN。
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
Object.is(NaN, NaN); // true