此文章比较各个版本之间Angular的Extend方法
版本1.2.26
此时的Angular Extend精简至极,只进行了浅拷贝.
|
|
上面的代码多的仅仅是将传入的参数中可枚举的属性复制到dst对象,并返回这个新的对象,传入参数中靠后的argument会覆盖调靠前的.
列举一个简单的例子:
|
|
最终输出结果是
|
|
由此可见extend
依次会将传入参数的第一层属性赋值给第一个参数的第一层属性,如果属性相同,则后面的值会覆盖前面的,如果是对象或者数组,则会引用同一个,靠后的优先级高,并返回第一个参数对象.
版本1.3.9
|
|
这个版本的extend
脱离了Angular自己定义的forEach
方法,减少了代码的耦合性.
Object.keys()
由于Angular在1.2.4版本后就放弃了对IE8的支持,所以这里用了Object.keys()
去获取传入对象的可枚举属性.
关于Object.keys()
看下面这个例子:
|
|
输出结果是['name','age','say']
,由此也可以看出angular.extend()
并不支持深拷贝.
关于Object.keys()
你还要需要注意:
|
|
版本1.4.0
Angular.extend()
方法发生重大变化:
|
|
extend
方法返回一个闭包函数baseExtend
,在这里你可能会对slice.call(arguments, 1)
有疑惑.这里首先在Angular源码244行附近你会找到var slice = [].slice;
那么在baseExtend
方法中传入的第二个参数实际是[].slice.call(argumens, 1)
,其实也就是Array.prototype.slice.call()
.我们只道arguments
实际是一个带有length
属性的对象,而Array.prototype.slice.call()
这个方法可以具有length属性的对象转成数组,除了IE下的节点集合(因为ie下的dom对象是以com对象的形式实现的,js对象与com对象不能进行转换);
|
|
关于
Array.prototype.slice.call()
实现过程的猜测见肥杜的Blog Array.prototype.slice.call(arguments)
下面我们看看baseExtend
干了什么:
|
|