对象是JavaScript中非常重要的数据结构。
1.基础
JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。- 一个
JavaScript对象可以有很多属性,属性定义了对象的特征。 - 访问属性是通过.操作符完成的,但这要求属性名必须是一个有效的变量名;对象的属性也可以通过方括号访问或者设置。
一个属性的名称如果不是一个有效的
JavaScript标识符(例如,一个由空格或连字符,或者以数字开头的属性名),就只能通过方括号标记访问。
2.Symbol
ES6 为什么引入了Symbol?
ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。
Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。 --阮一峰
作为属性名,每一个Symbol值都是不相等的。
// 无参数
let a = Symbol();
let b = Symbol();
a === b //false
// 有参数
let c = Symbol('foo');
let d = Symbol('foo');
c === c //false
注意:
- Symbol 值作为对象属性名时,不能用点运算符。
- 在对象内部,使用Symbol定义属性时,Symbol值必须放在方括号[]内。
3.枚举一个对象的所有属性
for...in循环:该方法依次访问一个对象及其原型链中所有可枚举的属性(不含Symbol属性)。Object.keys(obj):该方法返回一个对象 obj 自身包含(不包括原型中)的所有属性的名称的数组。Object.getOwnPropertyNames(obj):该方法返回一个数组,它包含了对象obj所有拥有的属性(无论是否可枚举)的名称。Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有Symbol属性的键名。Reflect.ownKeys(obj):Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是Symbol或字符串,也不管是否可枚举。
3.创建对象(创建对象一共有七种方式,这里只列举了几种常见的)
- 对象字面量
let person = {
name: 'Luna',
age: '18',
hobby: 'reading',
greeting: function() {
console.log('hello,I am ' + this.name)
}
};
- 使用
new表达式
let person = new Object();
person.name = 'Luna';
person.age = '18';
person.hobby = 'reading';
person.greeting = function () {
console.log('hello,I am ' + this.name)
}
- 使用构造函数:
function Person(name, age, hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
this.greeting = function () {
console.log('hello,I am ' + this.name)
}
}
let person = new Person('Luna','18','reading');
- 使用工厂模式
function createPerson(name, age, hobby) {
let obj = new Object();
obj.name = name;
obj.age = age;
obj.hobby = hobby;
obj.greeting = function () {
console.log('hello,I am ' + this.name)
}
return obj;
}
let person = createPerson('Luna','18','reading');
- 原型模式
function Person () {}
Person.prototype.name = 'Luna';
Person.prototype.age = '18';
Person.prototype.hobby = 'reading';
Person.prototype.greeting = function () {
console.log('hello,I am ' + this.name)
}
let person = new Person()
4.对象的方法
- Object.is():ES6 提出“Same-value equality”(同值相等)算法(ES5:JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。),用Object.is()解决严格相等的问题。
与"==="的区别:
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
- Object.assign():通过复制一个或多个对象来创建一个新的对象(属于浅拷贝【Object.assign()浅拷贝在后面章节会进行讲解】)。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
- Object.create():使用指定的原型对象和属性创建一个新对象。
const person = {
name: 'Luna',
age: '18',
hobby: 'reading',
greeting: function() {
console.log('hello,I am ' + this.name)
}
};
const me = Object.create(person);
me.name = 'Bella';
-
Object.defineProperty()/Object.defineProperties():给对象添加一个/多个属性并指定该属性的配置。
-
Object.entries():返回给定对象自身可枚举属性的[key, value]数组。
-
Object.freeze()/Object.isFrozen():冻结对象:其他代码不能删除或更改任何属性/判断对象是否已经冻结。
-
Object.getOwnPropertyDescriptor():返回对象指定的属性配置。
-
Object.getOwnPropertyNames():返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名。
-
Object.getOwnPropertySymbols():返回一个数组,它包含了指定对象自身所有的符号属性。
-
Object.getPrototypeOf():返回指定对象的原型对象。
-
Object.isExtensible():判断对象是否可扩展。
-
Object.isSealed()/Object.seal():判断对象是否已经密封。/防止其他代码删除对象的属性。
-
Object.keys():返回一个包含所有给定对象自身可枚举属性名称的数组。
-
Object.preventExtensions():防止对象的任何扩展。
-
Object.setPrototypeOf():设置对象的原型(即内部[Prototype]属性)。
-
Object.values():返回给定对象自身可枚举值的数组