对象
定义:
- 无序的数据集合
- 建制对的集合
创建:
声明形式
let obj = { 'name': 'frank', 'age': 18 }
构造形式
let obj = new Object()
person=new Object();
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue";
函数形式
function Person(name,age){
this.name = name;
this.age = age;
this.sayHi = function () {
console.log("hello");
};
}
var p = new Person("jimmy",18);
对象的属性
- 属性名:每个key都是对象的属性名(property)
- 属性值:每个 value 都是对象的属性值
奇怪的属性名:
所有属性名都会自动变成字符串
let obj = {
1: 'a',
3.2: 'b',
1e2: true,
1e-2: true,
.234: true,
0xFF: true
};
/** 以上每个属性的key值:
1其实是'1'
3.2其实是是'3.2'
1e2其实是'100'
1e-2其实是'0.01'
.234其实是'0.234'
0xFF其实是'255'
注意:
- 键名是字符串,不是标识符,可以包含任意字符
- 引号可省略,省略之后就只能写标识符
- 渲算引号省略了,键名也还是字符串(重要) 访问一个对象的属性值可以通过 . 操作符 和 [] 操作符 进行访问,举个粟子:
访问
. 操作符:要求属性名满足标识符的命名规范
[] 操作符:可以接受任意 UTF-8/Unicode 字符串作为属性名
let obj = {
'first_name': 'Jon',
age: 18,
say: () => {
console.log('hello')
}
}
obj.age // 通过 .运算符 访问,18
obj['age'] // 通过 []操作符 访问,18
obj['first_name'] // 通过 []操作符 访问,Jon
变量做属性名:
如何使用变量做属性名?之前都是常量做属性名
let p1 = 'name'
let obj = { p1 : 'frank'} //这样写,属性名为 'p1'
let obj = { [p1] : 'frank' } //这样写,属性名为 'name'
- 不加 [ ] 的属性名会自动变成字符串。
- 加了 [ ] 则会当做变量求值。
- 值如果不是字符串,则会自动变成字符串
除了字符串,symbol也能做属性名
let a = Symbol()
let obj = {[a]: 'Hello'}
对象操作
增加属性
1、修改或增加属性
(1)直接赋值
let obj = {name: 'frank'} // name 是字符串
obj.name = 'frank' // name 是字符串
obj['name'] = 'frank'
***obj[name] = 'frank' // 错,因 name 值不确定
obj['na'+'me'] = 'frank'
let key = 'name'; obj[key] = 'frank'
let key = 'name'; ***obj.key = 'frank'~~ // 错,因为 obj.key 等价于 obj['key']
(2)批量赋值
Object.assign(obj, {age: 18, gender: 'man'})
2、修改或增加公有属性
无法通过自身修改或增加共有属性
- let obj = {}, obj2 = {} 共有 toString
- obj.toString = 'xxx' 只会在改 obj 自身属性
- obj2.toString 还是在原型上
我偏要修改或增加原型上的属性
obj.__proto__.toString = 'xxx'// 不推荐用__proto__Object.prototype.toString = 'xxx'- 一般来说,不要修改原型,会引起很多问题
3、修改隐藏属性
不推荐使用__proto__
let obj = {name:'frank'}
let obj2 = {name: 'jack'}
let common = {kind: 'human'}
obj.__proto__ = common
obj2.__proto__ = common
推荐使用 Object.create
let obj = Object.create(common)
obj.name = 'frank'
let obj2 = Object.create(common)
obj2.name = 'jack'
规范大概的意思是,要改就一开始就改,别后来再改
删除属性
delete命令用于删除对象的属性,删除成功后返回true
举例:
(1)
注:只能用'xxx' in obj 查看属性名是否还在对象中:true表示在,false表示不在
(2)
①语句'xxx' in obj && obj.xxx === undefined返回true,表示属性xxx还在obj中,而且属性xxx的值是undefined
②注意obj.xxx === undefined不能断定'xxx' 是否为obj的属性。
查看属性
查看一个对象本身的所有属性,可以使用Object.keys方法。
- 查看一个对象的所有自身属性:
Object.keys(obj)
var obj = {
key1: 1,
key2: 2
};
Object.keys(obj);
// ['key1', 'key2']
- 查看一个对象的所有自身属性值:
Object.values(obj) - 查看一个对象的所有自身的属性和值:直接对象名就行
obj或者Object.entries(obj) - 查看自身+共有属性:
console.dir(obj) - 查看共有属性: 自己依次用
Object.keys打印出obj.__ proto_ - 判断一个属性是自身的还是共有的:
obj.hasOwnProperty('属性名')( 返回true说明该属性是自身属性,返回false说明该属性是共有属性) 'key' in obj查看属性名是否还在对象中:true表示在,false表示不在
查看一个对象的一个属性
- 中括号语法:
obj['key']或obj['k'+'ey'] - 点语法:
obj.key - 坑新人语法:
obj[key]// 变量 key 值一般不为 'key'
举例
let list = ['name','age','gender']
let person = {
name: 'yy', age : 18, gender : 'woman'
}
for (let i = 0; i < list.length; i++) {
let name = list [i]
console.log(person.name) //重点
}
// 结果为person的第一个属性值yy*3
let list = ['name','age','gender']
let person = {
name: 'yy', age : 18, gender : 'woman'
}
for (let i = 0; i < list.length; i++) {
let name = list [i]
console.log(person[name]) //重点
}
// 结果为person的所有属性值yy、18、woman
属性的遍历
for...in循环用来遍历一个对象的全部属性。
var obj = {a: 1, b: 2, c: 3};
for (var i in obj) {
console.log('键名:', i);
console.log('键值:', obj[i]);
}
// 键名: a
// 键值: 1
// 键名: b
// 键值: 2
// 键名: c
// 键值: 3
ES6
对象的扩展
属性的简洁表示法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
// 等同于
const baz = {foo: foo};
上面代码中,变量foo直接写在大括号里面。这时,属性名就是变量名, 属性值就是变量值。下面是另一个例子。
function f(x, y) {
return {x, y};
}
// 等同于
function f(x, y) {
return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
除了属性简写,方法也可以简写。
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
};
例子
let birth = '2000/01/01';
const Person = {
name: '张三',
//等同于birth: birth
birth,
// 等同于hello: function ()...
hello() { console.log('我的名字是', this.name); }
};
这种写法用于函数的返回值,将会非常方便。
function getPoint() {
const x = 1;
const y = 10;
return {x, y};
}
getPoint()
// {x:1, y:10}
CommonJS 模块输出一组变量,就非常合适使用简洁写法。
let ms = {};
function getItem (key) {
return key in ms ? ms[key] : null;
}
function setItem (key, value) {
ms[key] = value;
}
function clear () {
ms = {};
}
module.exports = { getItem, setItem, clear };
// 等同于
module.exports = {
getItem: getItem,
setItem: setItem,
clear: clear
};
扩展运算符
对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
ES6方法
Object.is()
Object.is用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
Object.assign()浅拷贝
Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。
注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}