前言:因为之前看过很多的博客啊,书籍啊但是最后都雁过无痕,再问我基本没什么印象,所以就迫使自己看书的时候记点笔记,因为懒得写字[捂脸],现在是打字比写字要快好多,所以就写博客吧!

ES6规范明确定义了对象的每种类别:1,普通对象 ;2:奇异对象;3 标准对象;4内置对象。

对象字面量语法的拓展:

ES5中对象字面量是简单的“键/值对”集合,这意味着初始化属性值的代码可能会有些重复:

function createPeople(name,age){
return {
name:name,
age:age
}
}
  function createPeople(name,age){
     return {
         name,
         age
     }
  }

这个函数创建了一个对象,其属性名和函数的参数名相同,看起来是重复了name和age。键值是重复的。ES6中可以简单书写名称省略冒号和值。当对象字面量中的属性只有名称时,JS引擎会在周边作用域查找同名变量。若找到就赋值给同名属性。

方法简写:

var person = {
name:'Miya',
sayName:function(){
console.log(this.name);
}
} var person = {
name:"Miya",
sayName(){
console.log(this.name);
}
}
person.sayName(); //Miya

方法简写能使用super,非简写方法则不能。

可计算属性名:

方括号允许指定变量或者字符串字面量为属性名。

var person = {},lastName = "last name";
person["age"] = "26";
person[lastName] = "Miya";
console.log(person) //{age: "26", last name: "Miya"}

lastName变量的值为"last name",属性名中包含空格,这种情况无法用小数点表示法进行属性的访问,而方括号表示法允许将任意字符串用作属性名。

如果属性名事先已知,可以使用字符串字面量表示,但是,如果属性名被包含在变量中,或则和必须通过计算获得,那么ES5中就无法对对象字面量定义这种属性。

ES6中,可计算属性名是对象字面量语法的一部分,用方括号表示。

var lastName = "last name";
var person = {
"first name":"Miya",
[lastName]:"Tang"
}
console.log(person[lastName]) //Tang
  var suff = " name";
  var person = {
   [`first ${suff}`]:"Miya",
   [`last ${suff}`]:"Tang"
  }
  console.log(person); //{first name: "Miya", last name: "Tang"}

对象字面量中的方括号表明该属性名需要计算,其结果是一个字符串,那么其中就可以包含表达式了。类似上面的形式。使用方括号表示法,任何能放在对象实例方括号内的东西,都可以作为可计算属性名用在对象字面量中。

新的方法:

从ES5开始就有一个设计意图:避免创建新的全局变量,避免在Object原型上添加新的方法,尽量尝试将新方法添加到合适的对象上。ES6在Object对象上引入了两个新方法:

Object.is()和Object.assin()

JS中进行比较两个值时,会使用(==)和(===),为了避免强制类型转换,开发者更倾向于使用严格相等运算符。但是严格相等也不是完全准确,例如:+0和-0相等,NaN ===NaN,会返回false,因此只有isNaN函数才能正确金策NaN。

ES6的Object.is()方法来弥补严格相等运算符残留的怪异缺陷。方法中接受两个参数,看下面的栗子:

console.log(+0 === -0)  //true
console.log(Object.is(+0,-0)) //false console.log(NaN === NaN) //false
console.log(Object.is(NaN,NaN)) //true console.log(5 == '5') //true
console.log(Object.is(5,"5")); //false

Object.assign()方法:

混入(Mixin)是JS中组合对象时最流行的模式。

function mixin(receiver,supplier){
Object.keys(supplier).forEach(function(key){
receiver[key] = supplier[key];
})
return receiver;
}

minxin()函数在supplier对象的自我属性上进行迭代。将这些属性赋值到receiver对象上(浅复制,当属性值为对象时,仅复制其引用),receiver对象就能获得新的属性而无须使用继承。

各式各样的库中都有相似但是名称不同的方法,流行的有:extend()或者minx(),基本功能都相同。还有一个Object.mixin()方法,但是Object.mixin()也会赋值访问器属性,考虑到super的使用,此方法最终被移除了。

var receiver = {};
var obj1 = {type:'js',name:"file.js"};
var obj2 = {type:'css'}
Object.assign(receiver,obj1,obj2)
{type: "css", name: "file.js"}

在接收对象中,后面的源对象属性会覆盖前面的。注意点:Object.assing()不能将源对象的访问器属性复制到接收对象中,由于源对象的访问器属性会转变成接收对象的数据属性。

var receiver = {};
var supplier = {
get name(){
return "file.js"
}
};
Object.assign(receiver,supplier);
console.log(receiver);
//{name: "file.js"}

重复的对象字面量属性:

ES5中严格模式下重复对象字面量属性会报错。ES6移除了重复属性的检查,无论是否是严格模式,当存在重复属性时,排在后面的属性的值会成为该属性的实际值。

"use strict";
var person = {
name:"miya",
name:'tang'
}
console.log(person)
//{{name: "tang"}}

自有属性的枚举顺序:

ES5没有定义对象属性的枚举顺序,ES6则严格定义了对象自有属性在被枚举时候的返回顺序。

var person = {
name:"miya",
age:'26',
sex:'female'
}
Object.getOwnPropertyNames(person)
(3) ["name", "age", "sex"]
Reflect.ownKeys(person)
(3) ["name", "age", "sex"]
var obj = {
a:1,
0:1,
c:1,
2:1,
b:1,
1:1
}
obj.d = 1;
console.log(Object.getOwnPropertyNames(obj).join("")) //'012acbd'

基本顺序:1,所有的数字类型,按照升序排列。2,字符串类型按被添加到对象的顺序排列。3,符号类型键按添加顺序来。

更强大的原型:

一般情况,对象的原型会通过构造器或者Object.create()方法创建对象时指定。ES6通过添加Object.setPrototypeOf()方法允许你修改任意指定对象的原型。接受两个参数,需要被修改原型对象,将会成为前者原型的对象。栗子如下:

let person = {
getGreeting(){
return "hello"
}
}
let dog = {
getGreeting(){
return "Woof"
}
} let friend = Object.create(person);
console.log(friend.getGreeting()) //hello
console.log(Object.getPrototypeOf(frined) === person) //true Object.setPrototypeOf(friend,dog);
console.log(friend.getGreeting()) //Woof
console.log(Object.getPrototypeOf(friend) === dog) //true

可以看出:Object.setPrototypeOf()方法能够修改对象的原型。

使用super引用的简单原型访问:

super引用能够更轻易地在对象原型上进行功能调用。

let person = {
getGreeting(){
return "hello"
}
}
let dog = {
getGreeting(){
return "Woof"
}
}
let friend = {
getGreeting(){
//原型上的getGreeting方法调用本身this对象
return Object.getPrototypeOf(this).getGreeting.call(this)+',hi!';
}
} //使用super进行简化
let friend = {

getGreeting(){
        //原型上的getGreeting方法调用本身this对象
        return super.getGreeting()+',hi!';
     }
  }

Object.setPrototypeOf(friend,person);

  console.log(friend.getGreeting()) //hello,hi!

Object.setPrototypeOf(friend,dog);
console.log(friend.getGreeting()) //Woof,hi!

friend上的getGreeting()调用了对象上的同名方法。调用原型上的方法用:Object.getPrototypeOf()和call(this),有点复杂,所以ES6引入了super,用来指向当前对象的原型的一个指针,相当于Object.getPrototypeOf(this)的值。可以使用super引用来调用对象原型上的任何方法。

需要注意点:super引用只能是位于简写方法,如果方法简写之外情况用super就会报错!!!

let friend = {
getGreeting(){
return super.getGreeting()+',hi!';
}
}
//'Uncaught SyntaxError: 'super' keyword unexpected here

这里举个由于this指向变化导致递归调用的栗子,而用super的话可以很好的解决this指向动态的问题,看下面的栗子:

let person = {
getGreeting(){
return "hello"
}
}
let friend = {
getGreeting(){
//原型上的getGreeting方法调用本身this对象,如果是relative,此时this就是relative,Object.getPrototypeOf(this)就是friend,然后call(this)...
return Object.getPrototypeOf(this).getGreeting.call(this)+',hi!';
}
} Object.setPrototypeOf(friend,person);
let relative = Object.create(friend);
relative.getGreeting()
//VM91:7 Uncaught RangeError: Maximum call stack size exceeded

可以看出发出堆栈错误,因为此时的this指向relative,而relative的原型是friend对象,friend.getGreeting().call()调用会导致进程开始反复进行递归调用,发生堆栈错误。

而如果用super引用的话:

let person = {
getGreeting(){
return "hello"
}
}
let friend = {
getGreeting(){
//super引用会一直指向person
return super.getGreeting()+',hi!';
}
} Object.setPrototypeOf(friend,person);
let relative = Object.create(friend);
relative.getGreeting()
//"hello,hi!"

因为super总是能指向正确的对象,本栗子中super.getGreeting()总是指向person.getGreeting(),不管有多少对象继承了此方法。

正式的“方法”定义:

let person = {
//方法
getGreeting(){
return "hello!"
}
}
//并非方法
function shareGreeting(){
return 'Hi!'
}

getGreeting()直接赋值给了一个对象,它的HomeObject属性值就是person,shareGreeting()函数被创建时候没有赋给一个对象,没有HomeObject属相。差异在于使用super引用时。

任何对super的引用第一步:在HomeObject上调用Object.getPrototypeOf()来获取原型的引用,第二部:在该原型上查找同名函数,第三部:创建this绑定并调用该方法。

关键字:【对象】【同名属性】【可计算属性名】【方法简写】【Object.is()】【Object.assign()】【枚举顺序】【Object.setPrototypeOf()】【super】

世界上只有一种真正的英雄主义,那就是认清生活的真相后还依然热爱生活。 ——《米开朗基罗》罗曼罗兰

ES6拓展的对象功能的更多相关文章

  1. [js高手之路] es6系列教程 - 对象功能扩展详解

    第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...

  2. ES6拓展符修改对象

    // ES6 拓展符合并两个对象let ab = { ...a, ...b }; // 等同于 let ab = Object.assign({}, a, b); // 修改对象部分属性.用户自定义的 ...

  3. ES6模块化与常用功能

    目前开发环境已经普及使用,如vue,react等,但浏览器环境却支持不好,所以需要开发环境编译,下面介绍下开发环境的使用和常用语法: 一,ES6模块化 1,模块化的基本语法 ES6 的模块自动采用严格 ...

  4. ES6的promise对象研究

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

  5. MyEclipse 10.x中拓展自动提示功能

    原文转自:MyEclipse 10.7中拓展自动提示功能 在myeclipse 9以前的版本中,我们如果要为html编辑器添加自动的代码提示可以这样操作: 1.windows-->prefere ...

  6. 教你如何使用ES6的Promise对象

    教你如何使用ES6的Promise对象 Promise对象,ES6新增的一个全新特性,这个是 ES6中非常重要的一个对象 Promise的设计初衷 首先,我们先一起了解一下,为什么要设计出这么一个玩意 ...

  7. 3dmax利用静止静态对象功能,制作精准击碎效果

    一般情况下,当我们在3D建模中使用RayFire破碎插件来制作一些精准击碎效果时,需要将物体的击中部分定义为休眠对象,将其他未击中的部分定义为静态对象,以实现击中部分出现碎片的效果.但这种方式必须精准 ...

  8. Class对象功能概述和Class对象功能获取Field

    Constructor[] getConstructors() Constructor getConstructor(类... parameterTypes) Constructor getDecla ...

  9. ES6入门系列 ----- 对象的遍历

    工作中遍历对象是家常便饭了,遍历数组的方法五花八门, 然而很多小伙伴是不是和我之前一样只会用for ...in.... 来遍历对象呢, 今天给大家介绍五种遍历对象属性的方法: 1, 最常用的for  ...

随机推荐

  1. Oracle中的 timestamp 和 timestamp with time zone, timestamp with local time zone

    SQL> select dbtimezone, sessiontimezone from dual; DBTIME ------ SESSIONTIMEZONE ---------------- ...

  2. iOS炫酷动画图案、多种选择器、网络测速、滑动卡片效果等源码

    iOS精选源码 对网络进行测速 自实现大标题,配合原生骨架屏demo 简单方便的pickerVIew记录数据 LZPickerView 科技风绘制组件,简单快速"画"出炫酷图案 R ...

  3. spring boot原理分析启动依赖中parent帮我们干了什么

    主要内容: 1:分析spring-boot-starter-parent 这个依赖 通过前面几篇文章的学习,我们感受到了spring boot的魅力.最明显的感觉就是pom.xml文件.代码少了很多. ...

  4. Angular开发者指南(七)依赖注入

    依赖注入 依赖注入(DI)是一种软件设计模式,处理组件如何获取其依赖关系. AngularJS注入器子系统负责创建组件,解析它们的依赖关系,并根据请求将它们提供给其他组件. 使用依赖注入 DI遍布An ...

  5. DB2数据库多行一列转换成 一行一列

    在db2中遇到多行一列转为一行一列的需求时,用db2函数 LISTAGG可以实现该功能.语法如下: SELECT   [分组的字段 ] , LISTAGG([需要聚合的字段名], ',')   FRO ...

  6. Qt QImage的浅拷贝与深拷贝

    首先简单说说什么是浅拷贝和深拷贝:浅拷贝就比如像引用类型,而深拷贝就比如值类型,即浅拷贝是共用一块内存的,而深拷贝是复制一份内容. 我们再来看看QImage类的几个构造函数: // 浅拷贝 QImag ...

  7. 整理struct sockaddr和struct sockaddr_in

    struct sockaddr定义在/usr/include/linux/socket.h struct sockaddr { unsigned short ss_family; - } struct ...

  8. python实现经典冒泡算法

    利用for循环,完成a=[1,7,4,89,34,2]的冒泡排序 冒泡排序:小的排在前,大的排在后面

  9. 地理位置(Geolocation)API 简介

    一.开篇简述 Geolocation API(地理位置应用程序接口)提供了一个可以准确知道浏览器用户当前位置的方法.且目前看来浏览器的支持情况还算不错(因为新版本的IE支持了该API),这使得在不久之 ...

  10. <USACO09DEC>过路费Cow Toll Pathsの思路

    啊好气 在洛谷上A了之后 隔壁jzoj总wa 迷茫了很久.发现那题要文件输入输出 生气 肥肠不爽 Description 跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦 ...