`
tooby
  • 浏览: 117296 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Angular的Object.assign

 
阅读更多

ES2015的一些新的内容,Object.assign函数的使用,使用该函数我们可以快速的复制一个或者多个对象到目标对象中,本文内容涉及es6,es7相关的对象复制的内容,以及一些es5的替代方案的介绍。

函数原型

首先看一下函数的定义: 函数参数为一个目标对象(该对象作为最终的返回值),源对象(此处可以为任意多个)。通过调用该函数可以拷贝所有可被枚举的自有属性值到目标对象中。

Object.assign(target,...sources)

这里我们需要强调的三点是:

  1. 可被枚举的属性
  2. 自有属性
  3. 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:

实现步骤:

  1. 判断是否原生支持该函数,如果不存在的话创建一个立即执行函数,该函数将创建一个assign函数绑定到Object上。
  2. 判断参数是否正确(目的对象不能为空,我们可以直接设置{}传递进去,但必须设置该值)
  3. 使用Object在原有的对象基础上返回该对象,并保存为out
  4. 使用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"}

不过仍旧只是浅层的替换,并没有实现深层次的合并。

分享到:
评论

相关推荐

    monad-ts:Monad-ts是一个小型库,实现了一些关键的monad以及将其链接到JavaScript和TypeScript中的流(管道)中的方法

    在库中使用ES5(Array.map,Array.reduce,Array.some,Array.isArray,Object.getOwnPropertyNames),ES6(Map,Array.from,Object.assign,Object.keys,Object.is)方法。 强烈建议始终使用ES5-shim和ES6-shim...

    AngularDynamicForms使用动态组件在Angular中可配置的活动表单

    Object.assign(componentRef.instance, inputs); this.componentRefs.push(componentRef); } // 在不再需要时销毁组件 destroyComponents() { this.componentRefs.forEach(ref =&gt; ref.destroy()); this....

    《JavaScript开发王》.pdf

    另外,Object对象提供了许多方法用于操作对象属性,如Object.keys、Object.values、Object.assign等。 ES6(ECMAScript 2015)及后续版本引入了许多新特性,如箭头函数、模板字符串、解构赋值、类和模块系统等,...

    angular2-immutable:Angular 2 IterableDiff和KeyValueDiff用于增强不可变数据结构的强大功能

    2. 使用`Object.assign()`或`{...}`语法:对于对象,可以使用`Object.assign()`合并新的属性到新对象,或者使用ES6的扩展运算符`{...}`创建一个新对象。 3. 使用Lodash等库:第三方库如Lodash提供了许多实用函数,如...

    牛:牛| 强大的Web组件框架库

    奥克斯 一个强大的小型Web组件框架/库。 API 可以在找到Api文档。... Event,CustomEvent,MouseEvent构造函数以及Object.assign,Array.from 包含所有内容。 Webcomponents.js 文档片段 URL,承诺,获取 支持

    webkit-assign-loader:Webpack加载器的webkit分配来处理WebKit问题#138038

    由于[WebKit问题#138038] [],在使用Object.create创建的对象上分配属性可能会导致错误TypeError: Attempted to assign to readonly property. 。 已知此错误会影响iOS 8用户,尤其是在[Angular.js] []的最新版本...

    JavaScript 中文参考手册(CHM)

    此外,JavaScript还提供了数组方法(如map、filter、reduce等)和对象方法(如Object.keys、Object.assign等),这些方法使得操作数据更加便捷。 错误处理是任何编程语言都必不可少的部分,JavaScript使用try......

    已总结好的 JS语法字典

    ES6引入的Object.assign()用于合并对象,Object.keys()获取对象的所有属性名,以及展开运算符({...obj})用于复制对象。 6. 控制流: 条件语句如if...else,switch...case;循环语句包括for、while、do...while,...

    objectAssignment:使用CodeSandbox创建

    在JavaScript中,对象赋值可以通过多种方式实现,如浅拷贝、深拷贝、扩展运算符以及Object.assign()方法。下面我们将深入探讨这些概念及其在CodeSandbox中的应用。 1. **浅拷贝**:浅拷贝仅复制对象的第一层属性,...

    Angular搜索场景中使用rxjs的操作符处理思路

    这里使用`Object.assign()`是为了每次发送一个新的对象副本,避免`distinctUntilChanged`因为比较的是同一个引用而导致始终认为值未改变。 接着,我们使用`pipe`方法结合`debounceTime`和`distinctUntilChanged`...

    神族九帝'博客.zip

    后续的ES7、ES8等版本也不断添加新的语法和功能,如async/await、Object.assign等。 8. **模块系统**:ES6引入了模块系统,使用import和export关键字进行模块的导入和导出,便于代码组织和复用。 9. **Node.js**:...

    JavaScript使用手册

    了解原型链、构造函数、this关键字以及Object.create()和Object.assign()方法对于理解对象行为至关重要。 5. **数组**:JavaScript的数组具有内置的方法,如push、pop、shift、unshift、splice、map、filter、...

    javascript知识图谱

    ES7、ES8乃至ES11也不断添加新的功能,如async/await、Object.assign、Object Rest/Spread等。 8. **JavaScript引擎与性能优化** 了解V8引擎的工作原理,如垃圾回收机制、优化编译(TurboFan和Ignition),以及...

    JavaScript

    后续版本ES7至ES11继续添加了更多的语法糖和功能,如async/await、Object.assign、Set和Map等。 8. **浏览器兼容性**:由于JavaScript的实现依赖于不同的浏览器,开发者需要关注不同浏览器对特定API的支持情况。...

    分享那些有趣的 Bug。推荐一些有意思的前端技巧。聊聊前端面试等。.zip

    - 利用`Object.assign()`或解构赋值实现浅拷贝和深拷贝。 - 利用CSS变量(Custom Properties)实现主题切换。 9. **前端面试中的实战题目**: - 实现一个简单的计算器或Todo应用。 - 解释如何实现一个自定义...

    JavaScript入门到精通

    ECMAScript 6(ES6,也称ES2015)引入了类、箭头函数、模板字符串、解构赋值、Promise、Set和Map等新特性,后续版本如ES2017、ES2018等持续扩展,如async/await、Object.assign等。 8. **JavaScript框架与库** 如...

    practice_portal

    3. **对象**:创建对象(字面量方式、构造函数、Object.create)、属性访问(点号与方括号)、原型链与继承、Object的方法(如Object.keys、Object.values、Object.assign)。 4. **数组方法**:push、pop、shift、...

    js代码-阿里面试题

    7. **对象操作**:掌握Object.keys()、Object.values()、Object.assign()等方法,以及深拷贝与浅拷贝的区别。 8. **正则表达式**:正则用于字符串的匹配和操作,理解和熟练运用各种正则表达式模式对于字符串处理至...

    一个经典的javascript教程

    后续版本如ES7、ES8等继续添加了更多的语言特性,如async/await、Object.assign等,使JavaScript更加现代和强大。 9. **JavaScript调试** 学会使用浏览器的开发者工具进行断点调试、查看变量值、跟踪调用堆栈,是...

Global site tag (gtag.js) - Google Analytics