JavaScript对象基础

对象是JavaScript中数据类型的一种,是由{}包裹的键值对集合。

对象的声明有两种方式:

let obj = {name:'xxx', age: 18}
let obj = new Object({name:'xxx', age: 18})

对象的键名是字符串类型,即使它没有加引号。

除了用字符串常量作为键值,还可以用字符串变量(ES6新增):

let key = 'title';
let obj = {};
obj[key] = '钢铁是怎样炼成的';

key可以是计算出来的,例如:

let index = 1;
let key = `title-${index}`;
let key = 1e2; // 会计算成数字100再作为key

对象的隐藏属性

每个对象都有一个隐藏属性__proto__,这个属性存储其原型 的地址。

查看对象的属性

let obj = {
name: 'xxx',
age: 18
}
// 查看obj的所有键名
Object.keys(obj); // ["name", "age"]

// 查看obj的所有值
Object.values(obj); // ["xxx", 18]

// 查看键和值
Object.entries(obj); // [["name", "xxx"], ["age", 18]]

这三个方法可以查看对象自身的属性,但是不能查看对象原型上的属性。

判断对象是否有某个属性

hasOwnProperty方法可以判断对象自身 是否有某属性:

obj.hasOwnProperty('toString') // false
obj.hasOwnProperty('name') // true

键名 in obj可以判断对象自身+其原型 上是否有某属性:

'toString' in obj // true
'name' in obj // true

修改或添加对象属性

直接赋值

let obj = {
name: 'John'
}

obj.age = 18;
// 或者
obj['age'] = 18; // 这种方法 使用的键名可以为计算出来的字符串、字符串变量

批量赋值

ES6新增。

Object.assign(obj, {age:18, gender: 'male'})

如果参数中的两个对象有键名重复,那么后面的会覆盖前面的。

删除对象的属性

delete obj.name
// 或者
delete obj['name']

属性的特征

属性的特征是用来描述属性的一些信息的,例如是否可修改等。

使用Object.getOwnPropertyDescriptor函数可以获取属性特征对象。

let obj = {
name: 'John',
}
console.log(Object.getOwnPropertyDescriptor(obj, "name"));
/*
{
configurable: true,
enumerable: true,
value: "xxx",
writable: true
}
*/

configurable:如果为 true,则此特性可以被删除,这些属性也可以被修改,否则不可以。

enumerable:如果为 true,表示该属性是可枚举的,会被在循环中列出,否则不会被列出。

writable:如果为 true,则值可以被修改,否则它是只可读的。

我们可以使用Object.defineProperty来修改它们。

Object.defineProperty(obj, propertyName, descriptor)

访问器

我们可以使用访问器gettersetter来获取和修改属性:

let obj = {
get propName() {
// 当读取 obj.propName 时,getter 起作用
},

set propName(value) {
// 当执行 obj.propName = value 操作时,setter 起作用
}
};

使用访问器的好处是我们可以在gettersetter中添加一些逻辑,以便对属性做更多控制。

例如,如果我们想禁止太短的 user 的 name,我们可以创建一个 setter name,并将值存储在一个单独的属性 _name 中: // todo: 键用symbol() 不用_name

let user = {
get name() {
return this._name;
},

set name(value) {
if (value.length < 4) {
alert("Name is too short, need at least 4 characters");
return;
}
this._name = value;
}
};

user.name = "Pete";
alert(user.name); // Pete

user.name = ""; // Name 太短了……

需要注意的是,在严格模式下,对一个只有getter没有setter的属性进行赋值操作会报错;在非严格模式下,不会报错,但是赋值操作不会生效。

参考

网道 - JavaScript教程 - 对象

Author: kpt

Permalink: http://kpt.ink/2021/08/02/JavaScript-Object-basic/

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。