摘要:現(xiàn)在讓我們用來復(fù)制我們可能看到,當(dāng)用的時候,對象屬性是遞歸復(fù)制的。到目前為止,一切看起來還不錯。如果深入研究的源碼,我們會發(fā)現(xiàn),無論是還是都調(diào)用了這個內(nèi)部函數(shù)。結(jié)果如下總結(jié)將框架升級到新版本是一種冒險行為。
在時間屬性上慎用Angular.js1.4的“angular.merge”函數(shù)
原文:Pay Attention to "angular.merge" in 1.4 on Date Properties
今天我將應(yīng)用從Angular.js1.3.9升級到1.4的時候,發(fā)現(xiàn)了一些Bug。在經(jīng)過一翻研究后,發(fā)現(xiàn)它們與時間屬性及1.4中的“angular.merge”函數(shù)有關(guān)。
在官方文檔中,“angular.merge”的表述如下:
復(fù)制src對象中的可枚舉屬性到dst對象中,以深度擴(kuò)展目標(biāo)對象“dst”。
同時也提到了與先前版本中的”angular.extend“的區(qū)別。
與"extend()"不同,在進(jìn)行深度復(fù)制時,"merge()"支持遞歸復(fù)制。
讓我們來看一個簡單的例子,在下面的代碼中,作用域內(nèi)有一個源對象和一個自定義對象,接著我用”angular.extend“將自定義對象復(fù)制到源對象中。
$scope.source = { name: "Shaun", age: 35, birthDate: new Date(1997, 5, 27), skills: { dotNet: { level: "expert", years: 10 }, javaScript: { level: "newbie", years: 2 } }, mvp: [ 2011, 2012, 2013, 2014, 2015 ] }; $scope.custom = { name: "Ziyan", age: 35, skills: { dotNet: { level: "hero", years: 100, active: true }, }, mvp: [ 2016 ] }; $scope.extend = angular.extend({}, $scope.source, $scope.custom);
從結(jié)果中我們可以看到,“angular.extend”執(zhí)行的是淺拷貝,像“name”,”age”和“birthDate”這些原始屬性值已經(jīng)合并了,但因為“skills”和”mvp”是對象和數(shù)組,”angular.extend“會復(fù)制全部值,而不是數(shù)組或?qū)ο笾械某蓡T。
現(xiàn)在讓我們用“angular.merge”來復(fù)制:
$scope.merge = angular.merge({}, $scope.source, $scope.custom);
我們可能看到,當(dāng)用“angular.merge”的時候,對象屬性是遞歸復(fù)制的。
到目前為止,一切看起來還不錯。但是有些人可能會發(fā)現(xiàn),在使用“angular.merge”的時候,其中一個屬性“birthDate”被設(shè)成了空對象。
如果深入研究angular.js的源碼,我們會發(fā)現(xiàn),無論是“angular.extend”還是“angular.merge”都調(diào)用了“baseExtend”這個內(nèi)部函數(shù)。它將多個對象合并到目標(biāo)對象,用一個標(biāo)志參數(shù)來表明是否為深度合并。
在這個函數(shù)內(nèi)部,會遍歷每個可枚舉屬性,將值復(fù)制到目標(biāo)對象。如果源屬性是一個對象并且需要深度復(fù)制,Angular.js會在目標(biāo)對象中創(chuàng)建一個空對象,并且對這個屬性遞歸執(zhí)行這個函數(shù)。
function baseExtend(dst, objs, deep) { var h = dst.$$hashKey; for (var i = 0, ii = objs.length; i < ii; ++i) { var obj = objs[i]; if (!isObject(obj) && !isFunction(obj)) continue; var keys = Object.keys(obj); for (var j = 0, jj = keys.length; j < jj; j++) { var key = keys[j]; var src = obj[key]; if (deep && isObject(src)) { if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {}; baseExtend(dst[key], [src], true); } else { dst[key] = src; } } } setHashKey(dst, h); return dst; }
除了日期之外,它幾乎可以處理所有情況。如果我們定義了一個日期屬性,例如“birthDate”,它就會用“angular.isObject”檢查這個屬性是否是為對象,返回的是“true”。所以它會在目標(biāo)對象中創(chuàng)建一個屬性名為“birthDate”的空對象,并且對“birthDate”調(diào)用“baseExtend”。但是因為“birthDate”的屬性為Date,并不是可枚舉屬性,所以這個對象不會分配到任何數(shù)據(jù)。這就是為什么結(jié)果中"birthDate"屬性為空的原因。
如果我將Angular.js 中的“baseExtend”函數(shù)復(fù)制到作用域內(nèi),并將代碼改成如下形式,當(dāng)屬性為Date時,也會執(zhí)行簡單的復(fù)制了。
$scope.$baseExtend = function (dst, objs, deep) { for (var i = 0, ii = objs.length; i < ii; ++i) { var obj = objs[i]; if (!angular.isObject(obj) && !angular.isFunction(obj)) { console.log("[" + obj + "] = (skip)"); continue; } var keys = Object.keys(obj); for (var j = 0, jj = keys.length; j < jj; j++) { var key = keys[j]; var src = obj[key]; // perform deep copy if // 1. spcified by user // 2. source property is an object // 3. source property is NOT a date if (deep && angular.isObject(src) && !angular.isDate(src)) { if (!angular.isObject(dst[key])) { console.log("[" + key + "] = (Try copy an object to an non-object, create an empty for deep copy.)"); dst[key] = angular.isArray(src) ? [] : {}; } $scope.$baseExtend(dst[key], [src], true); } else { dst[key] = src; console.log("[" + key + "] = " + src); } } } return dst; }; $scope.sample = $scope.$baseExtend({}, [$scope.source, $scope.custom], true);
結(jié)果如下:
總結(jié):將框架升級到新版本是一種冒險行為。我們需要進(jìn)行大量的回歸測試,以確保不會出現(xiàn)任何問題。我在執(zhí)行E2E測試時發(fā)現(xiàn)了這個問題。我想這是Angular.js的Bug,我已經(jīng)將這個問題貼了出來。在他們確認(rèn)和修改之前,在你的應(yīng)用中,慎用“angular.merge”這個函數(shù)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78526.html
摘要:總結(jié)一下的核心對象上的方法,也幫助自己學(xué)習(xí)一下平時工作中沒怎么用到的方法,看能不能提高開發(fā)效率。我當(dāng)前使用的版本是也是目前最新的穩(wěn)定版本,不過在全局上,版本不同也沒什么區(qū)別。在引入了的情況下,使用方法和幾乎一樣,相當(dāng)于一個語法糖。 總結(jié)一下AngularJS的核心對象angular上的方法,也幫助自己學(xué)習(xí)一下平時工作中沒怎么用到的方法,看能不能提高開發(fā)效率。我當(dāng)前使用的Angularj...
摘要:總結(jié)一下的核心對象上的方法,也幫助自己學(xué)習(xí)一下平時工作中沒怎么用到的方法,看能不能提高開發(fā)效率。我當(dāng)前使用的版本是也是目前最新的穩(wěn)定版本,不過在全局上,版本不同也沒什么區(qū)別。在引入了的情況下,使用方法和幾乎一樣,相當(dāng)于一個語法糖。 總結(jié)一下AngularJS的核心對象angular上的方法,也幫助自己學(xué)習(xí)一下平時工作中沒怎么用到的方法,看能不能提高開發(fā)效率。我當(dāng)前使用的Angularj...
摘要:原型鏈理解第一件事你不用管其他語言,一句話,你只要記住里面的對象包含一個原型,原型是啥,就是另外一個對象。原型就相當(dāng)于你家的車棚子,而你的那個自行車就是對象。萬事萬物皆對象有啥用一句話,擴(kuò)展原型方法,給大家一到面試題,數(shù)組去重自己體會下。 概述 通過上節(jié)課的學(xué)習(xí),大家已經(jīng)會用一種json的方式定義對象了,其實這個就是傳說中的單體模式,當(dāng)然這個大家不用記,關(guān)于設(shè)計模式暫時不用了解。但是總...
閱讀 2045·2021-11-08 13:22
閱讀 2506·2021-09-04 16:40
閱讀 1150·2021-09-03 10:29
閱讀 1715·2019-08-30 15:44
閱讀 2124·2019-08-30 11:13
閱讀 2791·2019-08-29 17:07
閱讀 1967·2019-08-29 14:22
閱讀 1247·2019-08-26 14:00