ES6对象属性名简洁表示法和表达式对象新方法属性的遍历
Posted 易函123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6对象属性名简洁表示法和表达式对象新方法属性的遍历相关的知识,希望对你有一定的参考价值。
概览
对象属性的简洁表示法
ES6允许直接写入变量和函数作为对象的属性和方法。
ES6允许在对象中只写属性名,不写属性值。
let foo = \'bar\';
let baz = {foo};
console.log(baz); // {foo:\'bar\'}
// same as
let baz1 = {foo:foo}
console.log(baz1); // {foo:\'bar\'}
let first = \'Jone\';
let last = \'Doe\';
let obj = {first,last};
console.log(obj); // {first: "Jone", last: "Doe"}
// same as
let obj1 = {first:first,last:last};
console.log(obj1); // {first: "Jone", last: "Doe"}
const HELLO = {
method(){
return \'hello\'
}
}
console.log(HELLO.method()); // \'hello\'
// same as
const HELLO1 = {
method:function(){
return \'hello\'
}
}
console.log(HELLO1.method()); // \'hello\'
实际运用中的一些例子:
// 用于人物名称及行为的对象
let birth = \'2000/01/01\'
const PERSON = {
name: \'张三\',
birth, // same as: birth:birth
hello() {console.log(\'我的名字是\', this.name);}
// same as: hello:function(){...}
}
// 用于函数返回值
function getPoint(x = 1, y=10){
return {x, y}
}
console.log(getPoint()); // {x: 1, y: 10}
console.log(getPoint(3,3)); // {x: 3, y: 3}
console.log(getPoint(3)); // {x: 3, 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};
// same as: module.exports = {getItem:getItem,setItem:setItem,clear:clear};
// 属性的赋值器和取值器
const CART = {
_wheels: 4,
get wheels(){
return this._wheels;
},
set wheels(value){
if(value<this._wheels){
throw new Error(\'数值太小了\');
}
this._wheels = value;
}
}
属性名表达式
ES6允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内。
定义对象属性的两种方法:
通过固定名称
let obj = {}; obj.foo = true; console.log(obj); // {foo: true}
通过表达式
let obj1 = {}; obj1[\'a\'+\'bc\'] = 123; console.log(obj1); // {abc: 123}
let propKey = \'foo\';
let propKeyObj = {
[propKey]: true,
[\'a\'+ \'bc\']: 123
}
console.log(propKeyObj); // {foo: true, abc: 123}
let lastWord = \'last word\';
let a = {
\'first word\':\'hello\',
[lastWord]:\'world\'
}
console.log(a); // {first word: "hello", last word: "world"}
console.log(a[\'first word\']);// \'hello\'
console.log(a[lastWord]); // \'world\'
console.log(a[\'last word\']); // \'world\'
// 定义方法名
let methodName = {
[\'h\'+\'ello\'](){
return \'hi\'
}
}
console.log(methodName.hello()); // \'hi\'
注意:属性名表达式不能和简洁表达式同时使用
// 报错
let foo = \'bar\';
let bar = \'abc\';
let baz = {[foo]};
注意:属性表达式如果是一个对象,默认情况下会把对象转为字符串[object Object]
const keyA = {a:1};
const keyB = {b:2};
const myObject = {
[keyA]: \'valueA\',
[keyB]: \'valueB\',
}
console.log(myObject); // {[object Object]: "valueB"}
Object.is(value1,value2)
与严格相等运算符(===)的行为基本一致;
解决严格运算符(===)NaN
不等于自身,以及+0等于-0的问题。
console.log(Object.is(\'foo\',\'foo\'));; // true
console.log({} === {}); // false
console.log(Object.is({},{})); // false
console.log(NaN === NaN); // false
console.log(Object.is(NaN,NaN)); // true
console.log(+0 === -0); // true
console.log(Object.is(+0,-0)); // false
console.log([0,NaN,2].indexOf(NaN)); // -1
console.log([0,NaN,2].findIndex(x => Object.is(x, NaN))); // 1
Object.assign(target,source_1,source_2,...)
Object.assign()
方法将源对象(source)所有可枚举的属性合并到目标对象(target)中:它修改target,首先将source_1的所有可枚举的自己的属性复制到target中,然后将source_2的所有自己的属性复制到target中,以此类推。最后,它返回target。
let target = {a:1};
let source_1 = {b:2};
let source_2 = {c:3};
Object.assign(target,source_1,source_2);
console.log(target,source_1,source_2); // {a: 1, b: 2, c: 3} {b: 2} {c: 3}
让我们更仔细看看Object.assign()
是如何运作的:
两种类型的属性键:同时支持
String
、Symbel
作为属性键;let v1 = \'abc\'; let v2 = true; let v3 = 10; let v4 = {[Symbol(\'c\')]: \'c\'}; const obj = Object.assign({}, v1, v2, v3, v4); console.log(obj); // {0: "a", 1: "b", 2: "c", Symbol(c): "c"}
仅复制源对象可枚举的自身属性:不复制继承属性,也不复制不可枚举的属性;
const obj = Object.assign({b: \'c\'}, Object.defineProperty({}, \'invisible\',{ enumerable:false, // enumerable属性称为‘可枚举性’ value:\'hello\' }) ) console.log(obj); // {b: "c"}
通过赋值复制:目标对象中的属性是通过赋值(内部操作[[Put]])创建的。这意味着,如果
target
拥有(自己的或继承的)setter
,则在复制期间将调用这些setter
。另一种方法是定义新的属性,这是一种总是创建新的自己的属性且从不调用setter
的操作。最初有人建议使用Object.assign()
的一个变体,它使用定义而不是赋值的方式。这个提议在ECMAScript 6中已经被拒绝了,但是在以后的版本中可能会被重新考虑。let obj1 = {a: {b: 1}}; let obj2 = Object.assign({}, obj1); console.log(obj2); // {a: {b: 1}}
// Object.assign()方法实行的是浅复制,而不是深复制。
let target = {a: { b: \'c\', d: \'e\' }};
let source = {a: { b: \'hello\' }};
const obj = Object.assign(target, source);
console.log(obj); // a: {b: "hello"}
console.log(target); // a: {b: "hello"}
常见用途:
**为对象添加属性**
class Point{
constructor(x, y){
Object.assign(this, {x, y});
}
}
**为对象添加方法**
function SomeClass(){
}
Object.assign(SomeClass.prototype, {
someMethod(arg1,arg2){
// ...
},
anotherMethod(){
// ...
}
})
console.dir(SomeClass);
// same as
SomeClass.prototype.someMethod = function(arg1, arg2){
//...
};
SomeClass.prototype.anotherMethod = function(){
//...
}
**克隆对象**
// 克隆原始对象自身的值
function clone1(origin){
return Object.assign({}, origin);
}
// 克隆原始对象继承的值(保持继承链)
function clone2(params) {
let paramsProto = Object.getPrototypeOf(params);
return Object.assigin(Object.create(paramsProto), params)
}
**合并多个对象**
// 多个对象合并到target
const merge1 = (target, ...sources) => Object.assign(target, ...sources);
// 多对象合并返回新对象
const merge2 = (...sources) => Object.assign({}, ...sources);
**为属性指定默认值**
const DEFAULTS = {
logLevel: 0,
output: \'html\'
};
function processContent(options){
options = Object.assign({},DEFAULTS,options);
console.log(options);
}
processContent(\'abc\'); // {0: "a", 1: "b", 2: "c", logLevel: 0, output: "html"}
processContent({\'abc\':\'abc\'}); // {logLevel: 0, output: "html", abc: "abc"}
### 属性的遍历
> `for...in`、`Object.keys(obj)`、`Object.getOwnPropertyNames(obj)`、`Object.getOwnPropertySymbels(obj)`、`Reflect.ownKeys(obj)`
function allObj(){
this.name = \'张三\'; // 自有属性
this.age = \'12\'; // 自有属性
this.invisible = {
enumerable: false,
value: \'hello\'
},
this.invisible = {
enumerable: false,
value: \'hello\'
}
}
allObj.prototype.disEnum = {
enumerable: false,
value: \'disEnum\'
}
allObj.prototype.Enum = {
enumerable: true,
value: \'Enum\'
}
let obj = new allObj
Object.assign(obj, {
a: \'1\',
b: \'2\',
c: \'3\',
})
// let obj2 = Object.assign(obj1,
// Object.defineProperty({}, )
// )
Object.assign(obj,
Object.defineProperty({}, \'visible\',{
enumerable: true,
value: \'word\'
})
)
console.log(obj); // allObj {a: "1",age: "12",b: "2",c: "3",invisible: {enumerable: false,value: \'hello\'},name: "张三",visible: "word",Symbol(c): "c",__proto__:Enum: {enumerable: true, value: "Enum"},disEnum: {enumerable: false, value: "disEnum"}}
// for...in循环遍历对象自身的和继承的属性(不含Symbol属性)
for(let key in obj){
console.log(key);
// name
// age
// invisible
// a
// b
// c
// invisible
// visible
// disEnum
// Enum
}
// Object.keys()返回一个数组,包括对象自身(不含继承的)的所有属性(不含Symbol属性)
console.log(Object.keys(obj)); // ["name", "age", "invisible", "a", "b", "c", "visible"]
// Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性 )
console.log(Object.getOwnPropertyNames(obj)); // ["name", "age", "invisible", "a", "b", "c", "visible"]
// Object.getOwnPropertySymbols() 返回一个数组,包含所有对象自身的所有Symbol属性
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(c)]
// Reflect.ownKeys()返回一个数组,包含对象自身的所有属性,不管属性名是Symbol还是字符串,也不管是否可枚举
console.log(Reflect.ownKeys(obj)); // ["name", "age", "invisible", "a", "b", "c", "visible", Symbol(c)]
以上是关于ES6对象属性名简洁表示法和表达式对象新方法属性的遍历的主要内容,如果未能解决你的问题,请参考以下文章