当前位置:K88软件开发文章中心编程语言JavaScriptECMAScript → 文章内容

ECMAScript 6 对象的扩展

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:38:30

由 youj 创建, 最后一次修改 2016-09-20 对象的扩展属性的简洁表示法属性名表达式方法的name属性Object.is()Object.assign()属性的可枚举性属性的遍历__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()Object.values(),Object.entries()对象的扩展运算符Object.getOwnPropertyDescriptors()属性的简洁表示法ES6允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。var foo = 'bar';var baz = {foo};baz // {foo: "bar"}// 等同于var baz = {foo: foo};上面代码表明,ES6允许在对象之中,只写属性名,不写属性值。这时,属性值等于属性名所代表的变量。下面是另一个例子。function f(x, y) { return {x, y};}// 等同于function f(x, y) { return {x: x, y: y};}f(1, 2) // Object {x: 1, y: 2}除了属性简写,方法也可以简写。var o = { method() { return "Hello!"; }};// 等同于var o = { method: function() { return "Hello!"; }};下面是一个实际的例子。var birth = '2000/01/01';var Person = { name: '张三', //等同于birth: birth birth, // 等同于hello: function ()... hello() { console.log('我的名字是', this.name); }};这种写法用于函数的返回值,将会非常方便。function getPoint() { var x = 1; var y = 10; return {x, y};}getPoint()// {x:1, y:10}CommonJS模块输出变量,就非常合适使用简洁写法。var 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 };// 等同于module.exports = { getItem: getItem, setItem: setItem, clear: clear};属性的赋值器(setter)和取值器(getter),事实上也是采用这种写法。var cart = { _wheels: 4, get wheels () { return this._wheels; }, set wheels (value) { if (value < this._wheels) { throw new Error('数值太小了!'); } this._wheels = value; }}注意,简洁写法的属性名总是字符串,这会导致一些看上去比较奇怪的结果。var obj = { class () {}};// 等同于var obj = { 'class': function() {}};上面代码中,class是字符串,所以不会因为它属于关键字,而导致语法解析报错。如果某个方法的值是一个Generator函数,前面需要加上星号。var obj = { * m(){ yield 'hello world'; }};属性名表达式JavaScript语言定义对象的属性,有两种方法。// 方法一obj.foo = true;// 方法二obj['a' + 'bc'] = 123;上面代码的方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时要将表达式放在方括号之内。但是,如果使用字面量方式定义对象(使用大括号),在ES5中只能使用方法一(标识符)定义属性。var obj = { foo: true, abc: 123};ES6允许字面量定义对象时,用方法二(表达式)作为对象的属性名,即把表达式放在方括号内。let propKey = 'foo';let obj = { [propKey]: true, ['a' + 'bc']: 123};下面是另一个例子。var lastWord = 'last word';var a = { 'first word': 'hello', [lastWord]: 'world'};a['first word'] // "hello"a[lastWord] // "world"a['last word'] // "world"表达式还可以用于定义方法名。let obj = { ['h'+'ello']() { return 'hi'; }};obj.hello() // hi注意,属性名表达式与简洁表示法,不能同时使用,会报错。// 报错var foo = 'bar';var bar = 'abc';var baz = { [foo] };// 正确var foo = 'bar';var baz = { [foo]: 'abc'};方法的name属性函数的name属性,返回函数名。对象方法也是函数,因此也有name属性。var person = { sayName() { console.log(this.name); }, get firstName() { return "Nicholas"; }};person.sayName.name // "sayName"person.firstName.name // "get firstName"上面代码中,方法的name属性返回函数名(即方法名)。如果使用了取值函数,则会在方法名前加上get。如果是存值函数,方法名的前面会加上set。有两种特殊情况:bind方法创造的函数,name属性返回“bound”加上原函数的名字;Function构造函数创造的函数,name属性返回“anonymous”。(new Function()).name // "anonymous"var doSomething = function() { // ...};doSomething.bind().name // "bound doSomething"如果对象的方法是一个Symbol值,那么name属性返回的是这个Symbol值的描述。const key1 = Symbol('description');const key2 = Symbol();let obj = { [key1]() {}, [key2]() {},};obj[key1].name // "[description]"obj[key2].name // ""上面代码中,key1对应的Symbol值有描述,key2没有。Object.is()ES5比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。ES6提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。Object.is('foo', 'foo')// trueObject.is({}, {})// false不同之处只有两个:一是+0不等于-0,二是NaN等于自身。+0 === -0 //trueNaN === NaN // falseObject.is(+0, -0) // falseObject.is(NaN, NaN) // trueES5可以通过下面的代码,部署Object.is。Object.defineProperty(Object, 'is', { value: function(x, y) { if (x === y) { // 针对+0 不等于 -0的情况 return x !== 0 || 1 / x === 1 / y; } // 针对NaN的情况 return x !== x && y !== y; }, configurable: true, enumerable: false, writable: true});Object.assign()基本用法Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。var target = { a: 1 };var source1 = { b: 2 };var source2 = { c: 3 };Object.assign(target, source1, source2);target // {a:1, b:2, c:3}Object.assign方法的第一个参数是目标

[1] [2] [3] [4] [5]  下一页


ECMAScript 6 对象的扩展