对象的扩展
属性和方法的简洁表达方式
- ES6允许在大括号里直接写入变量和函数,作为对象的属性和方法。
let name="Nick",age=18;
let student={name,age};
// let student={name:name,age:age};
function fn(x,y){
return {x,y}
}
// 等同于
function fn(x,y){
return {
x:x,
y:y
}
}
fn(1,2) // {x:1,y:2}
// 方法也可以简写
let str="name";
let obj={
fn(){},
//fn:function(){}
// 属性名,用[],里面可以写变量
[str]:"Jack",
// 等同于,name:"Jack"
["my"+str]:"Jack" //等同myname:"Jack"
}
// 简写形式的方法不能用作构造函数,会报错。
let obj ={
fn(){}
}
new obj.fn() // Uncaught TypeError: obj.fn is not a constructor
属性名表达式。
ES6允许使用字面量定义对象时,使用方括号语法。即把表达式放在方括号内。
let propKey = 'foo'
let obj ={
[propKey]:true,
['a'+'bc']:123
}
// 表达式也可用于方法名
let obj = {
['hi'+'bc'](){
console.log("object")
}
}
obj.hibc() // object
// 属性名表达式和简洁表示法不能同时使用,会报错。
const foo = 'bar'
const bar = '我是value'
let obj = {[foo]} // 报错
const foo ='bar'
let obj ={[foo]:'我是value'} // 正确
// 属性名表达式是一个对象,则会将属性名转为字符串[object Object]
let keyB={a:1}
let obj = {
[keyB]:'我是value'
}
console.log(obj) // {[object Object]: "我是value"}
对象的扩展运算符
解构赋值
- 扩展运算符与解构赋值结合使用,从一个对象取值,将目标对象自身的所有可遍历的、尚未被读取的属性,分配到指定的对象上面。所有的键和值都会拷贝到新对象上面。
let {x,y,...z} = {x:1,y:2,a:3,b:4}
console.log(x,y,z) // 1 2 {a: 3, b: 4}
- 对象的解构要求=的右边是一个对象,而如果是undefined和null则无法转换为对象,即报错。
let {...a} = null
let {...z} = undefined
- 扩展运算符必须是用在最后一个参数上,否则会报错。
let {...z,b,c} = {a:1,d:3,b:3,c:3} // 报错
- 扩展运算符是浅拷贝,如果拷贝的是一个复合类型(数组、对象、函数等)的值,则拷贝的是值的引用,不是这个值的副本。
let obj ={
a:{
b:1
}
}
let {...z} = obj
z.a.b=2
console.log(obj.a.b); // 2
- 扩展运算符的解构赋值不能复制从原型对象继承的属性。
let obj1 = {
a:1
}
let obj2 = {
b:2
}
obj2.__proto__ = obj1
let {...obj3} = obj1
console.log(obj3.a); // 1
console.log(obj3.b); // undefined
扩展运算符
// 1.对象的扩展运算符:将参数对象的所有可遍历属性拷贝到当前对象之中。
let obj = {
a: 1,
b: 2
}
let obj2 = { ...obj }
console.log(obj2);//{a:1,b:2}
// 2.数组是特殊的对象,故对象的扩展运算符也可用于数组
let arr = ['a','b','c']
let a ={...arr}
console.log(a); // {0: "a", 1: "b", 2: "c"}
// 3.扩展运算符后面是空对象,则无任何效果
let obj = {
...{},
a:1
}
console.log(obj); // {a:1}
// 4.不是对象,则自动转为对象
let obj ={
...1
}
// 等同于 {...Object(1)}
console.log(obj); // {}
// 等同于 {...Object(true)}
{...true} // {}
// 等同于 {...Object(undefined)}
{...undefined} // {}
// 等同于 {...Object(null)}
{...null} // {}
// 5. 若是字符串,则自动转换为类似数组的对象。
let obj ={...'hello'}
console.log(obj); //{0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
Object.is 判断两个值是否相同
console.log(NaN===NaN); //false
console.log(Object.is(NaN,NaN)); //true
console.log(-0===0); // true
console.log(Object.is(-0,0)); //false
未完
Object.assign
- 用于将所有可枚举属性的值从一个或多个源复制到目标对象,将返回目标对象(将改变目标对象的值)
- 目标对象中属性具有相同的键,则属性将被源对象中的属性覆盖,后面的源对象的属性也将类似的覆盖前面的源对象的属性。
- source为null或undefined时,该方法不会报错
- 这只是一个浅拷贝
// assign(target,source)
let obj1={name:"Nick"};
let obj2={age:18};
let obj3=Object.assign(obj1,obj2);
console.log(obj1);// {name:"Nick",age:18}
console.log(obj3);//{name:"Nick",age:18}
console.log(Object.assign(obj3,null)); // {name:"Nick",age:18}
Object.getOwnPropertyDescriptor(obj,prop);
- obj:目标对象,prop:目标内属性名称
- 有,返回属性描述符,否则返回undefined
- 该方法返回指定对象上一个自有属性对应的属性描述符。(自有属性即直接赋予该对象的属性,不需要从原型链上去找。)
- 去MDN看 MDN
Object.keys()
Object.value()
Object.entries()
对象的setter和getter
- 一个getter是一个获取某个特定属性的值的方法,一个setter是一个设置某个特定属性值的方法。
let o={
a:7,
get b(){
return this.a+1;
},
set c(x){
this.a=x/2;
}
};
console.log(o.a); // 7
console.log(o.b); // 8
o.c=50;
console.log(o.a); // 25
- getter和setter可以使用对象初始化器定义,也可以之后随时使用getter和setter添加方法添加到任何对象。 getter 方法是无参数的,setter方法只接受一个参数(设置为新值)。
// 对象初始化时定义
var o = {
a: 7,
get b() { return this.a + 1; },
set c(x) { this.a = x / 2; }
};
// 使用Object.defineProperties() 方法为对象添加
var o = { a:0 }
Object.defineProperties(o, {
"b": { get: function () { return this.a + 1; } },
"c": { set: function (x) { this.a = x / 2; } }
});
o.c = 10
console.log(o.b)