Es6对象的扩展

属性的简写方法

var name = '秦司令';
var json = {name} // name:'秦司令'

上面代码中,变量在对象中当做属性名,属性值就是变量的值,这就是属性的简写方式。


var age = 19
var obj = {
   name:'秦司令',  
   age
}
console.log(obj) // {name:'秦司令',age:19}

函数中的声明的对象也能简写

function example(x,y){
  return {x,y}
}
console.log(example(1,2)) // {x:1,y:2} 

上面代码如果不传参,x和y的参数就是undefined。


对象里面的函数也可以简写。

var json = {
  add(){
    alert(1)
  }
}
// 上面的方法等同于下面
var json = {
  add:function(){
    alert(1)
  }
}

简写一个Generator函数,前面需要要加上 * 号

var obj = {
    * add(){
      yiled 'hello word'
    }
}

上面代码中,Generator函数等下一期跟你们分享,详细讲解。

属性名表达式

js定义对象有两种方式

var obj = {}
obj.name = '秦司令';
obj['a' + 'ge'] = 19;

上面代码中,方法一是用标识符作为对象属性名,方法二是用表达式作为属性名,这是将表达式方在中括号内,中括号内可以写变量,请看下面代码。

let age = 'age';
var json = {
  [age] :19,
  ['a' + 'bc'] : 123
}
console.log(json) // {age:19,abc:123}

表达式还可以用于定义方法名。

var obj = {
    ['a' + 'bc'](){
        return 'abc'
    }
}
console.log(obj.abc()) // abc

注意,对象的简写不能和表达式一起使用,会报错。

var name = '秦司令';
console.log({ [name] }) // 报错
console.log({ [name] : 123 }) // 秦司令:123

如果属性表达式是一个对象的话,默认情况下会自动转为字符串,[object Object] 。

var dx = {}
var json = {
  [dx]:123
}
console.log(json) // {[object Object] :123}

方法name的属性

函数的name属性,返回函数名,对象方法也是函数,因此也有name属性。

var obj = {
  add(){
    return 123
  }
}
console.log(obj.add.name) // add

上面代码,方法add的name属性就是函数名,add。


函数name属性有两种特殊情况,bind方法创造的函数,name属性返回 bound 加上函数名 ;Function 构造函数创造的函数,name属性返回anonymous 英语意思为(匿名的)

(new Function()).name // anonymous
function abc(){}
console.log(abc.bind().name) // bound abc 

如果对象方法是一个Symbol值,那么name属性返回的就是这个Symbol值的描述。

var s = Symbol('foo')
var s1 = Symbol()
let obj = {
  [s](){},
  [s1](){}
}
console.log(obj[s].name) // ['foo']
console.log(obj[s1].name) // ""

上面代码中,s对应的Symbol值有描述,s1没有

属性的可枚举性和遍历

可枚举性

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。

let obj = {foo:123};
Object.getOwnPropertyDescriptor(obj,'foo');
//  {
//    value: 123,
//    writable: true,
//    enumerable: true,
//    configurable: true
//  }

描述对象的enumerable属性称为 "可枚举性" , 如果该属性为false,就表示某些操作会忽略当前属性。


目前,有四种操作会忽略enumerable为false属性
for..in循环:只遍历对象自身和继承的可枚举性的属性
Object.keys() : 返回对象自身的所有可枚举属性的键名
JSON.stringify() : 只转换自身的可枚举性的属性
Object.assign() : 忽略enumerable为false的属性,只拷贝对象自身的可枚举性的属性

var json1 = {name:'秦司令'}
Object.defineProperty(json1,'age',{
    value:19,
    enumeable:false
})
for(var i in json1){
    console.log(i)   // name 
};
console.log(Object.keys(json1)) // ['name']
console.log(JSON.stringify(json1))  // {"name":"秦司令"}
console.log(Object.assign({},json1))  // {name: "秦司令"}

上面代码中,都获取不到enumerable为false的属性,Object.defineProperty是专门设置描述对象的属性;

属性的遍历
Object.getOwnPropertyNames(obj)

该方法返回一个数组,包含自身的所有属性(不包含Symbol属性,但是包括不可枚举属性)的键名

var json1 = {name:'秦司令'}
Object.defineProperty(json1,'age',{
    value:19,
    enumeable:false
})
console.log(Object.getOwnPropertyNames(json1)) // ["name", "age"]
Object.getOwnPropertySymbols(obj)

该方法返回一个数组,包含对象自身的所有 Symbol 属性的键名,只返回Symbol的键名。

var jsonArr = {[Symbol('123')]:1,b:2,c:9,3:'d',[Symbol()]:123}
console.log(Object.getOwnPropertySymbols(jsonArr)) //  [Symbol(123), Symbol()]
Reflect.ownKeys(obj)

该方法返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

var jsonArr = {[Symbol('123')]:1,b:2,c:9,3:'d',[Symbol()]:123}
console.log(Reflect.ownKeys(jsonArr)) // ["3", "b", "c", Symbol()]

上面代码中,Reflect.ownKeys该方法返回一个数组,返回所有的属性,这个数组的顺序是这样的,首先是数值属性,然后是字符串,按照字符串的位置加入,最后是Symbol属性

super关键字

Object.prototype.name = 'lider'
var json = {
    name:'我是json',
    add(){
        return super.name;
    }
}
console.log(json.add());

上面代码中,super该方法是指向Object的原型。


看下面的列子

var obj = {
    name:'我是obj',
    na(){
          console.log(this.name)
    }
}

var json = {
    name:'我是json',
    add(){
        return super.name;
    }
}

Object.setPrototypeOf(json,obj)
console.log(json.add()); // 我是obj

上面的代码,把json的原型改成了obj的原型,所以name属性就指向obj里面的。


super该方法现正只能,用在对象的简写方法内容。

// 报错
const obj = {
  foo: super.foo
}

// 报错
const obj = {
  foo: () => super.foo
}

// 报错
const obj = {
  foo: function () {
    return super.foo
  }
}

对象的扩展运算符

Es2018将扩展运算符引入了对象。

var [a...b] = [1,2,3]
a //1
b // 2 3 

解构赋值

对象的解构赋值用于从一个对象取值,相当于将目标对象自身所有可遍历属性(包括enumerable),但尚未被读取的属性,分配到指定的对象上面,所有的键和它们的值,都会拷贝到新对象上面。

let {x,y...z} = {x:1,y:2,c:3,d:4}
x // 1
y // 2
z // {c:3,d:4}

上面代码中,变量z是解构赋值所在的对象,它获取等号右边尚未读取的值,并且将(键值和属性值) 一同拷贝过来


解构赋值要求等号右边必须是对象,如果不是对象,就会强制转换为对象,undefined和null无法转换为对象,所以它们会报错。

let {...z} = null;
let {...a} = undefined

解构赋值必须最后一个参数是扩展运算符,否则会报错。

let {...a,b} = {a:1,b:2}

注意,解构赋值的拷贝是浅拷贝,即如果一个键值的是数组或者是对象,那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。

let obj = { a: { b: 1 } };
let { ...x } = obj;
obj.a.b = 2;
x.a.b // 2

另外,扩展运算符的解构赋值,不能复制继承的原型。

let o1 = { a: 1 };
let o2 = { b: 2 };
o2.__proto__ = o1;
let { ...o3 } = o2;
o3 // { b: 2 }
o3.a // undefined

如果扩展运算符后面是一个对象,则没有任何效果。

console.log( {...{} , a:123 } ) // {a:123}

如果扩展运算符后面不是对象,则会自动将其转为对象。

console.log({...1}) // {}

上面代码中,将其转换为对象 包装类Number{1} ,因此它没有属性则返回空对象。


如果扩展运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象。

{...'hello'}
// {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}

扩展运算符的参数之中,如有取值函数get,这个函数是会执行的。

let abc = {
    get aa(){
        return 1
    }
}
console.log(abc)

let abc1 = {
    ...{
        get aa(){
            return '我自动执行'
        }
    }
}
console.log(abc1)
希望看完这篇文章,能对你有所收获!
如有不正确的地方,望大神指点。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容

  • 1. 属性的简介表示法 varfoo ='bar'; varbaz = {foo}; baz//{foo: "ba...
    ningluo阅读 290评论 0 0
  • 属性的简洁表示法 ES6允许直接写入变量和函数,作为对象的属性和方法。 上面代码表明,ES6允许在对象之中,直接写...
    oWSQo阅读 508评论 0 0
  • 1.属性的简洁表示法 允许直接写入变量和函数 上面代码表明,ES6 允许在对象之中,直接写变量。这时,属性名为变量...
    雨飞飞雨阅读 1,134评论 0 3
  • 1.属性的简介表示法 const foo ='bar' const baz = {foo} baz //{foo:...
    yfsola阅读 229评论 0 0
  • 江湖的另一端,曾在鄱阳湖上喝酒纵歌的年轻小哥刘休范初长成。 刘休范是孝武帝之侄,但他貌似资质愚钝,从小就在长辈兄弟...
    惘然生烟阅读 691评论 0 4