最近翻到 ElementUI 的日期組件源碼,看到一些處理日期的工具方法,挺有意思,平常沒有註意到,特此記錄下來。 ### 獲取當前日期的前一天,後一天 ```js export const prevDate = function(date, amount = 1) { return new Dat ...
最近翻到 ElementUI 的日期組件源碼,看到一些處理日期的工具方法,挺有意思,平常沒有註意到,特此記錄下來。
獲取當前日期的前一天,後一天
export const prevDate = function(date, amount = 1) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() - amount);
};
export const nextDate = function(date, amount = 1) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount);
};
這裡獲取當前日期的前一天用的是 date.getDate() - 1
而不是 date.getTime() - 24 * 60 * 60 * 1000
是為了避免在夏令時轉換時導致的錯誤。
在某些國家,比如英國,每年都會實行夏令時制。
夏令時,又稱作Daylight Saving Times(DST),是為了節省能源而人為規定的時間制度,夏天天亮得早,所以大家早起一個小時,就能多享受日光,從而減少用電量。冬天晚起一個小時,早上就能將將趕上天亮。
每年夏天的時候,英國都要把時間往前調一個小時,變成+1。比如:每年在三月最後一個周日的夜晚,時間會神奇地從00:59直接變成02:00。這就是夏令時的時間變化
所以在夏令時起止當天如果用 date.getTime() (+)- 24 * 60 * 60 * 1000
獲取前一天後一天可能會導致錯誤。
創建包含 1-N 的數組
Element 的做法是利用 Function.prototype.apply
的第二個參數可以是類數組對象來實現;
export const range = function(n) {
return Array.apply(null, {length: n}).map((_, n) => n);
};
上面的 Array.apply(null, {length: n})
將會創造 n
個值為 undefined
的數組,再利用 map
函數一個個改變數組值;
還有很多種實現方法,而且有比上面執行速度更快的方法;
(1)Array.from()
// 第一種
Array.from(Array(N), (_, i) => i+1)
// 第二種
Array.from({length: N}, (_, i) => i + 1)
// 第三種
Array.from({length:N}, Number.call, i => i + 1)
Array.from()
可以通過 可迭代對象 和 類數組對象(帶有 length
屬性和索引元素的對象) 來創建數組;
並且如果 類數組對象 只有length
屬性沒有索引元素,那麼創建的數組值都為 undefined
參考
Array.from()
的第二個參數為一個可選的 mapFn
,類似於數組 map
函數;但不同的是Array.from()
的 mapFn
會對空槽元素執行回調函數;上面方式的比 Array.apply(null, {length: n}).map((_, n) => n);
的優勢是不會創建中間數組;
第三種方法,第三個參數是一個函數,會被 Number.call
當作 this
調用
(2)while 循壞
let i=0, a=Array(N);
while(i<N) a[i++]=i;
(3)for 迴圈
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
(4)Array.prototype.fill
Array(N).fill().map((_, i) => i+1);
和 Array.from()
類似,Array(N).fill()
也會創建 N
個值為 undefined
的數組;
(5)Array(N).join().split(',')
Array(N).join().split(',').map((_, i) => i+1 );
Array(N)
會創建 N
個空槽組成的數組,空槽既不是 undefined
,也不是空字元串;並且 map
也不會對空槽元素執行回調函數,所以需要通過 Array(N).join().split(',')
將會得到 N
個字元串組成的數組;
(6)擴展運算符
[...Array(N).keys()].map(x => x + 1);
[...Array(N+1).keys()].slice(1)
[...Array(N)]
擴展運算符會將空槽元素轉化為 undefined
(7)Uint8Array
new Uint8Array(5).map((item, i) => i + 1);
性能
對以上方式進行性能測試,測試工具是 jsbench ,測試的的瀏覽器版本是谷歌 115.0.5790.110(正式版本) (64 位)
結果如下
設置初始值 N 為 1000000,ops 為每秒操作數,圖中結果按照從高到低排序;while
迴圈最快