ES6的学习笔记(七)对象的扩展

210 阅读4分钟

对象的扩展

属性和方法的简洁表达方式

  • 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)