摘要:現在讓我們用來復制我們可能看到,當用的時候,對象屬性是遞歸復制的。到目前為止,一切看起來還不錯。如果深入研究的源碼,我們會發現,無論是還是都調用了這個內部函數。結果如下總結將框架升級到新版本是一種冒險行為。
在時間屬性上慎用Angular.js1.4的“angular.merge”函數
原文:Pay Attention to "angular.merge" in 1.4 on Date Properties
今天我將應用從Angular.js1.3.9升級到1.4的時候,發現了一些Bug。在經過一翻研究后,發現它們與時間屬性及1.4中的“angular.merge”函數有關。
在官方文檔中,“angular.merge”的表述如下:
復制src對象中的可枚舉屬性到dst對象中,以深度擴展目標對象“dst”。
同時也提到了與先前版本中的”angular.extend“的區別。
與"extend()"不同,在進行深度復制時,"merge()"支持遞歸復制。
讓我們來看一個簡單的例子,在下面的代碼中,作用域內有一個源對象和一個自定義對象,接著我用”angular.extend“將自定義對象復制到源對象中。
$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);
從結果中我們可以看到,“angular.extend”執行的是淺拷貝,像“name”,”age”和“birthDate”這些原始屬性值已經合并了,但因為“skills”和”mvp”是對象和數組,”angular.extend“會復制全部值,而不是數組或對象中的成員。
現在讓我們用“angular.merge”來復制:
$scope.merge = angular.merge({}, $scope.source, $scope.custom);
我們可能看到,當用“angular.merge”的時候,對象屬性是遞歸復制的。
到目前為止,一切看起來還不錯。但是有些人可能會發現,在使用“angular.merge”的時候,其中一個屬性“birthDate”被設成了空對象。
如果深入研究angular.js的源碼,我們會發現,無論是“angular.extend”還是“angular.merge”都調用了“baseExtend”這個內部函數。它將多個對象合并到目標對象,用一個標志參數來表明是否為深度合并。
在這個函數內部,會遍歷每個可枚舉屬性,將值復制到目標對象。如果源屬性是一個對象并且需要深度復制,Angular.js會在目標對象中創建一個空對象,并且對這個屬性遞歸執行這個函數。
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”。所以它會在目標對象中創建一個屬性名為“birthDate”的空對象,并且對“birthDate”調用“baseExtend”。但是因為“birthDate”的屬性為Date,并不是可枚舉屬性,所以這個對象不會分配到任何數據。這就是為什么結果中"birthDate"屬性為空的原因。
如果我將Angular.js 中的“baseExtend”函數復制到作用域內,并將代碼改成如下形式,當屬性為Date時,也會執行簡單的復制了。
$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);
結果如下:
總結:將框架升級到新版本是一種冒險行為。我們需要進行大量的回歸測試,以確保不會出現任何問題。我在執行E2E測試時發現了這個問題。我想這是Angular.js的Bug,我已經將這個問題貼了出來。在他們確認和修改之前,在你的應用中,慎用“angular.merge”這個函數。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78526.html
摘要:總結一下的核心對象上的方法,也幫助自己學習一下平時工作中沒怎么用到的方法,看能不能提高開發效率。我當前使用的版本是也是目前最新的穩定版本,不過在全局上,版本不同也沒什么區別。在引入了的情況下,使用方法和幾乎一樣,相當于一個語法糖。 總結一下AngularJS的核心對象angular上的方法,也幫助自己學習一下平時工作中沒怎么用到的方法,看能不能提高開發效率。我當前使用的Angularj...
摘要:總結一下的核心對象上的方法,也幫助自己學習一下平時工作中沒怎么用到的方法,看能不能提高開發效率。我當前使用的版本是也是目前最新的穩定版本,不過在全局上,版本不同也沒什么區別。在引入了的情況下,使用方法和幾乎一樣,相當于一個語法糖。 總結一下AngularJS的核心對象angular上的方法,也幫助自己學習一下平時工作中沒怎么用到的方法,看能不能提高開發效率。我當前使用的Angularj...
摘要:原型鏈理解第一件事你不用管其他語言,一句話,你只要記住里面的對象包含一個原型,原型是啥,就是另外一個對象。原型就相當于你家的車棚子,而你的那個自行車就是對象。萬事萬物皆對象有啥用一句話,擴展原型方法,給大家一到面試題,數組去重自己體會下。 概述 通過上節課的學習,大家已經會用一種json的方式定義對象了,其實這個就是傳說中的單體模式,當然這個大家不用記,關于設計模式暫時不用了解。但是總...
閱讀 2050·2021-11-08 13:22
閱讀 2511·2021-09-04 16:40
閱讀 1156·2021-09-03 10:29
閱讀 1723·2019-08-30 15:44
閱讀 2128·2019-08-30 11:13
閱讀 2797·2019-08-29 17:07
閱讀 1972·2019-08-29 14:22
閱讀 1253·2019-08-26 14:00