ES6中扩展对象的功能性

news2024/12/19 14:41:52

对象是JavaScript编程的核心,ECMAScript6为对象提供了许多简单易用且更加灵活的新特性。

  1. ECMAScript 6在对象字面量的基础上做出了以下几个变更:
  • 简化属性定义语法,使将当前作用域中的同名变量赋值给对象的语法更加简洁
function createPerson(name, age) {
    return {
        name: name, 
        age: age
    }
};

这段代码属性名称与函数的参数相同,在返回的对象中,name和age分别重复了两遍,只是其中一个时对象属性的名称,另外一个是为属性赋值的变量。在ES6中,通过使用属性初始化的简写语法,可以消除这种属性名称和局部变量之间的重复书写。当一个对象的属性与本地变量同名时,不必再写冒号和值,简单地只写属性名即可。

// 属性初始值的简写
function createPerson(name, age) {
    return {
        name, age
    }
};

当对象字面量里只有一个属性的名称(而没有值)时,JavaScript引擎会在可访问作用域中查找其同名变量;如果找到,则该变量的值被赋给对象字面量里的同名属性。在上面的示例中,对象字面量属性name被赋予了局部变量name的值。

  • 添加可计算属性名特性,允许为对象指定非字面量属性名称

在ECMAScript 5及早起版本的对象实例中,如果想要通过计算得到属性名,就需要用方括号代替点记法。有些包括某些字符的字符串字面量作为标识符会出错,其和变量放在方括号中都是被允许的。比如

var person = {},lastName = "last name";
person["first name"] = "Nicholas";
person[lastName] = "Zakas";
// Nicholas
console.log(person["first name"]);
// Zakas
console.log(person[lastName]);

变量lastName被赋值为字符串"first name",引用的两个属性名称中都含有空格,因为不可使用点记法引用这些属性,却可以使用方括号,因为它支持通过任何字符串值作为名称访问属性的值。
在这里插入图片描述
此外,在对象字面量中,可以直接使用字符串字面量作为属性名称,就像这样

var person = {
    "first name": "Nicholas"
};
// Nicholas
console.log(person["first name"]);

这种模式适用于属性名提前已知或可被字符串字面量表示的情况,然而,如果属性名称"first name"被包含在一个变量中,或者需要通过计算才能得到该变量的值,那么在ECMAScript 5中时无法为一个对象字面量定义该属性的。

在ECMAScript 6中,可以在对象字面量中使用可计算属性名称,其语法与引用对象实例的可计算属性名称相同,也是使用方括号。

// 可计算属性
var suffix = " name";
var person = {
    ["first" + suffix]: "Nocholas",
    ["last" + suffix]: "Zakas"
};
console.log(person["first name"]);
console.log(person["last name"]);

在对象字面量中使用方括号代表该属性名称时可以计算的,它的内容将被求值并被最终转化为一个字符串,因而同样可以使用表达式作为属性的可计算名称。

  • 添加对象方法的简写语法,在对象字面量中定义方法时可以省略冒号和function关键字

在ECMAScript 5及早期保本中,如果为对象添加方法,必须通过指定名称并完整定义函数来实现,就像这样:

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

而在ECMAScript 6中,语法更简洁,消除了冒号和function关键字。以上案例重写为

// 对象方法的简写
var person = {
    name: "Nicholas",
    // 被赋值一个匿名表达式
    sayName() {
        console.log(this.name);
    }
}

通过对象方法简写语法,在person对象中创建一个sayName()方法,该属性被赋值为一个匿名函数表达式,它拥有在ECMAScript 5中定义的对象方法所具有的全部特性。二者唯一的区别时,简写方法可以使用super关键字。

通过对象方法简写语法创建的方法有一个name属性,其值为小括号前的名称。在上述示例中,person.sayName()方法中的name属性的值为sayName.

  • 弱化了严格模式下对象字面量重复属性名称的校验,即使在同一个对象字面量中定义两个同名属性也不会抛出错误

以下的代码在ECMAScript 5中是会报错的。但是在ECMAScript 6中对于每一组重复属性,都会选取最后一个取值。

var person = {
    name: "Nocholas",
    name: "Greg"
}
// Greg
console.log(person.name);
  1. Object.assign方法可以一次性更改对象中的多个属性,如果使用混入(Mixin)模式将非常有用。Object.js方法对于所有值都进行严格等价判断,当将其用于处理特殊JavaScript值问题时比===操作符更加安全
  • Object.assign方法
    混合(Mixin)时JavaScript中实现对象组合最流行的一种模式,在一个mixin方法中,一个对象接收来自另一个对象的属性和方法,许多JavaScript库中都有类似的mixin方法
function mixin(receiver,supplier){
    Object.keys(supplier).forEach(function(key){
        receiver[key] = supplier[key];
    });
    return receiver;
}

mixin()函数遍历supplier的自由属性并复制到receiver中(此处的复制行为是浅复制,当属性值为对象时只是复制对象的引用)。这样一来,receiver不通过继承就可以获得新属性。
这种混合模式非常流行,ECMAScript 6添加了Object.assign方法来实现相同的功能,这个方法接受一个接收对象和任意数量的源对象,最终返回接收对象。mixin方法使用赋值操作符来复制相关属性,却不能复制访问器属性到接收对象中,因此最终添加的方法弃用mixin而改用assign作为方法名。

具有同样功能的方法在各种第三方库中可能被定义了其他方法名,比较常见的有:extend()方法和mix()方法。

任何使用mixin方法的地方都可以直接使用Object.assign方法来替换。该方法可以接收任意数量的源对象,并按指定的顺序将属性复制到接收对象中,所以如果多个源对象具有同名属性,则排位靠后的源对象会覆盖排位靠前的,比如

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

此处两个源对象具有同名的type属性,receiver.type最终的值为"css".

==Object.assign方法不能将提供者的访问器属性复制给接收者。==由于Object.assign()方法执行了赋值操作,因为提供者的访问器属性最终会转变为接收对象的一个数据属性。比如

var receiver = {}, supplier = {
    get name() {
        return "file.js"
    }
};
Object.assign(receiver, supplier);
var descriptor = Object.getOwnPropertyDescriptor(receiver, "name")
// file.js
console.log(descriptor.value);
// 获取该属性的访问器属性,如果没有,则返回undefined
// undefined
console.log(descriptor.get);
// file.js
console.log(receiver.name);

这段代码中,supplier有一个名为name的访问器属性,当调用Object.assign方法时返回字符串"file.js".因此receiver接收这个字符串后将其存为数据属性receiver.name。

  • Object.is方法

当你想在JavaScript中比较两个值时,可能习惯于使用相等运算符(==)或全等运算符(===),许多开发者更喜欢后者,从而避免在比较时触发强制类型转换的行为。对于Object.is方法来说,其运行结果在大部分情况中与 === 运算符相同,唯一的区别在与 +0和-0被识别为不相等并且NaN与NaN等价。

// 使用Object.is判断参数类型是否相同且具有相同的值
// true
console.log(+0 == -0);
// true
console.log(+0 === -0);
// false
console.log(Object.is(+0, -0));

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

// true
console.log(5 == "5");
// false
console.log(5 === "5");
// false
console.log(Object.is(5, "5"));
  1. 在ECMAScript 6中同样清晰定义了自有属性的枚举顺序:当枚举属性时,数值键在前,字符串键在后;数值键总是按照升序排列,字符串按照插入的顺序排列。

ECMAScript 5中未定义对象属性的枚举顺序,由JavaScript引擎厂商自行决定。然而,ECMAScript 6严格规定了对象的自有属性被枚举时的返回顺序。这回影响到Object.getOwnPropertyNames方法以及Reflect.ownKeys返回属性的方式。Object.assign方法处理属性的顺序也将随之改变。

比如

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

Object.getOwnPropertyNames方法按照0、1、2、a、c、b、d的顺序一次返回对象obj中定义的属性。对于数值键,尽管在对象字面量中的顺序时随意的,但在枚举时会被重新组合和排序。字符串紧随数值键,并按照在对象obj中定义的顺序依次返回,最后动态加入的字符串键最后输出。

对于for-in循环,由于并非所有厂商都遵循相同的实现方式,因此仍未指定一个明确的枚举顺序;而Object.keys方法和JSON.stringify方法都指明与for-in使用相同的枚举顺序,因为它们的枚举顺序目前还不明晰。

对于JavaScript,枚举顺序的改变其实微不足道,但是有很多程序都需要指定枚举顺序才能正确运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1774.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL】MySQL基本操作详解

系列文章目录 第1篇:【MySQL】MySQL介绍及安装 第2篇:【MySQL】MySQL基本操作详解 文章目录 ✍1,数据库操作     🔍1.1,查看数据库     🔍1.2,创建数据库     🔍1.3,选择数据库     &…

Kubernetes基础_02_Pod全解析

系列文章目录 文章目录系列文章目录前言一、Pod的生命周期Lifecycle二、Pod的重启策略RestartPolicy三、静态Pod四、Pod的健康检查总结前言 Pod是Kubernetes最小单位,当然一个Pod可以有多个Container,但是container是docker的元素,不是Kuber…

CTFHub | 布尔盲注

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习,实训平台。提供优质的赛事及学习服务,拥有完善的题目环境及配套 writeup ,降低 CTF 学习入门门槛,快速帮助选手成长,跟随主流比赛潮流。 0x01 题目描述…

无限题库公众号系统搭建

无限题库公众号系统搭建 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(…

《设计模式:可复用面向对象软件的基础》——行为模式(笔记)

文章目录五、行为模式5.1 CHAIN OF RESPONSIBILITY(职责链)1.意图2.动机3.适用性4.结构5.参与者6.协作7.效果8.实现9.代码示例10.相关模式5.2 COMMAND(命令)1.意图2.别名3.动机4.适用性5.结构6.参与者.7.协作8.效果9.实现10.代码示例11.相关模式5.3 INTE…

CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录

很高兴和大家在这里分享我的最新专栏 Pytorch深度学习理论篇(2023版),恭喜本博客浏览量达到两百万,CSDN内容合伙人,CSDN人工智能领域实力新星~ 0 Pytorch深度学习理论篇实战篇(2023版)大纲 1 Pytorch深度学习理论篇实战篇(2023版)专栏地址&…

嵌入式应用-详解移植并使用freetype显示文字

目录 前言 1. freetype和相关概念简介 2.freetype显示文字流程和主要函数 2.1 包含头文件及API头文件:ft2build.h 2.2 初始化: FT_InitFreetype 2.3 加载(打开)字体Face: FT_New_Face 2.4 设置字体大小&#x…

sqrt函数模拟实现的两种方法

起因:在leetcode刷题时,有一道题目考察了有关sqrt的原理的题目,当时就去查了网上的文章,结果发现,一开始的时候看的很懵,最后也是搞定了两种方法,今天我就以最简单的方式写下这两种方式的思路讲解&#xff…

Python批量获取高校基本信息

文章目录前言一、需求二、分析三、处理四、运行效果前言 为了更好的掌握数据处理的能力,因而开启Python网络爬虫系列小项目文章。 小项目小需求驱动,每篇文章会使用两种以上的方式(Xpath、Bs4、PyQuery、正则等)获取想要的数据。…

T31快启图像效果优化

T31快启图像效果优化 liwen01 20220821 (一)基础方法及概念 参考文档 《Ingenic_Zeratul_T31_快起效果调试说明_20200927_CN》 (1)起始EV参数 IPC 每次启动都是冷启动,画面有一个暗变亮的过程,称作为AE收敛过程(自动曝光收敛过程)。 为了加快AE收…

LeetCode50天刷题计划第二季(Day 23 — 重排链表(16.20- 17.00)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、题目重排链表示例提示二、思路三、代码前言 链表基础题加一 一、题目 重排链表 给定一个单链表 L 的头节点 head ,单链表 L 表示为&#xff…

基于粒子群优化算法的时间调制非线性频偏FDA(Matlab代码实现)

🎉🎉🎉🎉欢迎您的到来😊😊😊 🥬博客主页:博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 📝床头铭:将来的我一定会感谢…

ARM64下构建 UEFI 模块

构建Application工程目录 mkdir edk2/ShellPkg/Application/ShellHello 目录内容如下: 编写 ShellHello.c /* edk2/ShellPkg/Application/ShellHello/ShellHello.c*/ #include <Uefi.h> #include <Library/UefiLib.h> #include <Library/DebugLib.h> #i…

上手之Python之异常

什么是异常 当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是所谓的“异常”, 也就是我们常说的BUG bug单词的诞生 早期计算机采用大量继电器工作&#xff0c;马克二型计算机就是这样的。 1945年9月9日&…

【JVM技术专题】 深入学习JIT编译器实现机制「 原理篇」

前提概要 解释器 Java程序最初是通过解释器(Interpreter)进行解释执行的&#xff0c;当虚拟机发现某个方法或代码块的运行特别频繁的时候&#xff0c;就会把这些代码认定为“热点代码”&#xff08;hotspot code&#xff09;。正因为如此&#xff0c;我们的hotspot的虚拟机就是…

将matlab数据导入到Python中使用

相信不少小伙伴都遇到过和我一样的问题&#xff0c;就是在尝试使用scipy.io.loadmat将matlab类型的数据导入python中的时候遇到如下错误提示。 import scipy as sc# 设定需要导入的matlab数据目录 path_TE00 r"D:\Window自带文件夹\桌面\PIC Design\Lumerical\Tutorials…

Apollo GraphQL

一、Apollo GraphQL介绍 Apollo 是一个开源的 GraphQL 开发平台&#xff0c; 提供了符合 GraphQL 规范的服务端和客户端实现。使用 Apollo 可以帮助我们更方便快捷的开发使用 GraphQL。 ● 官网&#xff1a;https://www.apollographql.com/ ● GitHub 相关开源仓库&#xff1a…

Vite+Vue+Electron环境搭建

因为electron可以直接加载html文件&#xff0c;也可以直接加载url链接&#xff0c;所以&#xff0c;我们可以在调试过程中使用url地址&#xff0c;来动态显示我们的改变过程。 electron简单来说就是对html的一种封装&#xff0c;所以我们先来搭建vue的开发环境&#xff0c;这里…

LQ0135 左孩子右兄弟【DFS+二叉树】

题目来源&#xff1a;蓝桥杯2021初赛 C A组H题 题目描述 对于一棵多叉树&#xff0c;我们可以通过“左孩子右兄弟” 表示法&#xff0c;将其转化成一棵二叉树。 如果我们认为每个结点的子结点是无序的&#xff0c;那么得到的二叉树可能不唯一。 换句话说&#xff0c;每个结点可…

并发编程之ForkJoin框架

什么是 Fork/Join 框架 Fork/Join 是从 java7 开始提供的并行执行任务的框架&#xff0c;是一个把大任务分割成若干个小任务&#xff0c;最终汇总每个小任务的结果&#xff0c;得到大任务结果的框架. 如下图&#xff1a; Fork/Join 的特性 ForJoinPool 不是为了替代 Execu…