从 Object.assign 开始了解ES2015

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

image.png

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会跳过那些值为 nullundefined 的源对象。

实例

  • 复制一个对象
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() 方法在复制对象时会忽略nullundefined。请看下面列出的代码:

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可以用来编写复杂的应用程序,成为企业级开发语言。


相关文章
|
6月前
|
JavaScript 前端开发
object.assign
object.assign
35 0
|
7月前
|
JSON JavaScript 前端开发
Object.assign
Object.assign
52 1
|
JavaScript
js的Object.assign坑
js的Object.assign坑
68 0
|
前端开发 索引
Array.prototype.at
Array.prototype.at
86 0
|
Java 数据库连接 mybatis
@TableId(type = IdType.ASSIGN_ID)
@TableId(type = IdType.ASSIGN_ID)
183 1
|
JavaScript 开发者
ES6之Object.assign()用法,Object.assign()到底是浅拷贝还是深拷贝?
ES6之Object.assign()用法,Object.assign()到底是浅拷贝还是深拷贝?
9069 1
Object.assign详解
Object.assign详解
270 0
|
JavaScript API
Array.apply(null,{length: 99}) 逻辑解析
Array.apply(null,{length: 99}) 逻辑解析
88 0
|
前端开发
前端学习案例1-object.assign
前端学习案例1-object.assign
68 0
前端学习案例1-object.assign
|
前端开发
前端学习案例5-object.assign的应用
前端学习案例5-object.assign的应用
68 0
前端学习案例5-object.assign的应用