ES2015的一些新的内容,Object.assign函数的使用,使用该函数我们可以快速的复制一个或者多个对象到目标对象中,本文内容涉及es6,es7相关的对象复制的内容,以及一些es5的替代方案的介绍。
函数原型
首先看一下函数的定义: 函数参数为一个目标对象(该对象作为最终的返回值),源对象(此处可以为任意多个)。通过调用该函数可以拷贝所有可被枚举的自有属性值到目标对象中。
Object.assign(target,...sources)
这里我们需要强调的三点是:
- 可被枚举的属性
- 自有属性
- string或者Symbol类型是可以被直接分配的
拷贝过程中将调用源对象的getter方法,并在target对象上使用setter方法实现目标对象的拷贝。
函数实例
这里我们通过几个MDN上的例子来介绍一下使用方法:
实例一
我们参考上面的原型函数说明即可知道其最开始的o1因为设置为target,则调用其setter方法设置了其他对象的属性到自身。
var o1 ={ a:1};var o2 ={ b:2};var o3 ={ c:3};var obj =Object.assign(o1, o2, o3);
console.log(obj);// { a: 1, b: 2, c: 3 }
console.log(o1);// { a: 1, b: 2, c: 3 }, target object itself is changed.
实例二
我们自定义了一些对象,这些对象有一些包含了不可枚举的属性,另外注意使用 Object.defineProperty 初始化的对象默认是不可枚举的属性。对于可枚举的对象我们可以直接使用Object.keys()获得,或者使用for-in循环遍历出来.
对于不可枚举的属性,使用Object.assign的时候将被自动忽略。
var obj =Object.create({ foo:1},{// foo is an inherit property.
bar:{
value:2// bar is a non-enumerable property.},
baz:{
value:3,
enumerable:true// baz is an own enumerable property.}});var copy =Object.assign({}, obj);
console.log(copy);// { baz: 3 }
实例三
对于只读的属性,当分配新的对象覆盖他的时候,将抛出异常:
var target =Object.defineProperty({},'foo',{
value:1,
writable:false});Object.assign(target,{ bar:2})//{bar: 2, foo: 1}Object.assign(target,{ foo:2})//Uncaught TypeError: Cannot assign to read only property 'foo' of object '#<Object>'(…)
Polyfill
这里我们简单的看下如何实现es5版本的Object.assign:
实现步骤:
- 判断是否原生支持该函数,如果不存在的话创建一个立即执行函数,该函数将创建一个assign函数绑定到Object上。
- 判断参数是否正确(目的对象不能为空,我们可以直接设置{}传递进去,但必须设置该值)
- 使用Object在原有的对象基础上返回该对象,并保存为out
- 使用for…in循环遍历出所有的可枚举的自有对象。并复制给新的目标对象(hasOwnProperty返回非原型链上的属性)
源码如下:
if(typeofObject.assign !='function'){(function(){Object.assign =function(target){'use strict';if(target ===undefined|| target ===null){thrownewTypeError('Cannot convert undefined or null to object');}var output =Object(target);for(var index =1; index < arguments.length; index++){var source = arguments[index];if(source !==undefined&& source !==null){for(var nextKey in source){if(source.hasOwnProperty(nextKey)){
output[nextKey]= source[nextKey];}}}}return output;};})();}
扩展内容
1.深度复制
当我们调用下面的函数的时候,由于Object.assign将覆盖之前的内容,所以并不能完全的做到融合对象,而是全部替换掉,所以返回的对象内容将变成最后一个值; {a: {c: 3}
Object.assign({a:{b:0}},{a:{b:1, c:2}},{a:{c:3}});
如何深层次的融合对象,比如我们期望的输出结果为:
{a:{b:1,c:3}}
这样我们必须实现自己的算法来完成深层复制了,不过github上已经有很多好的解决方案,比如deep-merge 通过递归的方式逐层的去调用assign函数。
2.ES2016实现
在es7中我们使用rest属性可以捕获所有剩余的对象内容比如下面的例子(可使用babel-repl页面测试,浏览器一般尚未支持):
let { fname, lname,...rest }={ fname:"Hemanth", lname:"HM", location:"Earth", type:"Human"};
fname;//"Hemanth"
lname;//"HM"
rest;// {location: "Earth", type: "Human"}
这样我们就可以使用该特性来实现assign函数
let oldObj1={a:"a",b:{b1:"b1"}}
let oldObj2={a:"a1",b:{b2:"b2"},c:"c"}
let newObject={...oldObj1,...oldObj2};
console.log(newObject){"a":"a1","b":{"b2":"b2"},"c":"c"}
不过仍旧只是浅层的替换,并没有实现深层次的合并。
相关推荐
angular1.4.6.min
使用angular1.x 做的web端的单页面前端框架,使用wampserver可运行查看。主要用了$state模块。
用于开发小型基于Angular的WebApp使用。 该框架主要包含 app.js - 应用启动文件 controller.js - 控制器文件 filer.js - 过滤器文件 partials文件夹 - 显示模板文件夹 services.js - 后台API访问层文件 单文件应用...
angular5.x介绍以及和vue、react对比 angular5.x介绍以及和vue、react对比
angular2文档,We developed this book to be used as course material for Rangle's Angular 2 training, but many people have found it to be useful for learning Angular 2 on their own. This book will cover...
angular1.6.5.rar
官方angular.min.js 官方angular.js
为了下载angular.min.js花费了很长时间,希望对你有用。
angular.min.js
angular deploy.doc
众所周知angular 1.x作为单页面js框架,当页面不断增加,加载js会越来越慢,该Demo可以解决按照需求加载指定js
angular4.x、angular5实战入门视频教程,angular4.x、angular5实战入门视频教程
amazing-angular-projects, 令人惊奇的开源 Angular 1.x & Angular 2.0项目集合 出色的Angular 项目令人惊奇的开源 Angular 1.x & Angular 2.0项目集合 最初发布在中。从近2 个开源项目中挑选了最上面的18个 Angular...
Embrace the full stack of web development, from styling with Bootstrap, building an interactive user interface with Angular 2, to storing data quickly and reliably in PostgreSQL. With this fully ...
Angular介绍.pptx
angular2-typescript-gulp, 一种以吞咽为基础的基本 Angular2. 带有打字和Gulp的 Angular2一种以吞咽为基础的基本 Angular2. 1.先决条件必须在系统上安装 nodejs,并且必须安装以下全局 node 软件包:吞咽npm -g ...
google网站无法下载angular.min .v1.2.11.js
angular.js-master.zip