前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小结ES6基本知识点(五):对象的扩展

小结ES6基本知识点(五):对象的扩展

原创
作者头像
前端林子
修改2019-03-23 09:20:13
2.3K0
修改2019-03-23 09:20:13
举报
文章被收录于专栏:前端技术总结前端技术总结

0,本文适合人群和主要内容

ES6初学者,通过阅读本文可对ES6知识点有个大体的概念,强烈建议阅读阮一峰大大的ES6入门

老司机可以直接绕路。

上一节主要是总结了ES6中和数组有关的内容。本节主要总结ES6中对象的扩展,具体内容包括以下几个方面:

会介绍以下内容:

1.ES6对象字面量

1.1简化对象属性定义

验证(1)

简化属性定义:

代码语言:javascript
复制
            // ES5
            function test(name, age) {
                return {
                    name: name,
                    age: age
                }
            }
            // 等价于
            function test(name, age) {
                return {
                    name,
                    age
                }
            }

当一个对象的属性和本地变量同名时,可以简单地中写属性名。

1.2对象方法简写

验证(2)

对象方法可以简写,去掉冒号和function关键字:

代码语言:javascript
复制
            // ES5
            var person = {
                name: "Peter",
                age: 26,
                showAge: function () {
                    console.log('age is', this.age)
                }
            }
            // 等价于
            var person = {
                name: "Peter",
                age: 26,
                showAge() {
                    console.log('age is', this.age)
                }
            }

1.3同一个对象定义多个同名属性不报错

验证(3)

同一个对象定义多个同名属性不报错

代码语言:javascript
复制
var person = {
    name:'Peter',
    name:'Tom'
}
console.log(person.name) // Tom

ES5在严格模式下会去校验是否有同名属性,ES6则无论在严格模型下,还是非严格模式下,都不会去校验属性是否重复。

2.Object.is()和Object.assing()

2.1Object.is()

有些像“===”运算符,可接受两个参数进行比较。如果两个参数的类型一致,并且值也相同,则返回true。

验证:

代码语言:javascript
复制
console.log(Object.is(1,"1")); // false 

Object.is()和===运算符的区别:

代码语言:javascript
复制
console.log(Object.is(+0, -0)); // false
console.log(+0 === -0); // true

console.log(Object.is(NaN, NaN)) // true
console.log(NaN === NaN) // false

2.2Object.assign(target,source1,source2,...)

返回第一个接收对象,可以接受任意个源对象,如果多个源对象有相同的属性,则后面的会覆盖前面的。

验证(1):

代码语言:javascript
复制
            var target = {};
            Object.assign(target, {
                name: 'tony',
                age: '24'
            })
            console.log(target) // {name: "tony", age: "24"}    

验证(2)

如果后面的多个源对象source1,source2有同名的属性,则后面的源对象会覆盖前面的

代码语言:javascript
复制
            var target = {};
            Object.assign(target, {
                name: 'tony',
                age: '24'
            }, {
                    age: '28'
                })
            console.log(target) // {name: "tony", age: "28"}    

验证(3)

代码语言:javascript
复制
            var target = {};
            function source() { }
            source.prototype = {
                constructor: source,
                hello: function () { console.log('hello~~') }
            }
            Object.assign(target, source.prototype)
            target.hello(); //hello~~    

验证(4)

忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。

代码语言:javascript
复制
            var target = {};
            var source1 = {
                age: '24'
            }
            function Person(name) {
                this.name = name;
            }
            Person.prototype.hello = function () {
                console.log(this.name)
            }
            var source2 = new Person("tony");
            // 使用Object.defineProperty()为source2对象定义一个名为hobby的属性,且设定为可枚举的
            Object.defineProperty(source2, "hobby", {
                enumerable: true,
                value: 'reading'
            })

            Object.assign(target, source1, source2)
            console.log(target) // {age: "24", name: "tony", hobby: "reading"}        

去掉上述enumerable属性(默认为false),再看下结果:

代码语言:javascript
复制
            var target = {};
            var source1 = {
                age: '24'
            }
            function Person(name) {
                this.name = name;
            }
            Person.prototype.hello = function () {
                console.log(this.name)
            }
            var source2 = new Person("tony");
            // 使用Object.defineProperty()为source2对象定义一个名为hobby的属性,且设定为不可枚举的
            Object.defineProperty(source2, "hobby", {
                value: 'reading'
            })

            Object.assign(target, source1, source2)
            console.log(target) // {age: "24", name: "tony"}    

可以看出Object.assign()会忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。

【补充】有四个操作会忽略enumerable为false的属性,即不可枚举的属性:

for...in循环:只遍历对象自身的和继承的可枚举的属性。

Object.keys():返回对象自身的所有可枚举的属性的键名。

JSON.stringify():只串行化对象自身的可枚举的属性。

Object.assign():只拷贝对象自身的可枚举的属性。

3.定义了自身属性枚举顺序

自有属性枚举顺序的基本规则:

1,所有数字键按升序排序;

2,所有字符串键按它们被加入对象的顺序排序;

3,所有symbol键按照它们被加入对象的顺序排序;

验证(1):

可以用Object.getOwnPropertyNames(obj)方法查看对象自身的所有属性(不含Symbol属性,包含不可枚举属性)的键名。

代码语言:javascript
复制
            var obj = {
                2: 1,
                name: 'tony',
                0: 1,
                age: '24',
                hobby: 'reading',
                1: 1
            }
            console.log(Object.getOwnPropertyNames(obj)) // ["0", "1", "2", "name", "age", "hobby"]

可以看出,字符串键是跟在数值键之后,数值键按升序排序,字符串键按加入对象的顺序排序。

【补充】:

ES6 一共有 5 种方法可以遍历对象的属性。

(1)for...in

for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

(2)Object.keys(obj)

Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

(3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

(4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

(5)Reflect.ownKeys(obj)

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

以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

4.创建对象后修改对象原型:Object.setPrototypeOf()

Object.setPrototypeOf()方法的作用:改变任意指定对象的原型,接受两个参数:

  -- 被改变原型的对象

  -- 替代第一个参数原型的对象

验证(1):

代码语言:javascript
复制
            var dog = {
                hello() {
                    console.log('a dog barks')
                }
            }
            var person = {
                hello() {
                    console.log('say hello')
                }
            }

            // 以person为原型
            var person1 = Object.create(person);
            person1.hello(); // say hello
            console.log(person.isPrototypeOf(person1)) // true

            // 将person1的原型设置为dog
            Object.setPrototypeOf(person1, dog)
            person1.hello(); // a dog barks
            console.log(person.isPrototypeOf(person1)) // false
            console.log(dog.isPrototypeOf(person1)) // true

说明:person1的原型原本是person,通过Object.setPrototypeOf(person1,dog)后,把person1的原型设置为了dog。

5.super关键字

ES5中,this关键字总是指向函数所在的当前对象。

ES6 中的关键字super,指向当前对象的原型对象。

验证(1):

可以用super更方便地访问对象的原型,来引用对象原型上所有的方法。

ES5:

代码语言:javascript
复制
            var dog = {
                hello() {
                    return 'a dog barks'
                }
            }
            var person = {
                hello() {
                    return 'say hello'
                }
            }
            var friend = {
                hello() {
                    let msg = Object.getPrototypeOf(this).hello.call(this)
                    console.log(msg);
                }
            }
            Object.setPrototypeOf(friend, dog);
            friend.hello(); // a dog barks
            Object.setPrototypeOf(friend, person);
            friend.hello(); // say hello    

Object.getPrototypeOf(this)就是指向对象的原型,ES6中可以用super替换:

代码语言:javascript
复制
Object.getPrototypeOf(this).hello.call(this)
// 等价于
super.hello()
代码语言:javascript
复制
            var dog = {
                hello() {
                    return 'a dog barks'
                }
            }
            var person = {
                hello() {
                    return 'say hello'
                }
            }
            var friend = {
                hello() {
                    let msg = super.hello()
                    console.log(msg);
                }
            }
            Object.setPrototypeOf(friend, dog);
            friend.hello(); // a dog barks
            Object.setPrototypeOf(friend, person);
            friend.hello(); // say hello

从结果可以看出效果是一样的。

验证(2)

必须要在简写方法的对象中使用super,其他地方声明中使用则会报语法错误。

代码语言:javascript
复制
Uncaught SyntaxError: 'super' keyword unexpected here

还是上面的示例:

代码语言:javascript
复制
         var dog = {
                hello() {
                    return 'a dog barks'
                }
            }
            var person = {
                hello() {
                    return 'say hello'
                }
            }
            var friend = {
                hello: function () {
                    let msg = super.hello()
                    console.log(msg);
                }
            }
            Object.setPrototypeOf(friend, dog);
            friend.hello();
            Object.setPrototypeOf(friend, person);
            friend.hello(); // Uncaught SyntaxError: 'super' keyword unexpected here

6.小结

本节内容主要总结了ES6中对象的一些扩展。包括对象字面量上的变更、Object.is()(注意下和===的区别)、Object.assign()方法,对象自身属性的枚举属性的顺序、Object.setPrototypeOf()方法可以在创建对象后改变它的原型,以及可以通过super关键字调用对象原型的方法。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.ES6对象字面量
    • 1.1简化对象属性定义
      • 1.2对象方法简写
        • 1.3同一个对象定义多个同名属性不报错
        • 2.Object.is()和Object.assing()
          • 2.1Object.is()
            • 2.2Object.assign(target,source1,source2,...)
            • 3.定义了自身属性枚举顺序
            • 4.创建对象后修改对象原型:Object.setPrototypeOf()
            • 5.super关键字
            • 6.小结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档