关于javascript:总结Es6对象扩展了哪些功能

2次阅读

共计 5374 个字符,预计需要花费 14 分钟才能阅读完成。

前言

JavaScript 中,简直每一个值都是某种特定的类型对象。Es6也着重晋升了对象的功能性,Es6通过多种形式来增强对象的应用,通过简略的语法扩大,提供更多操作对象及与对象交互的办法。上面来介绍它们。

对象字面量语法扩大

对象字面量如此就行,就是咱们想创建对象,不在须要编写冗余的代码。间接通过的它的简洁语法就能够实现。那么看看 Es6 为对象做了那些个性吧。

属性初始值的简写

在 Es5 中,对象字面量只是简略的键值和汇合,这意味着初始化属性有一些反复。

function person(name) {
    return {name: name}
}

在 Es6 中,通过属性的简写则能够省去这 name 属性一遍,当一个对象的属性和变量同名时,则能够省去冒号和值。看如下案例

function person(name) {
    return {name}
}

对象办法的简写语法

Es6 也改良了对象字面量的对象简写办法,在 Es5 中,定义对象办法必须的得写残缺名称才能够。

Es5 案例

let person = {test: function() {}}

Es6 案例

let person() {test() {}}

通过 Es6 对象的办法简写,定义的是一个匿名表达式,这个函数领有和 Es5 截然不同的个性。Es5 定义对象函数和 Es6 简写定义的函数惟一区别,简写的函数能够应用super

可计算属性名

在 Es5 中,如果想要通过计算失去属性名,则须要用 [] 方括号代替。

let person = {}
let value = "hello WaRen"
person["wa ren"] = "蛙人"
person[value] = "value"

下面 example 中,是咱们在 es5 中的做法,如果对象的 key 值是一个变量,那咱们就应用对象方括号增加。

在 Es6 中,可在对象字面量中应用可计算属性名称,咱们来看上面例子

let key = "name"
let person = {[key]: "蛙人" // 在对象字面量中这样应用 [] 方括号定义 key 是 Es6 语法
    [`${key}_test`]: "test"
}

下面这种在对象字面量中应用方括号示意该属性名是能够计算的,能够写表达式的,而后最终 key 值都会以字符串类型返回。切记,在对象字面量中应用方括号 [] 定义 key 值是 Es6 中的语法。自己也是刚晓得(根底不扎实 呜呜呜),经测试 bable 转换 Es6 转 Es5 能够看到后果。

反复的对象字面量属性

在 Es5 严格模式下退出了对象字面量反复属性的验证,当同时存在多个同名属性时会抛出异样。看上面例子

"use strict"
var person = {
    name: "蛙人",
    name: "张三" // 在 Es5 严格模式下会抛出语法错误
}

在 Es5 严格模式下时,第二个属性 name 会触发一个语法错误,然而在 Es6 中反复属性查看被移除了,Es6 中无论是在严格模式下,还是不在严格模式下代码都不会进行反复属性验证,对于反复属性都是前面的笼罩后面的。ps: 这个我也是刚刚晓得 流下了没技术的眼泪。。。

"use strict"
let person = {
    name: "蛙人",
    name: "张三"
}

在下面 example 中,咱们能够看到,这是 Es6 规范反复属性并没有抛出异样而是前面对象笼罩后面对象,最初 name 属性为 ” 张三 ”,咱们当初浏览器运行的都是 Es6 规范。

Es6 对象新增的办法

Es6 中在全局 Object 对象上引入了一些新办法。

Object.is

咱们在 Es5 中的时候常常应用 == 相等运算符 or === 全等运算符来比拟值,然而在 Es5 中相等运算符或者全等运算符也不齐全精确,这里拿官网说的举个例子,+ 0 和 -0 这个在 JavaScript 引擎中被示意两个不同的实体,而应用全等运算符或者相等运算符都会返回 ture, 同样NaN == NaN 返回 false。然而 Es6 中呈现了 Object.is 办法来补救这些有余,Object.is办法接管 2 个参数,如果这两个参数值相等并且类型也相等,则返回true

console.log(+0 == -0) // ture
console.log(+0 === -0) // true
console.log(Object.is(+0, -0)) // false

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

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

下面 example 中,咱们能够看到 Object.is 办法是挺严格的,然而这个只是解决非凡状况下应用,所以咱们没必要摈弃== or ===

Object.assign

Object.assign 办法能够接管任意数量源对象,第一个参数是接收者,也就是最终的返回值,第二个参数当前都是会复制到第一个参数外面,所以如果有多个源对象具备同名属性 key 值,那么则靠后的对象会笼罩靠前的对象。来看上面例子

let test1 = {name: "蛙人"}
let test2 = {name: "张三"}
let result = Object.assign({}, test1, test2)
console.log(result)  // {name: "张三"}

下面 example 中,能够看到下面的对象属性如果具备同名的,前面的则会笼罩后面的。如果参数里传入的是非对象也能执行,只不过会疏忽。来看上面例子

let result = Object.assign({}, 1, 2, 3)
console.log(result)  // {}

留神: Object.assign 办法不能将取值函数 (拜访器属性) 复制到对象中,因为 Object.assign 办法执行了赋值操作,那么对象最终会转换成一个一般的属性。

let test = {get name() {return "蛙人"}
}
let result = Object.assign({}, test)
console.log(Object.getOwnPropertyDescriptor(result, "name")) // {configurable: true enumerable: true value: "蛙人" writable: true}

下面 example 中,能够看到咱们复制对象的最终后果,取值函数的确失落了,咱们能够依据获取 对象的形容属性 能够看到。如果不懂 对象的形容属性 能够看我这篇文章《深刻了解 JavaScript 对象》

Object.setPrototypeOf

在 Es5 中,提供了 Object.getPrototypeOf 办法获取对象的原型,然而 Es5 中并没有提供设置对象的原型的办法,如果咱们想要设置对象的原型,xx.__proto__ = xx.__proto__ 显然这样写也是没问题的,然而并不合理。所以 Es6 提供了 Object.setPrototypeOf 办法, 这个办法接管两个参数,第一个就是被批改的对象,第二个是原型对象。来看上面例子

let person = {}
function Fn() {}
let fn = new Fn()
Object.setPrototypeOf(person, fn)
console.log(person)

下面 example 中,能够看到就是把 person 的原型对象批改成 fn 的原型对象,这时你在拜访 person 对象就能够分明的看到原型对象曾经被更改了。

Object.values

Object.values办法返回一个数组,成员是参数对象本身的,不蕴含继承和原型上的

let person = {
    name: "蛙人",
    age: 24,
    sex: "male"
}
console.log(Object.values(person)) // ["蛙人", 24, "male"]

Object.entries

Object.entries办法返回一个数组(也就是一个二维数组),成员是参数对象本身的,属性的键值对数组,不蕴含继承和原型上的。

let person = {
    name: "蛙人",
    age: 24,
    sex: "male"
}
console.log(Object.entries(person)) // [["name", "蛙人"], ["age", 24], ["sex", "male"]]

Object.fromEntries

Object.fromEntriesObject.entries 的反向操作,返回值是一个对象,用于将一个键值对数组转为对象。

let testArr = [["name", "蛙人"],
    ["age", 24],
    ["sex", "male"]
]
console.log(Object.fromEntries(testArr)) // {name: "蛙人", age: 24, sex: "male"}

自有对象属性枚举程序

在 Es5 中没有定义对象属性的枚举程序,是由 js 引擎厂商自行决定的。然而,在 Es6 中规定了对象自有属性被枚举返回的程序。自有属性枚举程序的根本规定如下:

  • 所有数字键按升序排序
  • 所有字符串键按退出对象的程序排序
  • 所有 symbol 键按退出对象的程序排序
let o = {
    4: 4,
    1: 1,
    b: "b",
    a: "a"
}
o.c = "c"

console.log(Object.keys(o)) // ["1", "4", "b", "a", "c"]
console.log(Object.getOwnPropertyNames(o)) // ["1", "4", "b", "a", "c"]
for (let i in o) {console.log(i) // 1 4 b a c
}

下面 example 中,能够看到对象枚举属性都是依据 Es6 中规定程序来返回的,请留神 , 对于数字键,只管在对象字面量中程序是随便的,然而在枚举时会被重新组合和排序。字符串紧跟数字键前面,并依照该属性在对象里的程序返回,最初是动静增加字符串健值。

简化原型拜访的 Super 援用

在 Es6 中,新提供了 super 关键字,该办法是为了简化获取以后的原型的对象应用的。来看上面例子

Es5 案例

let person = {getName() {return Object.getPrototypeOf(this).getVal.call(this)
    }
}
let o = {getVal() {return "蛙人"}
}

Object.setPrototypeOf(person, o)
console.log(person.getName()) // 蛙人

下面 example 中,能够看到先把 person 的原型设置为 o 对象,而后调用 person 对象时,该 getName 办法里又获取了以后的原型,调用原型上的办法,也就是调用的 o 对象的办法。

Es6 案例

let person = {getName() {return super.getVal.call(this)
    }
}
let o = {getVal() {return "蛙人"}
}

Object.setPrototypeOf(person, o)
console.log(person.getName()) // 蛙人

下面 example 中,能够看到咱们把下面代码略微调整了一下,把 Object.getPrototypeOf 换成了 super 关键字。super关键字作用就是能够代替 Object.getPrototypeOf 办法拜访对象原型。然而 super 关键字也是有个弊病就是只能在对象字面量的办法简写状况下应用。来看上面案例

let person = {getName: function() {return super.toString() // 报错
    }
}

在下面 example 中,person对象里用匿名 function 定义了一个属性,因为在以后上下文中 super 援用是非法的,所以就抛出谬误。那么为什么同样都是函数而有差别呢,那么咱们持续往下看。

正确区分办法的定义

在 Es6 之前没有规定的 办法 这个概念,办法仅仅是一个具备性能而非对象的属性,而在 Es6 中正式将办法定义为一个函数,它会有一个外部的 [[HomeObject]] 属性来包容这个办法隶属的对象。看上面例子

let person = {getName() {} // 是办法}
function getName() {} // 不是办法

下面 example 中,定义 person 对象,它有一个 getName 办法,因为间接把函数赋值给了 person 对象,getName办法的 [[HomeObject]] 属性值为 person 对象。而后在看上面用 function 关键字定义的 getName 办法,这时它没有赋值给一个对象,所以没有明确定义 [[HomeObject]] 属性。如果不应用 super 关键字这两个函数这点小区别没什么大问题。然而要应用 super 关键字的话就尤其重要。<br/>

因为 super 关键字援用都通过 [[HomeObject]] 属性来确定后续运行过程。super关键字先会在 [[HomeObject]] 属性上找到以后对象 (属性值),也就是person 而后在调用 Object.getPrototypeOf 办法获取以后原型,而后在去原型上找到以后同名函数,最初设置 this 绑定并且调用。这也就是下面为什么 super 关键字会报错的起因。

感觉写的不错的话那就点个赞叭!


大家也能够加我的微信一起交换

正文完
 0