写点什么

从 Object.assign 开始了解 ES2015

用户头像
devpoint
关注
发布于: 2021 年 05 月 28 日
从 Object.assign 开始了解ES2015

ECMAScript 6(以下简称 ES6)是 JavaScript 语言的下一代标准。因为当前版本的 ES6 是在 2015 年发布的,所以又称 ECMAScript 2015。也就是说,ES6 就是 ES2015。本文着重介绍 ES2015 新增内容之一:Object.assign。在文章最后也介绍 ECMAScript 的发展历程。

Object.assign

Object.assign方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

语法

Object.assign(target, ...sources)
复制代码


  • 参数:

  • target:目标对象。

  • sources:源对象。

  • 返回值:目标对象。

  • 描述:如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖。后来的源的属性将类似地覆盖早先的属性。

注意

Object.assign方法只会拷贝源对象自身的并且可枚举的属性到目标对象。


拷贝过程中将调用源对象的getter方法,并在 target 对象上使用setter方法实现目标对象的拷贝。因此,它分配属性,而不仅仅是复制或定义新的属性。


如果合并源包含getter,这可能使其不适合将新属性合并到原型中。


  • String 类型和 Symbol 类型的属性都会被拷贝。

  • 在出现错误的情况下,例如,如果属性不可写,会引发 TypeError,如果在引发错误之前添加了任何属性,则可以更改 target 对象。

  • Object.assign会跳过那些值为 null 或 undefined 的源对象。

实例

  • 复制一个对象


    var obj = {name:"devpoint"};    var copy = Object.assign({}, obj);    console.log(copy); //{name:"devpoint"}
复制代码


  • 深度拷贝问题针对深拷贝,需要使用其他方法,Object.assign拷贝的是属性值。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。


    function test() {        let obj1 = { name: "devpoint1", address: { city: "Shenzhen1" } };        let obj2 = Object.assign({}, obj1);        console.log(JSON.stringify(obj2)); // {"name":"devpoint1","address":{"city":"Shenzhen1"}}
obj1.name = "devpoint2"; console.log(JSON.stringify(obj1)); // {"name":"devpoint2","address":{"city":"Shenzhen1"}} console.log(JSON.stringify(obj2)); // {"name":"devpoint1","address":{"city":"Shenzhen1"}}
obj2.name = "devpoint3"; console.log(JSON.stringify(obj1)); // {"name":"devpoint2","address":{"city":"Shenzhen1"}} console.log(JSON.stringify(obj2)); // {"name":"devpoint3","address":{"city":"Shenzhen1"}}
obj2.address.city = "Shenzhen3"; console.log(JSON.stringify(obj1)); // {"name":"devpoint2","address":{"city":"Shenzhen3"}} console.log(JSON.stringify(obj2)); // {"name":"devpoint3","address":{"city":"Shenzhen3"}}
// Deep Clone obj1 = { name: "devpoint1", address: { city: "Shenzhen1" } }; let obj3 = JSON.parse(JSON.stringify(obj1)); obj1.name = "devpoint4"; obj1.address.city = "Shenzhen4"; console.log(JSON.stringify(obj3)); // {"name":"devpoint1","address":{"city":"Shenzhen1"}} } test();
复制代码


  • 忽略 nullundefined


JavaScript 的 Object.assign() 方法在复制对象时会忽略 null 和 undefined。请看下面列出的代码:


const obj1 = {    title: "devpoint",};
const obj2 = Object.assign({}, obj1, null, undefined, { city: "Shenzhen" });console.log(obj2); // { title: 'devpoint', city: 'Shenzhen' }
复制代码

ECMAScript 简介

先说 JavaScript

1994 年,网景公司(Netscape)发布了 Navigator 浏览器 0.9 版。这是历史上第一个比较成熟的网络浏览器,轰动一时。但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力。比如,如果网页上有一栏"用户名"要求填写,浏览器就无法判断访问者是否真的填写了,只有让服务器端判断。如果没有填写,服务器端就返回错误,要求用户重新填写,这太浪费时间和服务器资源了。


因此,网景公司急需一种网页脚本语言,嵌入到网页中,使得浏览器可以与网页互动。网页脚本语言到底是什么语言?网景公司当时有两个选择,这两个选择各有利弊,网景公司内部争执不下,管理层一时难以下定决心:


  • 采用现有的语言,比如 Perl、Python、Tcl、Scheme 等等,允许它们直接嵌入网页;

  • 优点:有利于充分利用现有代码和程序员资源,推广起来比较容易

  • 发明一种全新的语言

  • 优点:有利于开发出完全适用的语言,实现起来比较容易


就在这时,发生了另外一件大事:1995 年 Sun 公司将 Oak 语言改名为 Java,正式向市场推出。


Sun 公司大肆宣传,许诺这种语言可以"一次编写,到处运行"(Write Once, Run Anywhere),它看上去很可能成为未来的主宰。网景公司动了心,决定与 Sun 公司结成联盟。它不仅允许 Java 程序以 applet(小程序)的形式,直接在浏览器中运行;甚至还考虑直接将 Java 作为脚本语言嵌入网页,只是因为这样会使 HTML 网页过于复杂,后来才不得不放弃。总之,当时的形势就是,网景公司的整个管理层,都是 Java 语言的信徒,Sun 公司完全介入网页脚本语言的决策。因此,Javascript 后来就是网景和 Sun 两家公司一起携手推向市场的,这种语言被命名为"Java+script"并不是偶然的。


1995 年 4 月,网景公司录用了 34 岁的系统程序员 Brendan Eich。Brendan Eich 的主要方向和兴趣是函数式编程,网景公司招聘他的目的,是研究将 Scheme 语言作为网页脚本语言的可能性。Brendan Eich 本人也是这样想的,以为进入新公司后,会主要与 Scheme 语言打交道。但仅仅一个月之后,1995 年 5 月,网景公司做出决策,未来的网页脚本语言必须"看上去与 Java 足够相似",但是比 Java 简单,使得非专业的网页作者也能很快上手。这个决策实际上将 Perl、Python、Tcl、Scheme 等非面向对象编程的语言都排除在外了。Brendan Eich 被指定为这种"简化版 Java 语言"的设计师。


但是,他对 Java 一点兴趣也没有。为了应付公司安排的任务,他只用 10 天时间就把 Javascript 设计出来了。由于设计时间太短,语言的一些细节考虑得不够严谨,导致后来很长一段时间,Javascript 写出来的程序混乱不堪。


总的来说,他的设计思路是这样的:


  • 借鉴 C 语言的基本语法;

  • 借鉴 Java 语言的数据类型和内存管理;

  • 借鉴 Scheme 语言,将函数提升到"第一等公民"(first class)的地位;

  • 借鉴 Self 语言,使用基于原型(prototype)的继承机制。所以,Javascript 语言实际上是两种语言风格的混合产物----(简化的)函数式编程+(简化的)面向对象编程。这是由 Brendan Eich(函数式编程)与网景公司(面向对象编程)共同决定的。


Brendan Eich 设计的这个脚本语言,是为 Netscape 公司准备在 1995 年发行的 Netscape Navigator 2.0 浏览器提供的。 开始的时候这个语言是被称为 LiveScript,就在 Netscape Navigator 2.0 即将正式发布前,Netscape 将其更名为 JavaScript,目的是为了利用 Java 这个因特网时髦词汇。这个是 JavaScript 1.0 版本。该版本推出,获得了很大成功。


因为 JavaScript 1.0 如此成功,Netscape 在 Netscape Navigator 3.0 中发布了 1.1 版。恰巧那个时候,微软决定进军浏览器,发布了 IE 3.0 并搭载了一个 JavaScript 的克隆版,叫做 JScript(这样命名是为了避免与 Netscape 潜在的许可纠纷)。微软步入 Web 浏览器领域的这重要一步虽然令其声名狼藉,但也成为 JavaScript 语言发展过程中的重要一步。


在微软进入后,有 3 种不同的 JavaScript 版本同时存在:


  • Netscape Navigator 3.0 中的 JavaScript

  • IE 中的 JScript 以

  • CEnvi 中的 ScriptEase(一家称作 Nombas 的公司开发的可嵌入网页的脚本语言)。


与 C 和其他编程语言不同的是,JavaScript 并没有一个标准来统一其语法或特性,而这 3 种不同的版本恰恰突出了这个问题。随着业界担心的增加,这个语言的标准化显然已经势在必行。

ECMAScript 的诞生

1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给国际标准化组织 ECMA,希望这种语言能够成为国际标准。ECMA 是 European Computer Manufacturers Association 的缩写,即欧洲计算机制造商协会,ECMA 是制定信息传输与通讯的国际化标准组织。


ECMA 的第 39 号技术专家委员会(Technical Committee 39,简称 TC39)负责制订 ECMAScript 标准,成员包括 Netscape、Sun、Microsoft、Mozilla、Google 等大公司。


1997 年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。


该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。


  • 商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。

  • 想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。


因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。Jscript 和 ActionScript 也算是 ECMAScript 的一种实现。

发展历程

  • 1997 年,ECMAScript 1.0 发布。

  • 1998 年,ECMAScript 2.0 发布

  • 1999 年,ECMAScript 3.0 发布。3.0 版是一个巨大的成功,在业界得到广泛支持,成为通行标准,奠定了 JavaScript 语言的基本语法,以后的版本完全继承。直到今天,初学者一开始学习 JavaScript,其实就是在学 3.0 版的语法。

  • 2000 年,ECMAScript 4.0 开始酝酿。这个版本最后没有通过。为什么 ES4 没有通过呢?因为这个版本太激进了,对 ES3 做了彻底升级,导致标准委员会的一些成员不愿意接受。

  • 2007 年,ECMAScript 4.0 版草案发布,本来预计次年 8 月发布正式版本。但是,各方对于是否通过这个标准,发生了严重分歧。以 Yahoo、Microsoft、Google 为首的大公司,反对 JavaScript 的大幅升级,主张小幅改动;以 JavaScript 创造者 Brendan Eich 为首的 Mozilla 公司,则坚持当前的草案。

  • 2008 年,由于对于 4.0 版本应该包括哪些功能,各方分歧太大,争论过于激烈,ECMA 开会决定,中止 ECMAScript 4.0 的开发,将其中涉及现有功能改善的一小部分,发布为 ECMAScript 3.1(会后不久,ECMAScript 3.1 就改名为 ECMAScript 5),而将其他激进的设想扩大范围,放入以后的版本。由于会议的气氛,4.0 版本的项目代号起名为 Harmony(和谐)。

  • 2009 年,ECMAScript 5.0 版正式发布。Harmony 项目则一分为二,一些较为可行的设想定名为 JavaScript.next 继续开发,后来演变成 ECMAScript 6;一些不是很成熟的设想,则被视为 JavaScript.next.next,在更远的将来再考虑推出。

  • 2011 年,ECMAscript 5.1 版发布,并且成为 ISO 国际标准。

  • 2013 年 3 月,ECMAScript 6 草案冻结,不再添加新功能。

  • 2013 年 12 月,ECMAScript 6 草案发布。

  • 2015 年 6 月,ECMAScript 6 正式通过,成为国际标准。从 2000 年算起,这时已经过去了 15 年。


ECMAScript 6 提出了很多新的特性,重点加强了模块、类声明、词法块定界、迭代器和生成器、异步编程的回调、模式解析以及合适的尾调用,另外还扩展了 ECMAScript 的内置库以支持更多的抽象数据结构。其目的就是使 JavaScript 可以用来编写复杂的应用程序,成为企业级开发语言。



发布于: 2021 年 05 月 28 日阅读数: 598
用户头像

devpoint

关注

细节的追求者 2011.11.12 加入

专注前端开发,用技术创造价值!

评论

发布
暂无评论
从 Object.assign 开始了解ES2015