Skip to content

对象 #158

@S-T-D

Description

@S-T-D

属性

数据属性

对象的属性可分为 数据属性 和 访问器 属性。

ES5 中新增了属性描述符用来描述对象中的数据属性。

var obj = {
	count: 6
};

Object.getOwnPropertyDescriptor(obj, 'count');
// {
//    value: 6,
//    writable: true,
//    enumerable: true,
//    configurable: true
// }

默认情况下,3 个描述符都为 true

 

可写性 writable

writable 决定是否可以修改属性值,如果为 false,将不能修改。

  • 在普通模式下,尝试修改会静默失败
  • 在严格模式下,尝试修改会抛出错误
var obj = {};

Object.defineProperty(obj, 'a', {
	value: 6,
	writable: false,        // 不可写
} );

 

可配置性 configurable

configurable 表示是否可以修改属性的描述符。

如果 configurable 被设置成 false 了,那么就不能再修改这 3 个描述符,尝试修改会报错,同时,执行 delete 操作也会静默失败。

当然,除了 writable,它比较特殊。

如果 configurable 变成 false 后,writable 可以由 true 变成 false,但是不能由 false 变成 true

所以,configurable 是单向操作,一旦变为 false,就不能再改成 true

 

可枚举性 enumerable

它控制着一个属性是否能在特定的对象-属性枚举操作中(属性被迭代时)出现,比如:

  • for in 循环
  • Object.keys 方法
  • JSON.stringify 方法

设置为 false 就不会出现在上述枚举和方法中,但是依然是可以通过对象访问的。

propertyIsEnumerable 方法可用于判断一个属性是否直接存在于对象上,并使是可枚举的。

 

访问器属性

访问器属性包含两个函数:gettersetter,分别在读取和设置属性值的时候调用。

除此之外,还包括 configurableenumerable

注意:同时定义数据属性和访问器属性会报错:Invalid property descriptor. Cannot both specify accessors and a value or writable attribute。

直接定义:

var obj = {
	get name() {
		return 'test';
	}
};

通过方法定义:

Object.defineProperty(
	obj,
	"age",
	{
		get: function(){ 
            return 18;
        },
	}
);

 

不可变性

下面创建的都是 浅 不可变性,只对 对象 的直接属性起作用,如果属性是对其他对象的引用,那被引用的属性不受影响。

对象常量

通过使用 writableconfigurable 可以使对象的属性不能修改和删除。

const CONSTANTS = {};

Object.defineProperty(CONSTANTS, 'PI', {
    value: 3.14,
    writable: false,
    configurable: false,
});

 

防止扩展

禁止对象添加新的属性,如果添加会静默失败,严格模式下报错。

const obj = {
	value: 2
};

Object.preventExtensions( obj );

obj.name = 'test';
obj.name; // console: undefined

 

封印

Object.seal 方法接收一个对象,它对这个对象做了两件事情:

  • 在对象调用 Object.preventExtensions 方法,禁止其扩展
  • 将对象现有属性的 configurable 设置为 true,所以,不能配置和删除属性

但是,如说属性的 writabletrue,就已然可以修改属性值。

 

冻结

Object.freeze 方法,相当于在 seal 的基础上,将属性的 writable 设置为 false

对象的属性不能配置、删除,也不能修改。

 

属性存在性

in 操作符

in 操作符会检查属性是否存在于对象或者其原型链的对象上。

 

hasOwnProperty

hasOwnProperty 方法也可以判断一个对象是否有某个属性,但是不会检查原型链。

一般情况下,可以通过普通对象直接访问 hasOwnProperty 方法,但是更好的方式是:

Object.prototype.hasOwnProperty.call(obj, "name")

这样可以防止 obj 对象没有链接到 Object.prototype,不能访问 hasOwnProperty 方法。

 

对象的方法汇总

keys

返回一个所有可枚举属性的数组,不包括原型链上的属性。

Object.keys(obj);

 

getOwnPropertyNames

返回一个所有属性的数组,不论是否可以枚举。

Object.getOwnPropertyNames(obj);

 

propertyIsEnumerable

判断一个属性是否直接存在于对象,并且是可枚举的。

obj.propertyIsEnumerable('name');

 

hasOwnProperty

判断对象是否直接拥有属性。

Object.prototype.hasOwnProperty.call(obj, "name");

 

defineProperty

定义单个数据属性或访问器属性。

Object.defineProperty(obj, "name", {
	value: 'tom',
	writable: false,
	configurable: true,
	enumerable: true
} );

 

defineProperties

定义多个数据属性或访问器属性。

Object.defineProperty(obj, {
    name: {
        value: 'tom',
	    writable: false,
    },
    age: {
        get() {
            return 18;
        }
    }
});

 

getOwnPropertyDescriptor

获取某个属性的属性描述符。

Object.getOwnPropertyDescriptor(obj, name);

 

getOwnPropertyDescriptors

获取对象所有属性的属性描述符。

Object.getOwnPropertyDescriptors(obj);

 

is

比较两个值是否严格相等。

Object.is('test', 'test')   // true

Object.is({}, {})           // false

Object.is(+0, -0)           // false

Object.is(NaN, NaN)         // true

+0 === -0                   // true

NaN === NaN                 // false

 

assign

Object.assign(目标对象, 源对象1, 源对象2 ...),返回目标对象。

将源对象上可枚举和直接拥有的属性拷贝到目标对象,并且是浅拷贝。

 

create

Object.create(proto,[propertiesObject])

该方法创建一个新对象,这个新对象的原型指向 proto

  • proto:新创建对象的原型对象
  • propertiesObject:属性对象,会添加到新创建对象上面

 

setPrototypeOf

Object.setPrototypeOf(a, b)

a 的原型指向 b

 

isPrototypeOf

// Foo.prototype 在 a 的原型链上出现过吗?
Foo.prototype.isPrototypeOf( a );

// b 在 c 的原型链上出现过吗?
b.isPrototypeOf( c );

 

getPrototypeOf

Object.getPrototypeOf(obj) 返回指定对象的原型

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions