方法列表

assign

Object.assign 方法将所有可枚举(Object.propertyIsEnumerable() 返回 true)和自有(Object.hasOwnProperty() 返回 true)属性从一个或多个源对象复制到目标对象,返回修改后的对象

如果目标对象与源对象具有相同的 key,则目标对象中的属性将被源对象中的属性覆盖,后面的源对象的属性将类似地覆盖前面的源对象的属性

参数说明

  1. assign (
  2. target: object,
  3. ...source: object[],
  4. ) return target // 目标对象
参数名 是否必填 类型 说明
target object 目标对象,接收源对象属性的对象,也是修改后的返回值
…source object[] 源对象,包含将被合并的属性

示例

复制对象与合并对象
  1. // 复制对象
  2. const obj = { a: 1 };
  3. const copy = Object.assign({}, obj);
  4. console.log(copy); // { a: 1 }
  5. // 合并对象
  6. const o1 = { a: 1 };
  7. const o2 = { b: 2 };
  8. const o3 = { c: 3 };
  9. const obj = Object.assign(o1, o2, o3);
  10. console.log(obj); // { a: 1, b: 2, c: 3 }
  11. console.log(o1); // { a: 1, b: 2, c: 3 }

如果 source 的属性是一个引用值,则他只会复制其引用值
  1. const target = {}
  2. const source = { numbers: [1, 2, 3, 4, 5] }
  3. Object.assign(target, source)
  4. source.numbers.push(6)
  5. console.log(target) // [1, 2, 3, 4, 5, 6]
  6. console.log(source) // [1, 2, 3, 4, 5, 6]

原型链上的属性和不可枚举属性不能被复制
  1. const obj = Object.create(
  2. {}, // 这里是 obj 的 prototype
  3. {
  4. name: {
  5. value: 'obj',
  6. },
  7. type: {
  8. value: 'object',
  9. enumerable: true,
  10. },
  11. },
  12. )
  13. const newObj = Object.assign({}, obj)
  14. console.log(newObj) // { type: 'object' }

create

Object.create 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)

参数说明

  1. create (
  2. proto: object | null
  3. propertiesObject: object
  4. ) return object // 带着指定的原型对象及其属性
参数名 是否必填 类型 说明
proto object | null 新创建对象的原型对象
propertiesObject object 如果该参数被指定且不为 undefined,则该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。这些属性对应于
Object.defineProperties 的第二个参数

示例

正常的创建一个对象

  1. const obj = Object.create(
  2. Object.prototype,
  3. {
  4. name: {
  5. value: 'obj',
  6. writable: true,
  7. enumerable: true,
  8. configurable: true,
  9. }
  10. }
  11. )
  12. console.log(obj) // { name: 'obj' }

使用 null 作为 proto 创建对象

并不推荐这样使用,如果使用null作为原型,会产生许多问题

  1. const normalObj = {};
  2. const nullProtoObj = Object.create(null)
  3. console.log("normalObj is: " + normalObj); // "normalObj is: [object Object]"
  4. console.log("nullProtoObj is: " + nullProtoObj); // 报错 Cannot convert object to primitive value,因为没有继承到 Object.prototype.toString 方法

巧用

Object.create 可以使用在构造函数继承上

  1. function Shape() {
  2. this.x = 0;
  3. this.y = 0;
  4. }
  5. Shape.prototype.move = function(x, y) {
  6. this.x += x;
  7. this.y += y;
  8. console.info('Shape moved.');
  9. };
  10. function Rectangle() {
  11. Shape.call(this);
  12. }
  13. Rectangle.prototype = Object.create(Shape.prototype);
  14. Rectangle.prototype.constructor = Rectangle;
  15. const rect = new Rectangle();
  16. console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true
  17. console.log('Is rect an instance of Shape?', rect instanceof Shape); // true
  18. rect.move(1, 1); // 'Shape moved.'

defineProperty

Object.defineProperty 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for...inObject.keys 方法),可以改变这些属性的值,也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty 添加的属性值是不可修改(immutable)的

参数说明

  1. defineProperty (
  2. obj: object,
  3. prop: string | Symbol,
  4. descriptor: object // 属性描述符
  5. ) return object // 被传递给函数的对象
参数名 是否必填 类型 说明
obj object 要定义属性的对象
prop string | Symbol 要定义或修改的属性的名称或 Symbol
descriptor object 要定义或修改的属性描述符

prop 属性描述符

  1. descriptor {
  2. value: any, // 属性对应的值 默认为 undefined
  3. writable: boolean, // 是否可写 默认为 false
  4. enumerable: boolean, // 是否可枚举 默认为 false
  5. configurable: boolean, // 是否可配置 默认为 false
  6. get: function, // 访问此属性时调用的函数 默认为 undefined
  7. set: function, // 设置此属性是调用的函数 默认为 undefined
  8. }
  9. get () return any
  10. set (
  11. value: any // 设置时传入的值
  12. ) return any

如果一个描述符不具有 valuewritablegetset 中的任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有 valuewritablegetset 键,则会产生一个异常

也就是说 当 valuewritable 存在时,不能同时设置 getset

示例

创建一个常规对象 (可枚举,可配置,可写)
  1. var o = {}; // 创建一个新对象
  2. // 在对象中添加一个属性与数据描述符的示例
  3. Object.defineProperty(o, "a",
  4. {
  5. value: 37,
  6. writable: true,
  7. enumerable: true,
  8. configurable: true
  9. }
  10. );
  11. console.log(o) // { a: 37 }
  12. // 使用 get 和 set 写法
  13. // 在对象中添加一个设置了存取描述符属性的示例
  14. var bValue = 38;
  15. Object.defineProperty(o, "b", {
  16. // 使用了方法名称缩写(ES2015 特性)
  17. // 下面两个缩写等价于:
  18. get() { return bValue; },
  19. set(newValue) { bValue = newValue; },
  20. enumerable : true,
  21. configurable : true
  22. });
  23. // 数据描述符和存取描述符不能混合使用
  24. Object.defineProperty(o, "conflict", {
  25. value: 0x9f91102,
  26. get() { return 0xdeadbeef; }
  27. });
  28. // 抛出错误 TypeError: value appears only in data descriptors, get appears only in accessor descriptors

创建一个不可写属性 writable: false
  1. var o = {};
  2. Object.defineProperty(o, "a",
  3. {
  4. value: 37,
  5. writable: false,
  6. enumerable: true,
  7. configurable: true
  8. }
  9. );
  10. o.a = 99
  11. // 这里不会报错 但值也不会更改
  12. console.log(o) // { a: 37 }

创建一个不可枚举属性 enumerable: false
  1. var o = {}
  2. // enumerable 的默认值是 false 这里为了更好区分所以手写一下
  3. Object.defineProperty(o, 'a', { value: 1, enumerable: true })
  4. Object.defineProperty(o, 'b', { value: 2, enumerable: false })
  5. Object.defineProperty(o, 'c', { value: 3, enumerable: true })
  6. for (const k in o) {
  7. console.log(k, o[k])
  8. /**
  9. * 这里 2 并没有打印出来
  10. * a 1
  11. * c 3
  12. */
  13. }

关于这点其实 chrome 的控制台可以非常容易的看到

不可枚举的属性颜色要比别的属性淡些

创建一个不可枚举属性 configurable: false

其实也可以简单理解成是 不可删除的

  1. var o = {}
  2. Object.defineProperty(o, 'a', { value: 1, configurable: true })
  3. Object.defineProperty(o, 'b', { value: 2, configurable: false })
  4. Object.defineProperty(o, 'c', { value: 3, configurable: true })
  5. console.log(o) // { a: 1, b: 2, c: 3 }
  6. delete o.a
  7. delete o.b
  8. delete o.c
  9. console.log(o) // { b: 2 }

defineProperties

Object.defineProperties 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象

Object.defineProperties 本质上定义了 obj 对象上 props 的可枚举属性相对应的所有属性

也可以理解成 Object.defineProperty 的批发版

参数说明

  1. defineProperties (
  2. obj: object,
  3. props: object, // 就像是对象描述符的集合,键名对应属性名
  4. ) return object // 被传递给函数的对象
参数名 是否必填 类型 说明
obj object 在其上定义或修改属性的对象
props object 要定义其可枚举属性或修改的属性描述符的对象。对象中存在的属性描述符主要有两种:数据描述符和访问器描述符(更多详情,请参阅 Object.defineProperty

示例

  1. var obj = {};
  2. Object.defineProperties(obj, {
  3. 'property1': {
  4. value: true,
  5. writable: true
  6. },
  7. 'property2': {
  8. value: 'Hello',
  9. writable: false
  10. }
  11. });
  12. console.log(obj) // { property1: true, property2: 'Hello' }

entries

Object.entries 方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)

Object.entries 返回一个数组,其元素是与直接在 object 上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同

参数说明

  1. entries (
  2. obj: object
  3. ) return array // 自身可枚举属性的键值对数组
参数名 是否必填 类型 说明
obj object 可以返回其可枚举属性的键值对的对象

示例

正常使用
  1. const obj = { foo: 'bar', baz: 42 };
  2. console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
  3. const obj = { 0: 'a', 1: 'b', 2: 'c' };
  4. console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

使用 for in 循环
  1. // 使用 for in 循环
  2. const obj = { a: 5, b: 7, c: 9 };
  3. for (const [key, value] of Object.entries(obj)) {
  4. console.log(`${key} ${value}`);
  5. /**
  6. * a 5
  7. * b 7
  8. * c 9
  9. */
  10. }

同时 forEach 也可以使用
  1. const obj = { a: 5, b: 7, c: 9 };
  2. Object.entries(obj).forEach(([key, value]) => {
  3. console.log(`${key} ${value}`);
  4. /**
  5. * a 5
  6. * b 7
  7. * c 9
  8. */
  9. });

freeze

Object.freeze 方法可以冻结一个对象,返回和传入的参数相同的对象,一个被冻结的对象具有以下特点

  • 不能添加新的属性
  • 不能删除已有的属性
  • 不能修改已有属性的可枚举性、可配置性、可写性
  • 不能修改已有属性的值
  • 不能修改该对象的原型

参数说明

  1. freeze (
  2. obj: object
  3. ) return object // 被冻结之后的对象
参数名 是否必填 类型 说明
obj object 要被冻结的对象

示例

冻结对象

在严格模式下给已冻结的对象进行增删改操作会报错

  1. var obj = {
  2. prop: function () { },
  3. foo: 'bar'
  4. };
  5. // 新的属性会被添加,已存在的属性可能
  6. // 会被修改或移除
  7. obj.foo = 'baz';
  8. obj.lumpy = 'woof';
  9. delete obj.prop;
  10. console.log(obj) // { foo: 'baz', lumpy: 'woof' }
  11. // 作为参数传递的对象与返回的对象都被冻结
  12. // 所以不必保存返回的对象(因为两个对象全等)
  13. var o = Object.freeze(obj);
  14. o === obj; // true
  15. Object.isFrozen(obj); // true
  16. // 现在任何改变都会失效
  17. obj.foo = 'quux'; // 静默地不做任何事
  18. // 静默地不添加此属性
  19. obj.quaxxor = 'the friendly duck';
  20. console.log(obj ) // { foo: 'baz', lumpy: 'woof' }
  21. // 在严格模式,如此行为将抛出 TypeErrors
  22. function fail() {
  23. 'use strict';
  24. obj.foo = 'sparky'; // throws a TypeError
  25. delete obj.quaxxor; // 返回 true,因为 quaxxor 属性从来未被添加
  26. obj.sparky = 'arf'; // throws a TypeError
  27. }
  28. fail();
  29. // 试图通过 Object.defineProperty 更改属性
  30. // 下面两个语句都会抛出 TypeError.
  31. Object.defineProperty(obj, 'ohai', { value: 17 });
  32. Object.defineProperty(obj, 'foo', { value: 'eit' });
  33. // 也不能更改原型
  34. // 下面两个语句都会抛出 TypeError.
  35. Object.setPrototypeOf(obj, { x: 20 })
  36. obj.__proto__ = { x: 20 }

冻结数组
  1. let a = [0];
  2. Object.freeze(a); // 现在数组不能被修改了。
  3. a[0] = 1; // 静默不做任何事
  4. a.push(2); // 报错
  5. // 在严格模式下会报错
  6. function fail() {
  7. "use strict"
  8. a[0] = 1; // 报错
  9. a.push(2); // 报错
  10. }
  11. fail();

巧用

深冻结

冻结数组并不是深冻结的,当一个数组里面的属性属于引用值时,这个属性的值并不能同时被冻结

  1. obj = {
  2. internal: {}
  3. };
  4. Object.freeze(obj);
  5. obj.internal.a = 'aValue';
  6. obj1.internal.a // 'aValue'

所以我们需要去实现一个深度冻结函数

  1. // 深冻结函数。
  2. function deepFreeze(obj) {
  3. // 取回定义在 obj 上的属性名
  4. var propNames = Object.getOwnPropertyNames(obj);
  5. // 在冻结自身之前冻结属性
  6. propNames.forEach(function(name) {
  7. var prop = obj[name];
  8. // 如果 prop 是个对象,冻结它
  9. if (typeof prop == 'object' && prop !== null)
  10. deepFreeze(prop);
  11. });
  12. // 冻结自身 (no-op if already frozen)
  13. return Object.freeze(obj);
  14. }
  15. obj2 = {
  16. internal: {}
  17. };
  18. deepFreeze(obj2);
  19. obj2.internal.a = 'anotherValue';
  20. obj2.internal.a; // undefined

getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

该方法允许对一个属性的描述进行检索。在 Javascript 中, 属性 由一个字符串类型的“名字”(name)和一个“属性描述符”(property descriptor)对象构成

参数说明

  1. getOwnPropertyDescriptor (
  2. obj: object,
  3. prop: string,
  4. ) return object | undefiend // 如果存在则返回对象属性的描述符 反之返回 undefined
参数名 是否必填 类型 说明
obj object 需要查找的目标对象
prop string 目标对象内属性名称

示例

  1. var o, d;
  2. o = { get foo() { return 17; } };
  3. d = Object.getOwnPropertyDescriptor(o, "foo");
  4. // d {
  5. // configurable: true,
  6. // enumerable: true,
  7. // get: /*the getter function*/,
  8. // set: undefined
  9. // }
  10. o = { bar: 42 };
  11. d = Object.getOwnPropertyDescriptor(o, "bar");
  12. // d {
  13. // configurable: true,
  14. // enumerable: true,
  15. // value: 42,
  16. // writable: true
  17. // }
  18. o = {};
  19. Object.defineProperty(o, "baz",
  20. {
  21. value: 8675309,
  22. writable: false,
  23. enumerable: false
  24. }
  25. )
  26. d = Object.getOwnPropertyDescriptor(o, "baz");
  27. // d {
  28. // value: 8675309,
  29. // writable: false,
  30. // enumerable: false,
  31. // configurable: false
  32. // }

getOwnPropertyNames

Object.getOwnPropertyNames 方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组

Object.getOwnPropertyNames 返回一个数组,该数组对元素是 obj 自身拥有的枚举或不可枚举属性名称字符串。 数组中枚举属性的顺序与通过 for in 循环(或 Object.keys)迭代该对象属性时一致。数组中不可枚举属性的顺序未定义

参数说明

  1. getOwnPropertyNames (
  2. obj: object,
  3. ) return string // 在给定对象上找到的自身属性对应的字符串数组
参数名 是否必填 类型 说明
obj object 一个对象,其自身的可枚举和不可枚举属性的名称被返回

示例

  1. var arr = ["a", "b", "c"];
  2. console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
  3. // 类数组对象
  4. var obj = { 0: "a", 1: "b", 2: "c"};
  5. console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
  6. // 使用 Array.forEach 输出属性名和属性值
  7. Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
  8. console.log(val + " -> " + obj[val]);
  9. });
  10. // 输出
  11. // 0 -> a
  12. // 1 -> b
  13. // 2 -> c
  14. // 不可枚举属性
  15. var my_obj = Object.create({}, {
  16. getFoo: {
  17. value: function() { return this.foo; },
  18. enumerable: false
  19. }
  20. });
  21. my_obj.foo = 1;
  22. console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

此方法不会获取到 prototype 上的属性

  1. function ParentClass() {}
  2. ParentClass.prototype.inheritedMethod = function() {};
  3. function ChildClass() {
  4. this.prop = 5;
  5. this.method = function() {};
  6. }
  7. ChildClass.prototype = new ParentClass;
  8. ChildClass.prototype.prototypeMethod = function() {};
  9. console.log(
  10. Object.getOwnPropertyNames(
  11. new ChildClass() // ["prop", "method"]
  12. )
  13. );

getOwnPropertySymbols

Object.getOwnPropertySymbols 方法返回一个给定对象自身的所有 Symbol 属性的数组

Object.getOwnPropertyNames 类似,您可以将给定对象的所有符号属性作为 Symbol 数组获取。 请注意,Object.getOwnPropertyNames 本身不包含对象的 Symbol 属性,只包含字符串属性。

因为所有的对象在初始化的时候不会包含任何的 Symbol,除非你在对象上赋值了 Symbol 否则 Object.getOwnPropertySymbols 只会返回一个空的数组。

一个很好的例子 Array 的迭代器就是一个 Symbol

但是打印 Array[Symbol.iterator] 的时候会显示 undefined

打印 [][Symbol.iterator] 则会出出现对应的函数

参数说明

  1. getOwnPropertySymbols (
  2. obj: object
  3. ) return array // 在给定对象自身上找到的所有 Symbol 属性的数组
参数名 是否必填 类型 说明
obj object 要返回 Symbol 属性的对象

示例

  1. var obj = {};
  2. var a = Symbol("a");
  3. var b = Symbol.for("b");
  4. obj[a] = "localSymbol";
  5. obj[b] = "globalSymbol";
  6. var objectSymbols = Object.getOwnPropertySymbols(obj);
  7. console.log(objectSymbols.length); // 2
  8. console.log(objectSymbols) // [Symbol(a), Symbol(b)]
  9. console.log(objectSymbols[0]) // Symbol(a)

getPrototyoeOf

Object.getPrototypeOf 方法返回指定对象的原型(内部[[Prototype]]属性的值)。

参数说明

  1. getPrototypeOf (
  2. obj: object
  3. ) return object | null // 给定对象的原型。如果没有继承属性,则返回 null
参数名 是否必填 类型 说明
obj object 要返回其原型的对象

示例

  1. var proto = {};
  2. var obj = Object.create(proto);
  3. Object.getPrototypeOf(obj) === proto; // true
  4. var reg = /a/;
  5. Object.getPrototypeOf(reg) === RegExp.prototype; // true

is

Object.is 方法判断两个值是否为同一个值

如果满足以下任意条件则两个值相等

  • 都是 undefined
  • 都是 null
  • 都是 true 或都是 false
  • 都是相同长度、相同字符、按相同顺序排列的字符串
  • 都是相同对象(意味着都是同一个对象的值引用)
  • 都是数字且
    • 都是 +0
    • 都是 -0
    • 都是 NaN
    • 都是同一个值,非零且都不是 NaN

参数说明

  1. is (
  2. value1: any,
  3. value2: any,
  4. ) return boolean
参数名 是否必填 类型 说明
value1 any 被比较的第一个值
value2 any 被比较的第二个值

示例

普通判断
  1. Object.is(25, 25); // true
  2. Object.is('foo', 'foo'); // true
  3. Object.is('foo', 'bar'); // false
  4. Object.is(null, null); // true
  5. Object.is(undefined, undefined); // true
  6. Object.is(window, window); // true
  7. Object.is([], []); // false
  8. var foo = { a: 1 };
  9. var bar = { a: 1 };
  10. Object.is(foo, foo); // true
  11. Object.is(foo, bar); // false
  12. // Case 3: NaN
  13. Object.is(NaN, 0/0); // true
  14. Object.is(NaN, Number.NaN) // true

+0-0

当我们使用 全等(===)时 +0-0 是相等的

但是当我们使用 Object.is 时,他们是不相等的

可以说 Object.is 更为严格

  1. Object.is(0, -0); // false
  2. Object.is(+0, -0); // false
  3. Object.is(-0, -0); // true
  4. Object.is(0n, -0n); // true

也可以用来判断 NaN
  1. Object.is(NaN, 0/0); // true
  2. Object.is(NaN, Number.NaN) // true

isExtensible

Object.isExtensible 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。

参数说明

  1. isExtensible (
  2. obj: object,
  3. ) return boolean
参数名 是否必填 类型 说明
obj object 需要检测的对象

示例

  1. // 新对象默认是可扩展的。
  2. var empty = {};
  3. Object.isExtensible(empty); // === true
  4. // ...可以变的不可扩展。
  5. Object.preventExtensions(empty);
  6. Object.isExtensible(empty); // === false
  7. // 密封对象是不可扩展的。
  8. var sealed = Object.seal({});
  9. Object.isExtensible(sealed); // === false
  10. // 冻结对象也是不可扩展。
  11. var frozen = Object.freeze({});
  12. Object.isExtensible(frozen); // === false

isFrozen

Object.isFrozen 方法判断一个对象是否被冻结

一个对象是冻结的是指它不可[扩展](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible),所有属性都是不可配置的,且所有数据属性(即没有 getter 或 setter 组件的访问器的属性)都是不可写的

使用方法同 isExtensible 这里不再赘述了

示例

  1. // 一个对象默认是可扩展的,所以它也是非冻结的。
  2. Object.isFrozen({}); // === false
  3. // 一个不可扩展的空对象同时也是一个冻结对象。
  4. var vacuouslyFrozen = Object.preventExtensions({});
  5. Object.isFrozen(vacuouslyFrozen) //=== true;
  6. // 一个非空对象默认也是非冻结的。
  7. var oneProp = { p: 42 };
  8. Object.isFrozen(oneProp) //=== false
  9. // 让这个对象变的不可扩展,并不意味着这个对象变成了冻结对象,
  10. // 因为 p 属性仍然是可以配置的 (而且可写的).
  11. Object.preventExtensions(oneProp);
  12. Object.isFrozen(oneProp) //=== false
  13. // 此时,如果删除了这个属性,则它会成为一个冻结对象。
  14. delete oneProp.p;
  15. Object.isFrozen(oneProp) //=== true
  16. // 一个不可扩展的对象,拥有一个不可写但可配置的属性,则它仍然是非冻结的。
  17. var nonWritable = { e: "plep" };
  18. Object.preventExtensions(nonWritable);
  19. Object.defineProperty(nonWritable, "e", { writable: false }); // 变得不可写
  20. Object.isFrozen(nonWritable) //=== false
  21. // 把这个属性改为不可配置,会让这个对象成为冻结对象。
  22. Object.defineProperty(nonWritable, "e", { configurable: false }); // 变得不可配置
  23. Object.isFrozen(nonWritable) //=== true
  24. // 一个不可扩展的对象,拥有一个不可配置但可写的属性,则它仍然是非冻结的。
  25. var nonConfigurable = { release: "the kraken!" };
  26. Object.preventExtensions(nonConfigurable);
  27. Object.defineProperty(nonConfigurable, "release", { configurable: false });
  28. Object.isFrozen(nonConfigurable) //=== false
  29. // 把这个属性改为不可写,会让这个对象成为冻结对象。
  30. Object.defineProperty(nonConfigurable, "release", { writable: false });
  31. Object.isFrozen(nonConfigurable) //=== true
  32. // 一个不可扩展的对象,值拥有一个访问器属性,则它仍然是非冻结的。
  33. var accessor = { get food() { return "yum"; } };
  34. Object.preventExtensions(accessor);
  35. Object.isFrozen(accessor) //=== false
  36. // ...但把这个属性改为不可配置,会让这个对象成为冻结对象。
  37. Object.defineProperty(accessor, "food", { configurable: false });
  38. Object.isFrozen(accessor) //=== true
  39. // 使用 Object.freeze 是冻结一个对象最方便的方法。
  40. var frozen = { 1: 81 };
  41. Object.isFrozen(frozen) //=== false
  42. Object.freeze(frozen);
  43. Object.isFrozen(frozen) //=== true
  44. // 一个冻结对象也是一个密封对象。
  45. Object.isSealed(frozen) //=== true
  46. // 当然,更是一个不可扩展的对象。
  47. Object.isExtensible(frozen) //=== false

isSealed

Object.isSealed 方法判断一个对象是否被密封

如果这个对象是密封的,则返回 true,否则返回 false。密封对象是指那些不可 扩展 的,且所有自身属性都不可配置且因此不可删除(但不一定是不可写)的对象。

示例

  1. // 新建的对象默认不是密封的。
  2. var empty = {};
  3. Object.isSealed(empty); // === false
  4. // 如果你把一个空对象变的不可扩展,则它同时也会变成个密封对象。
  5. Object.preventExtensions(empty);
  6. Object.isSealed(empty); // === true
  7. // 但如果这个对象不是空对象,则它不会变成密封对象,因为密封对象的所有自身属性必须是不可配置的。
  8. var hasProp = { fee: "fie foe fum" };
  9. Object.preventExtensions(hasProp);
  10. Object.isSealed(hasProp); // === false
  11. // 如果把这个属性变的不可配置,则这个属性也就成了密封对象。
  12. Object.defineProperty(hasProp, 'fee', {
  13. configurable: false
  14. });
  15. Object.isSealed(hasProp); // === true
  16. // 最简单的方法来生成一个密封对象,当然是使用 Object.seal.
  17. var sealed = {};
  18. Object.seal(sealed);
  19. Object.isSealed(sealed); // === true
  20. // 一个密封对象同时也是不可扩展的。
  21. Object.isExtensible(sealed); // === false
  22. // 一个密封对象也可以是一个冻结对象,但不是必须的。
  23. Object.isFrozen(sealed); // === true ,所有的属性都是不可写的
  24. var s2 = Object.seal({ p: 3 });
  25. Object.isFrozen(s2); // === false, 属性"p"可写
  26. var s3 = Object.seal({ get p() { return 0; } });
  27. Object.isFrozen(s3); // === true ,访问器属性不考虑可写不可写,只考虑是否可配置

keys

Object.keys 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。

Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的 object 上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。

参数说明

  1. keys (
  2. obj: object,
  3. ) return array
参数名 是否必填 类型 说明
obj object 要返回其枚举自身属性的对象

示例

  1. var arr = ['a', 'b', 'c'];
  2. console.log(Object.keys(arr)); // ['0', '1', '2']
  3. var obj = { 0: 'a', 1: 'b', 2: 'c' };
  4. console.log(Object.keys(obj)); // ['0', '1', '2']
  5. var anObj = { 100: 'a', 2: 'b', 7: 'c' };
  6. console.log(Object.keys(anObj)); // ['2', '7', '100']
  7. var myObj = Object.create({}, {
  8. getFoo: {
  9. value: function () { return this.foo; }
  10. }
  11. });
  12. myObj.foo = 1;
  13. console.log(Object.keys(myObj)); // ['foo']

preventExtensions

Object.preventExtensions 方法让一个对象变的不可扩展,也就是永远不能再添加新的属性

仅阻止添加自身的属性。但其对象类型的原型依然可以添加新的属性

参数说明

  1. preventExtensions (
  2. obj: object
  3. ) return object // 已经不可扩展的对象
参数名 是否必填 类型 说明
obj object 将要变得不可扩展的对象

示例

  1. // Object.preventExtensions 将原对象变的不可扩展,并且返回原对象。
  2. var obj = {};
  3. var obj2 = Object.preventExtensions(obj);
  4. obj === obj2; // true
  5. // 字面量方式定义的对象默认是可扩展的。
  6. var empty = {};
  7. Object.isExtensible(empty) // true
  8. // ...但可以改变。
  9. Object.preventExtensions(empty);
  10. Object.isExtensible(empty) // false
  11. // 使用 Object.defineProperty 方法为一个不可扩展的对象添加新属性会抛出异常。
  12. var nonExtensible = { removable: true };
  13. Object.preventExtensions(nonExtensible);
  14. Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // 抛出 TypeError 异常
  15. // 在严格模式中,为一个不可扩展对象的新属性赋值会抛出 TypeError 异常。
  16. function fail()
  17. {
  18. "use strict";
  19. nonExtensible.newProperty = "FAIL"; // throws a TypeError
  20. }
  21. fail();

seal

Object.seal 方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变

通常,一个对象是可扩展的(可以添加新的属性)。密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出 TypeError (在严格模式 中最常见的,但不唯一)。

参数说明

  1. seal (
  2. obj: object
  3. ) return object // 被密封的对象
参数名 是否必填 类型 说明
obj object 将要被密封的对象

示例

  1. var obj = {
  2. prop: function() {},
  3. foo: 'bar'
  4. };
  5. // 可以添加新的属性
  6. // 可以更改或删除现有的属性
  7. obj.foo = 'baz';
  8. obj.lumpy = 'woof';
  9. delete obj.prop;
  10. var o = Object.seal(obj);
  11. o === obj; // true
  12. Object.isSealed(obj); // === true
  13. // 仍然可以修改密封对象的属性值
  14. obj.foo = 'quux';
  15. // 但是你不能将属性重新定义成为访问器属性
  16. // 反之亦然
  17. Object.defineProperty(obj, 'foo', {
  18. get: function() { return 'g'; }
  19. }); // throws a TypeError
  20. // 除了属性值以外的任何变化,都会失败。
  21. obj.quaxxor = 'the friendly duck';
  22. // 添加属性将会失败
  23. delete obj.foo;
  24. // 删除属性将会失败
  25. // 在严格模式下,这样的尝试将会抛出错误
  26. function fail() {
  27. 'use strict';
  28. delete obj.foo; // throws a TypeError
  29. obj.sparky = 'arf'; // throws a TypeError
  30. }
  31. fail();
  32. // 通过 Object.defineProperty 添加属性将会报错
  33. Object.defineProperty(obj, 'ohai', {
  34. value: 17
  35. }); // throws a TypeError
  36. Object.defineProperty(obj, 'foo', {
  37. value: 'eit'
  38. }); // 通过 Object.defineProperty 修改属性值

setPrototypeOf

Object.setPrototypeOf 方法设置一个指定的对象的原型 ( 即,内部 [[Prototype]] 属性)到另一个对象或 null

参数说明

  1. setPrototypeOf (
  2. obj: object,
  3. prototype: object | null,
  4. ) return undefined
参数名 是否必填 类型 说明
obj object 要设置其原型的对象
prototype object 该对象的新原型

示例

  1. var dict = Object.setPrototypeOf({}, null);
  2. console.log(dict.__proto__) // undefined
  3. var dict = Object.setPrototypeOf({}, { a: 1, b: 2, c: 3, });
  4. console.log(dict.__proto__) // { a: 1, b: 2, c: 3 }

values

Object.values 方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用 for in 循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。

参数说明

  1. setPrototypeOf (
  2. obj: object
  3. ) return array // 一个包含对象自身的所有可枚举属性值的数组
参数名 是否必填 类型 说明
obj object 被返回可枚举属性值的对象

示例

  1. var obj = { foo: 'bar', baz: 42 };
  2. console.log(Object.values(obj)); // ['bar', 42]
  3. var obj = { 0: 'a', 1: 'b', 2: 'c' };
  4. console.log(Object.values(obj)); // ['a', 'b', 'c']
  5. var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
  6. console.log(Object.values(an_obj)); // ['b', 'c', 'a']
  7. var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
  8. my_obj.foo = 'bar';
  9. console.log(Object.values(my_obj)); // ['bar']
  10. console.log(Object.values('foo')); // ['f', 'o', 'o']