博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重学ES6 对象的扩展(1)
阅读量:7119 次
发布时间:2019-06-28

本文共 4623 字,大约阅读时间需要 15 分钟。

属性的简洁表示

es6 允许直接写入和函数作为对象的属性和方法。

var foo = 'bar';var baz = {foo};baz // {foo: "bar"}复制代码

等同于

var baz = {
foo: "bar"}复制代码

es6允许,在对象中只写属性名,不写属性值。这时属性值等于属性名所代表的变量

function f(x, y){    return {x, y};}复制代码

等同与

function f(x, y){    return {
x:x,y:y};}f(1,2); //{x:1,y:2}复制代码

除了属性简写,方法也可以简写。

var o = {    method() {        return 'hello';    }}复制代码

等同

var o = {    method: function() {        return "hello";    }}复制代码

用于函数返回值

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) {    ms[key] = value;}function clear (){    ms = {};}module.exports = { getItem, setItem, clear};复制代码

属性名表达式

定义对象属性有两种方法

//1 直接用标识符作为属性名obj.foo = true;//2 表达式作为属性名obj['a' + 'bc'] = 123;复制代码

ES6允许字面量定义方法时,把表达式放在方括号内。

let propKey = 'foo'let obj = {    [propKey] : true,    ['a' + 'bc'] : 123}复制代码

表达式还可以用于定义方法名

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。

const person = {    sayName() {        console.log('hello!');    }}person.sayName.name //"sayName"复制代码

上述代码,name属性返回函数名,即方法名。

如果对象的方法使用了取值函数(getter)和存值函数(setter),则name属性不在该方法上,而是在该方法属性的描述对象的get和set属性上,返回值是方法名前加上get和set。

const obj = {    get foo(){},    set foo(x){}}obj.foo.name //找不到nameconst descriptor = Object.getOwnPropertyDescriptor(obj,'foo');descriptor.get.name //"get foo"descriptor.set.name //"set foo"复制代码

Object.is()

ES5比较两个值相等,有== 和 ===,都有缺点,前者会自动转换数据类型,后者NaN不等于自身,以及 +0 等于 -0 ,JavaScript缺乏这样一种运算,在所有环境中,只要两个值是一样的,就应该相等。

ES6 提出了“same-value equally”(同值相等)算法用来解决这个问题。Object.is 就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格相等(===)行为基本一致。

Object.is('foo','foo') //trueObject.is({},{}) //false复制代码

不同之处,有两个

+0 === -0 //trueNaN === NaN //falseObject.is(+0,-0) // falseObject.is(NaN,NaN)//true复制代码

ES5部署代码

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() 用于向所有可枚举属性复制到目标对象。

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 第一个参数是目标对象,后面的参数都是源对象。

如果目标对象与源对象有相同属性名,后面的属性会覆盖前面的属性。

Object.assign 复制,只复制源对象的自身属性,不复制继承属性,也不可复制不可枚举属性。属性名为Symbol值的属性,也会被复制。

Object.assign 实行的是浅复制,不是深复制。如果源对象某个属性值是对象,那么,目标对象复制得到的是对这个对象的引用。

var target = {    a:{        b:'c',        d:'e'    }}var source = {    a:{        b:'hello'    }}Object.assign(target, source); //{a:{b:'hello'}}复制代码

数组注意点:

Object.assign([1,2,3],[4,5]) //[4,5,3]复制代码

上面代码,Object.assign把数组视为属性名为 0 1 2的对象,因此目标数组的 0号属性4覆盖了原数组的0号属性1.

常见用途

为对象添加属性

将 x,y属性添加到Point类对象实例中。

class Point {    constructor(x,y){        Object.assign(this,{x,y})    }}复制代码

为对象添加方法

Object.assign(SomeClass.prototype,{    someMethod(arg1,arg2){        ...    },    anotherMethod(){        ...    }});//等同于SomeClass.prototype.someMethod = function (arg1,arg2){    ...}SomeClass.prototype.anotherMethod = function (){    ...}复制代码

克隆对象

只能克隆原始对象自身的值,不能克隆继承的值。

function clone(origin) {    return Object.assign({},origin)}复制代码

想要保持继承,使用如下代码

function clone(origin){    let originProto = Object.getPrototypeOf(origin);    return Object.assign(Object.create(originProto),origin)}复制代码

合并多个对象

将多个对象合并到某个对象

const merge = (target,...sources) => Object.assign(target,...sources);复制代码

属性的可枚举

对于每一个属性都具有一个描述对象,用于控制该属性的行为。

Object.getOwnPropertyDescriptor 方法可以获取该属性的描述对象。

let obj = {    foo:123}Object.getOwnPropertyDescriptor(obj,'foo');//{
// value:123,// writable:true,// enumerable:true// configurable:true//}复制代码

描述对象的 enumerable 属性,称为“可枚举性”。如果该属性为false,表示某些操作会忽略当前属性。

ES5 有三个操作会忽略 enumerable 为 false 的属性。

  • for...in循环:只遍历对象自身的和继承的可枚举属性。
  • Object.keys():返回对象自身的所有可枚举属性的键名。
  • JSON.stringify():只串行化对象自身的可枚举属性。

总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的属性,所以,尽量不要用 for...in循环,而用 Object.key()代替

属性的遍历

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

1 for...in

遍历对象自身的和继承的可枚举属性

2 Object.keys(obj)

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

3 Object.getOwnPropertyNames(obj)

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

4 Object.getOwnPropertySymbol(obj)

Object.getOwnPropertySymbol(obj) 返回一个数组,包含对象自身所有的Symbol属性。

5 Reflect.ownKeys(obj)

Reflect.ownKeys(obj) 返回一个数组,包含对象自身的所有属性,不管是Symbol还是字符串,也不管是否可枚举。

转载于:https://juejin.im/post/5cd4c95ce51d456e5c5babb1

你可能感兴趣的文章
vsftpd虚拟用户
查看>>
ionic 幻灯指令 ion-slide-box
查看>>
发一个经典的Flask-SQLAlchemy使用场景
查看>>
iOS逆向之自动化重签名
查看>>
java 读取pdf、word、Excel文件
查看>>
递归处理vue菜单数据
查看>>
html5 图片热点area,map的用法
查看>>
Java集合框架知多少——干货!!!
查看>>
P2030 - 【BJOI2006】狼抓兔子
查看>>
【随想】关于图灵机
查看>>
echarts 通过ajax实现动态数据加载
查看>>
结构化方法与面向对象方法之比较
查看>>
Pig调试环境
查看>>
Python连接MySQL数据库
查看>>
BZOJ2815:[ZJOI2012]灾难(拓扑排序,LCA)
查看>>
[转] js对象监听实现
查看>>
【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee
查看>>
mongoDB 3.0 安全权限访问控制
查看>>
电子数字 网易游戏在线笔试 第一题 hihocoder
查看>>
Java 中nextLine()方法没有执行直接跳过解决办法
查看>>