ES6对象的拓展
重点知识1(ES6中关于对象的简写)
-
- ES6 允许在对象中只写属性名,不写属性值
例1
var foo = 'bar';
var baz = {foo};
console.log(baz); //{foo:bar}
// => 等同于
var baz = {
foo:foo
}
例2
function f(x,y){
return {x,y} // 1 2
}
f(1,2);
// => 等同于
function f(x,y){
return {
x:x,
y:y
}
}
f(1,2)
- 2.除了属性简写,方法也可以简写
var o = {
method(){
return 'hello'
}
};
// => 等同于
var o = {
method:function(){
return 'hello'
}
};
- 3.下面举一个简单的例子
var birthDay = '0709';
var name = 'kjh';
var person = {
name, //等同于 name:name
birthDay, //等同于 birthDay:birthDay
sayHello(){
console.log(this.name);
}
//等同于 sayHello:fucntion(){....}
}
console.log(person); //{name: "kjh", birthDay: "0709", sayHello: ƒ}
这种方法用于写函数的返回值将会非常方便
function getPoint(){
var x = 1;
var y = 10;
return {x,y};
}
var a = getPoint();
console.log(a); //{x: 1, y: 10}
重点知识2(ES6中对象的新方法 Object.is())
-
ES5中有两个运算符用来比较两个值是否相等。 == 和 === 运算符
缺点:
== 会自动转换数据类型
=== 中的NaN 不等于本身ES6 提出了 Same-value equality (同值相等)
一些例子:
Object.is('foo','foo'); //true
Object.is({},{}); //false
Object.is(+0,-0); //false
console.log( +0 == -0) //true
console.log(NaN === NaN) //false
Object.is(NaN,NaN); //true
重点知识3(ES6中的新方法Object.assign())
- Object.assign方法用于将元对象(source)的所有可枚举属性复制到目标对象(target)
- 举个例子:
//举个例子
var target = {a:1};
var source1 = {b:2};
var source2 = {c:3};
Object.assign(target,source1,source2);
console.log(target) //{a: 1, b: 2, c: 3}
//Object.assign 方法的第一个参数是目标对象,后面的参数都是源对象
- 一些特殊情况
var fina_obj = {a:1,b:1};
var test_obj1 = {b:2,c:3};
var test_obj2 = {c:4,d:5};
Object.assign(fina_obj,test_obj1,test_obj2);
console.log(fina_obj); //{a: 1, b: 2, c: 4, d: 5}
//表明: 如果目标对象与源对象有同名顺序ing,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性。
- 如果只有一个参数,Object.assign()会直接返回该参数
var fina_obj = {a:1};
console.log(Object.assign(fina_obj)); //{a:1}
console.log(Object.assign(fina_obj) === fina_obj) //true
- 非对象传入的情况
//如果传入的不是对象,会先转换为对象
console.log(Object.assign(2)); //Number(2)
console.log(typeof(Object.assign(2))); //object
//因为undefined和null无法转换为对象,所以将他们视为参数,就会报错
Object.assign(undefined) //reference error
Object.assign(null) //reference error
//如果非对象参数出现在源对象的位置(即非首参数),那么处理规则会有所不同,首先这些参数会先转换为对象,
//如果不能转换为对象便会跳过,这意味着,undefined和null在首参数便不会报错。
let obj = {a:1};
console.log(Object.assign(obj,undefined)); // {a:1}
console.log(Object.assign(obj,null)); // {a:1}
//其他类型的值不在首参数也不会报错,但是除了字符串会以数组的形式复制到目标对象,其他值都不会产生效果
var v1 = 'abc';
var v2 = true;
var v3 = 10;
var obj = Object.assign({}, v1,v2, v3);
console.log(obj); //{0: "a", 1: "b", 2: "c"}
上面的代码中,布尔值、数值、字符串分别转成对应的包装对象,可以看到它们的原始值
都在包装对象的内部属性[ [PrimitiveValu e] 上面,这个属性是不会被 Object.assign
复制的。只有字符串 包装对象会产生可枚举 实义属性,那些属性则会被拷贝。
注意:Object.assign方法实行的是千夫指,而不是深复制。
如果某个属性的值是对象,那么目标对象复制得到的是这个对象的引用
重点知识4(Object.assign()的常见用途)
- 1.为对象添加属性
let fina_obj = {
id:01,
date:'2019-12-19'
}
Object.assign(fina_obj,{name:'number_one'})
console.log(fina_obj); //{id: 1, date: "2019-12-19", name: "number_one"}
- 2.为对象添加方法
let fina_obj = {
id:01,
date:'2019-12-19'
}
Object.assign(fina_obj,{name:'number_one',sayName(){
alert(this.name);
}})
console.log(fina_obj); //{id: 1, date: "2019-12-19", name: "number_one", sayName: ƒ}
fina_obj.sayName(); //number_one
- 3.克隆对象
let fina_obj = {
name:'01',
age:20,
phoneNumber:15686942972
}
function clone(origin){
return Object.assign({},origin);
}
var new_obj = clone(fina_obj);
console.log(new_obj) // {name: "01", age: 20, phoneNumber: 15686942972}
- 4.合并多个对象
let obj1 = {
id:01
};
let obj2 = {
name:'number_one'
};
let fina_obj = {};
Object.assign(fina_obj, obj1, obj2);
console.log(fina_obj) //obj的拓展.html:240 {id: 1, name: "number_one"}
重点知识5(对象的可枚举性)
- 对象的Object.getOwnPropertyDescriptor 方法可以获取该对象某个属性的描述对象
let obj = {foo: 123};
console.log(Object.getOwnPropertyDescriptor(obj,'foo'));
//{value: 123, writable: true, enumerable: true, configurable: true}
描述对象的enumerable属性称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前的属性。
-
ES5中有三个操作会忽略enumerable为false的属性
-
for…in 循环: 只遍历对象自身的和继承的可枚举属性
-
Object.keys(): 返回对象自身的所有可枚举属性的键名
-
JSON.stringify() : 只串行化对象自身的可枚举属性
-
ES6 新增了一个操作Object.assign(),会忽略enumerable为false的属性,只复制对象自身的可枚举属性
结论:这四个操作中只有for…in会返回继承的属性。 实际上引入enumerable的最初的目的就是让某些属性可以规避掉for…in操作
比如,对象原型的tostring方法以及数组的length属性不要被for…in遍历到总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的 属性。所以,尽量不要用 for … in 循环,而用 Object. keys ()代替。- 举个例子:
-
let obj = {
name:'kjh',
id:01,
phoneNumber:15686942972
}
//for ... in
for(let k in obj){
console.log(k) // name id phoneNumber
}
//object.keys()
console.log(Object.keys(obj)); //["name", "id", "phoneNumber"]
//SON.stringify()
console.log(JSON.stringify(obj)) //{"name":"kjh","id":1,"phoneNumber":15686942972}
//Object.assign()
console.log(Object.assign(obj)); //{name: "kjh", id: 1, phoneNumber: 15686942972}
重点知识6(对象属性的遍历)
-
属性的遍历
- ES6一共有5中方法可以遍历对象的属性。
- 1.for … in
- 2.Object.keys(obj)
- 3.Object.getOwnPropertyNames(obj)
- 4.Object.getOwnPropertySymbols(obj)
- 5.reflect.ownKeys(obj)
-
举个例子
// // 举个例子:
let father_obj ={
school:'xiyou' //提供可枚举的属性给fina_obj 继承
}
let fina_obj = {
[Symbol()]: 1,
b: 2,
10: 0,
2: 0,
a: 3,
name:'kang+'
}
Object.setPrototypeOf(fina_obj,father_obj); //实现继承school属性
// 将fina_obj的name属性设置为不可枚举属性
Object.defineProperty(fina_obj,'name',{
enumerable:false
})
//没遍历之前的属性
console.log(fina_obj) //{2: 0, 10: 0, b: 2, a: 3, name: "kang+", Symbol(): 1}
1.for ... in 遍历obj
for(let k in fina_obj){
console.log(k);
}
结果: 2 10 b a school
结论:for...in 循环遍历自身的和继承来的可枚举的属性(不含Symbol属性)
——————————————————————————————————————————————————————————————————————————————————————————————————————
2.Object.keys(obj) 遍历obj
console.log(Object.keys(fina_obj));
结果:["2", "10", "b", "a"]
结论:Object keys 返回 个数组,包括对象自身的(不含继承 )所有可枚举属性(不含 Symbol属性)
——————————————————————————————————————————————————————————————————————————————————————————————————————
3.Object.getOwnPropertyNames(obj)
console.log(Object.getOwnPropertyNames(fina_obj));
结果:["2", "10", "b", "a", "name"]
结论:Object getOwnPropertyNames 返回 个数组,包含对象自身的所有属性(不含 symbol属性,但是包括不可枚举属性)
——————————————————————————————————————————————————————————————————————————————————————————————————————
4.Object.getOwnPropertySymbols(obj)
console.log(Object.getOwnPropertySymbols(fina_obj))
结果:[Symbol()]
结论:返回一个数组,返回该对象的所有symbol属性
——————————————————————————————————————————————————————————————————————————————————————————————————————
5.Reflect.ownKeys(obj)
console.log(Reflect.ownKeys(fina_obj));
结果:["2", "10", "b", "a", "name", Symbol()]
结论:以数组形式饭胡igai对象的所有属性,继承属性除外