属性初始值的简写

当对象字面量只有一个属性的名称时,JS引擎会在可访问作用域中查找其同名变量;如果找到则该变量的值被赋给对象字面量里的同名属性

function createPerson(name, age) {
return {
name,
age
}
}

对象方法的简写

var person = {
name: 'angela',
sayName() {
console.log(this.name)
}
}

可计算属性名

在ES5中如果属性名中包含空格或者是动态的字符串变量作为属性名,则需要用[]方括号来访问,如下所示

var person = {},
lastName = 'last name';
person["first name"] = 'Li'
person[lastName] = 'yun hua'

这种方式适用于属性名提前已经或可被字符串字面量表示的情况,如果属性名“first name”被包含在一个变量中或者需要通过计算才得到该变量的值
ES6支持了可计算属性名
比方说上面的代码ES6可简化写成如下:

let lastName = 'last name';
var person = {
"first name": 'Li',
[lastName]: 'yun hua'
}

甚至方括号中内容同样可以使用表达式作为属性的可计算名称

var suffix = 'name'
var person = {
['first ' + suffix]: 'Li',
['last ' + suffix]: 'yun hua'
}

也就是说任何可用于对象实例括号记法的属性名同样可以作为对象字面量中计算属性名

Object.is

由于全等===有一些特例:1、+0和-0相等 2、NaN和NaN不完全相等
故ES6引用了Object.is方法来弥补全等运算符的不准备运算
对Object.is方法来说,其运算结果大部分情况与===运算符相同,唯一区别在于+0和-0被识别为不相等,NaN和NaN被识别为相等

Object.assign

Object.assign方法接受任意数量的源对象,并按指定的顺序将属性复制到接收对象中,所以如果多个源对象具有同名属性,则排位靠后的源对象会覆盖排位靠前的
有一个需要特别注意的点是Object.assign方法不能将提供者的访问器属性复制到接收对象中,由于Object.assign执行了赋值操作,因此提供者的访问器属性最终会被转变为接收对象中的一个数据属性

var receiver = {},
supplier = {
get name() {
return "file.js"
}
}
Object.assign(receiver, supplier)
var desc = Object.getOwnPropertyDescriptor(receiver, "name")
console.log(desc.value)//file.js
console.log(desc.get)//undefined

重复的对象字面量属性

在ES5严格模式下,对于对象字面量重复属性则会抛出错误
但在ES6严格模式下,不会报错,取值会选取最后一个

'use strict'
var person = {
name: 'lisa',
name: 'angela'
}
console.log(person.name)//angela

自有属性的枚举顺序

  1. 所有数字键按升序排序

  2. 所有字符串按照它们被加入对象的顺序排序

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

var obj = {
a: 1,
0: 1,
c: 1,
2: 1,
b: 1,
1: 1
}
obj.d = 1
console.log(Object.getOwnPropertyNames(obj).join(''))//012acbd

改变对象的原型

ES5中可以通过Object.getPrototypeOf来返回任意指定对象的原型
ES6中添加了Object.setPrototypeOf来改变任意指定对象的原型

var person = {
getGreeting() {
return 'hello'
}
}
var dog = {
getGreeting() {
return 'woof'
}
}
let friend = Object.create(person)
console.log(friend.getGreeting())//hello
console.log(Object.getPrototypeOf(friend) === person)//true
Object.setPrototypeOf(friend, dog)
console.log(friend.getGreeting())//woof
console.log(Object.getPrototypeOf(friend) === dog)//true

简化了原型访问的Super引用

在ES5中如果要调用父类的方法,则一般是通过如果这种方式,也就是获得原型对象再通过call来调用
Object.getPrototypeOf(this).getGreeting.call(this)

var person = {
getGreeting() {
return 'hello'
}
}
var dog = {
getGreeting() {
return 'woof'
}
}
var friend = {
getGreeting() {
return Object.getPrototypeOf(this).getGreeting.call(this) + ",hi!";
}
}
Object.setPrototypeOf(friend, person)
console.log(friend.getGreeting())//hello,hi!
console.log(Object.getPrototypeOf(friend) === person)//true
Object.setPrototypeOf(friend,dog)
console.log(friend.getGreeting())//woof,hi!
console.log(Object.getPrototypeOf(friend) === dog)//true

但是在多重继承的情况下,上述方法则会出错,举例来说

var person = {
getGreeting() {
return 'hello'
}
}
var friend = {
getGreeting() {
return Object.getPrototypeOf(this).getGreeting.call(this) + ",hi!";
}
}
Object.setPrototypeOf(friend, person)
var relative = Object.create(friend)
console.log(person.getGreeting())//hello
console.log(friend.getGreeting())//hello,hi!
console.log(relative.getGreeting())// 报错 Uncaught RangeError: Maximum call stack size exceeded

ES6中通过super关键字可轻松解决问题

var person = {
getGreeting() {
return 'hello'
}
}
var friend = {
getGreeting() {
return super.getGreeting.call(this) + ",hi!";
}
}
Object.setPrototypeOf(friend, person)
var relative = Object.create(friend)
console.log(person.getGreeting())//hello
console.log(friend.getGreeting())//hello,hi!
console.log(relative.getGreeting())// hello,hi

大家可能会疑惑super是怎么做到知道真正的调用对象是哪个
这其实是因为ES6中正式将方法定义为一个函数,它会有一个内部的[[HomeObject]]属性来容纳这个方法从属的对象

var person = {
// 是方法
getGreeting() {
return 'hello'
}
}
function shareGreeting(params) {
return 'Hi!'
}

person.getGreeting方法的[[HomeObject]]属性为person,而shareGreeting函数未将其赋值给一个对象,因而没有明确定义其[[HomeObject]]属性

super的所有引用都通过[[HomeObject]]属性来确定后续的运行过程

  1. 在[[HomeObject]]属性上调用Object.getPrototypeOf方法来检索原型的引用

  2. 搜索原型找以同名函数

  3. 设置this绑定并调用相应的方法

深入理解ES6之《扩展对象》的更多相关文章

  1. 《深入理解ES6》笔记——扩展对象的功能性(4)

    变量功能被加强了.函数功能被加强了,那么作为JavaScript中最普遍的对象,不加强对得起观众吗? 对象类别 在ES6中,对象分为下面几种叫法.(不需要知道概念) 1.普通对象 2.特异对象 3.标 ...

  2. 深入理解 ES6中的 Reflect

    阅读目录 一:Reflect.get(target, name, receiver) 二:Reflect.set(target,name,value,receiver) 三:Reflect.apply ...

  3. ES6的promise对象研究

    ES6的promise对象研究 什么叫promise? Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码:让代码更加的直观. 那我们为什么 ...

  4. ES6正则表达式扩展

    前面的话 正则表达式是javascript操作字符串的一个重要组成部分,但在以往的版本中并未有太多改变.然而,在ES6中,随着字符串操作的变更, ES6也对正则表达式进行了一些更新.本文将详细介绍ES ...

  5. ES6函数扩展

    前面的话 函数是所有编程语言的重要组成部分,在ES6出现前,JS的函数语法一直没有太大的变化,从而遗留了很多问题和的做法,导致实现一些基本的功能经常要编写很多代码.ES6大力度地更新了函数特性,在ES ...

  6. ES6数组扩展

    前面的话 数组是一种基础的JS对象,随着时间推进,JS中的其他部分一直在演进,而直到ES5标准才为数组对象引入一些新方法来简化使用.ES6标准继续改进数组,添加了很多新功能.本文将详细介绍ES6数组扩 ...

  7. ES6数字扩展

    前面的话 本文将详细介绍ES6数字扩展 指数运算符 ES2016引入的唯一一个JS语法变化是求幂运算符,它是一种将指数应用于基数的数学运算.JS已有的Math.pow()方法可以执行求幂运算,但它也是 ...

  8. ES6,扩展运算符的用途

    ES6的扩展运算符可以说是非常使用的,在给多参数函数传参,替代Apply,合并数组,和解构配合进行赋值方面提供了很好的便利性. 扩展运算符就是三个点“...”,就是将实现了Iterator 接口的对象 ...

  9. 理解 ES6 Generator-next()方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 前端知识体系:JavaScript基础-原型和原型链-理解 es6 中class构造以及继承的底层实现原理

    理解 es6 中class构造以及继承的底层实现原理 原文链接:https://blog.csdn.net/qq_34149805/article/details/86105123 1.ES6 cla ...

随机推荐

  1. Python:HTTP请求头headers信息的查询

    GET和POST请求后会返回一个response对象,可通过key.values等访问字典中元素的方式来访问该response对象headers中的各种属性 r=requests.get(url,he ...

  2. Django的orm(一)

    Django的orm一 1.创建表 1.1 创建普通表 class UserType(models.Model): ''' 用户类型 ''' title=models.CharField(max_le ...

  3. mysql通过mysqldunp命令重做从库详细操作步骤

    mysql通过mysqldunp命令重做从库详细操作步骤 背景 生产环境上的主从复制集群,因为一些异常或人为原因,在从库做了一些操作,导致主从同步失败.一般修复起来比较麻烦,通过重做mysql从库的方 ...

  4. 写下载的时候,axios的responseType: "blob"(一定要修改)

    download(data, fileName) {       // window.URL.createObjectURL创建一个地址.       const url = window.URL.c ...

  5. think php 删除

    表单页面 <a href="/examtest/test/edit/id/{$v['id']}">修改</a> <a href="/exam ...

  6. LGP3092题解

    看 DP 的时候翻到的题,发现这题的坑鸽子了一年半 这个状态感觉比较厉害,还是来记录一下吧. 首先硬币数量很少让我们想到状压,可以想出来一个十分 navie 的状态:\(dp[S][n]\) 表示用过 ...

  7. Python之简单的用户名密码验证

    题目要求: 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定   #要求使用文件存储用户名和密码,每次从文件读入用户名和密码用来验证,如果输错三次密码该账户会被锁定,并讲锁定的用户名写入文件 # ...

  8. javascript、css3曲线运动示例记录

    想做一个加入购物车的曲线动效,网上找到两个demo,分别是js和css3实现的. js:https://www.cnblogs.com/wangmeijian/p/5824176.html jquer ...

  9. 导入导出笔记-easyExcel初探(表格导入和模板化导出)

    前言 本文使用的EasyExcel Alibaba和EasyPoi Apache技术栈分析 EasyExcel Dependency EasyPoi Dependency 1.需求一:表格化需求导入导 ...

  10. 电子检索实体书「GitHub 热点速览 v.22.12」

    不知道有没有小伙伴遇到实体书快速定位指定内容的问题,凭借着记忆里很难快速翻阅到正确的页数,但 paperless-ngx 也许能帮上你的忙,它除了能将你的实体书籍电子化变成文件库里的一员之外,还能帮你 ...