const arr = [1,1,1,1,1,1,3,3,3,3,32,2,2,2,2,3,3,4,-1,-10,-10,-1,4,4,5,5,9]
// set方式去重
// 不改變源數組的數據
console.log([...new Set(arr)])
// includes方式去重, 時間復雜度 O(n)
function uniq(arr) {
let _result = []
for(let i=0; i < arr.length; i++) {
if (!_result.includes(arr[i])) {
_result.push(arr[i])
}
}
return _result
}
console.log(uniq(arr))
let arr = [1,2,5,3,1,6,7,3,4,10,12,3,21]
function bubbleSort(arr) {
// 淺克隆, 對外部傳入的參數不進行更改, 保證函數是一個純函數
let _arr = [].concat(arr)
// 核心邏輯
for(let i=0; i<_arr.length -1; i++) {
for(let j=0; j<_arr.length-i-1; j++) {
if (_arr[j] > _arr[j+1]) {
let temp = _arr[j]
_arr[j] = _arr[j + 1]
_arr[j + 1] = temp
}
}
}
return _arr
}
console.log(bubbleSort(arr))
let arr = [300,432,1342,543,23,656,45,6465,4345,232,87,97,754,345]
function quickSort(arr) {
if(arr.length <= 1) {
return arr
}
const pivot = arr[0]
let bigger = []
let smaller = []
for(let i=1; i<arr.length; i++) {
if (arr[i] > pivot) {
bigger.push(arr[i])
}
}
for(let i=1; i<arr.length; i++) {
if (arr[i] < pivot) {
smaller.push(arr[i])
}
}
return quickSort(smaller).concat(pivot, quickSort(bigger))
}
console.log(quickSort(arr))
案例一:
function curry(fn) {
return function() {
let arg = arguments
return function() {
return fn(...arg, ...arguments)
}
}
}
function fn(a,b,c,d) {
return a+b+c+d
}
let fun = curry(fn)
let fun2 = fun(1,2,3)
console.log(fun2(5))
案例二:
let fn = a => b => c => a+b+c
console.log(fn(1)(2)(3))
let arr = [0,[3,4,5],[[[[12,5,6,7,54,34],43,34],33]], {a:1}]
function flatten(arr) {
let _arr = []
for(let i=0; i<arr.length; i++) {
const leixing = Object.prototype.toString.call(arr[i])
if (leixing !== '[object Array]') {
_arr.push(arr[i])
} else {
_arr = _arr.concat(flatten(arr[i]))
}
}
return _arr
}
console.log(flatten(arr))
Array.prototype.max = function max() {
console.log(this)
return Math.max.apply(Math, this)
}
let array = [1,2,3,4]
console.log(array.max())
let arr = [1,2,3,[4,5,6], {a:1}]
function deepClone(o) {
if (
typeof o == 'number'
||
typeof o == 'string'
||
typeof o == 'boolean'
||
typeof o == 'undefined'
) {
return o
} else if(Array.isArray(o)) {
let _arr = []
for(let i=0; i<o.length; i++) {
_arr.push(deepClone(o[i]))
}
return _arr
} else if(typeof o == 'object') {
let _o = {}
for(let k in o) {
_o[k] = deepClone(o[k])
}
return _o
}
}
let deep = deepClone(arr)
console.log(arr[3] == deep[3]) // false
// 功能: 傳入一個數值, 隨機生成指定范圍內的樣本數據
// 參數: 樣本個數
// start: 樣本起始數值
// end: 樣本結束數值
function sample(num, start, end) {
end -= 1
let _arr = []
while(num != _arr.length){
let data = parseInt(Math.random() * end) + start
if (!_arr.includes(data)) {
_arr.push(data)
}
}
return _arr
}
console.log(sample(30, 2, 32))
// 輸出結果
// [
// 9, 27, 18, 28, 24, 13, 31, 11, 6,
// 19, 7, 17, 21, 26, 30, 22, 8, 25,
// 10, 3, 2, 5, 4, 12, 20, 14, 29,
// 15, 32, 23
// ]
字符串反轉函數
let str = 'abcde'
function myReverse(str) {
return str.split('').reverse().join('')
}
let res = myReverse(str)
console.log(res)
偏函數的作用: 調用之后能夠獲得一個特定功能的函數
// 需求: 實現一個檢查類型的偏函數
function checkType(type) {
return function(o) {
return Object.prototype.toString.call(o) == `[object ${type}]`
}
}
let checkIsArray = checkType('Array')
console.log(checkIsArray([1,2,3]))
// 輸出結果
// true
閉包的特點: 調用永久記住當前作用域的變量
案例一:
var a = 2
function foo() {
var a = 1
function bar() {
console.log(a)
}
bar()
}
foo()
//輸出結果
//1
案例二:
var a = 1
function bar() {
console.log(a)
}
(function(fn) {
var a = 2
fn()
})(bar)
// 輸出結果
// 1
// 箭頭函數this跟定義時上下文永遠綁定
// 普通函數的this, 視運行環境而改變
function fun() {
return () => {
console.log(this)
}
}
let laowang = {name: 'laowang'}
let xiaoliu = {name: 'xiaoliu'}
let arrowFun = fun.call(laowang)
arrowFun() // { name: 'laowang' }
arrowFun.call(xiaoliu) // { name: 'laowang' }
arrowFun = arrowFun.bind(xiaoliu)
arrowFun() // { name: 'laowang' }
// 函數非嚴格模式下實參與實參列表的關系
function fun(a, b) {
a = (typeof a !== 'undefined') ? a : 10
b = (typeof b !== 'undefined') ? b : 20
console.log(a == arguments[0])
console.log(b == arguments[1])
a = 123
b = 456
console.log(a == arguments[0])
console.log(b == arguments[1])
}
fun(1, 2)
// 輸出結果
// true
// true
// true
// true
// 函數嚴格模式下實參與實參列表的關系
function fun(a, b) {
'use strict'
a = (typeof a !== 'undefined') ? a : 10
b = (typeof b !== 'undefined') ? b : 20
console.log(a == arguments[0])
console.log(b == arguments[1])
a = 123
b = 456
console.log(a == arguments[0])
console.log(b == arguments[1])
}
fun(1, 2)
// true
// true
// false
// false
// 函數改良
// 這種方式跟非嚴格模式下的執行結果是一致的
function fun(a=10, b=20) {
console.log(a == arguments[0])
console.log(b == arguments[1])
a = 123
b = 456
console.log(a == arguments[0])
console.log(b == arguments[1])
}
fun(1, 2)
// true
// true
// false
// false
解釋: 變量在定義之后, 但沒有聲明的情況下, 是暫時不能訪問的
// 案例一: 函數后面的默認參數可以訪問前面的參數
// 實參其實相當于使用 let來聲明一個變量
function foo(a) {
return a + 5
}
function fun(a, b = foo(a)) {
console.log(a + b)
}
fun(1) // 7
fun(1, 2) // 3
// 案例二: 函數后面的參數無法訪問前面參數的值
function add(a = b, b) {
return a + b
}
console.log(add(1, 2)) // 3
console.log(add(undefined, 2)) // ReferenceError: Cannot access 'b' before initialization
// 不使用展開運算符
let arr = [1,2,3,4]
let max = Math.max.apply(null,arr)
console.log(max)
// 改進
let arr = [1,2,3,4]
let max = Math.max(...arr)
console.log(max)
參考資料: https://www.runoob.com/js/js-strict.html
use strict解釋: 為什么使用嚴格模式:
消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為;
消除代碼運行的一些不安全之處,保證代碼運行的安全;
提高編譯器效率,增加運行速度;
為未來新版本的Javascript做好鋪墊。
"嚴格模式"體現了Javascript更合理、更安全、更嚴謹的發展方向,包括IE 10在內的主流瀏覽器,都已經支持它,許多大項目已經開始全面擁抱它。
另一方面,同樣的代碼,在"嚴格模式"中,可能會有不一樣的運行結果;一些在"正常模式"下可以運行的語句,在"嚴格模式"下將不能運行。掌握這些內容,有助于更細致深入地理解Javascript,讓你變成一個更好的程序員。
// 需求: 封裝一個迭代器
function arrIterator(arr) {
let i = 0
return {
next: function() {
let done = i > arr.length - 1 ? true : false
let value = !done ? arr[i++] : 'undefined'
return {
done,
value
}
}
}
}
let arr = [1,2,3,4,5]
let iterator = arrIterator(arr)
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
// 輸出結果
// { done: false, value: 1 }
// { done: false, value: 2 }
// { done: false, value: 3 }
// { done: false, value: 4 }
// { done: false, value: 5 }
// { done: true, value: 'undefined' }
// 生成器
// 作用: 用于生成迭代器
function *generator(arr) {
for(let i=0; i<arr.length; i++) {
yield arr[i]
}
}
let arr = [1,2,3,4,5]
const arrIterator = generator(arr)
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
// 生成器
// 作用: 用于生成迭代器
// 案例一
function *generator(arr) {
for(let i=0; i<arr.length; i++) {
yield arr[i]
}
}
let arr = [1,2,3,4,5]
const arrIterator = generator(arr)
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
console.log(arrIterator.next())
// 輸出結果
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// { value: 4, done: false }
// { value: 5, done: false }
// { value: undefined, done: true }
// 案例二
// 生成器可以yield 一個Promise實例對象
function *generator() {
yield sumAfter1000ms(1,2).then(res => console.log(res))
yield sumAfter1000ms(2,2).then(res => console.log(res))
}
function sumAfter1000ms(a,b) {
return new Promise((resolve, reject) => {
setTimeout(function(){
resolve(a+b)
}, 2000)
})
}
const iterator = generator()
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
// 輸出結果
// { value: Promise { <pending> }, done: false }
// { value: Promise { <pending> }, done: false }
// { value: undefined, done: true }
// 3
// 4
promise作用:
- 解決毀掉地獄的問題
- 使代碼調用更加清晰易懂
promise的三種狀態:
- pending
- resolve
- reject.
promise特點:
- 使用resolve和reject封裝結果回調函數
- Promise的實例會調用.then方法
// 案例一
// 不使用promise的情況
function fun(a, b, cb) {
setTimeout(function(){
return cb(a + b)
}, 2000)
}
fun(1,2, res => {
console.log(res)
fun(3,4, res => {
console.log(res)
fun(4, 5, res => {
console.log(res)
})
})
})
// 案例二: 使用promise的寫法
function sum(a,b) {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve(a + b)
}, 2000)
})
}
sum(1,2)
.then(res => {
console.log(res)
})
// 案例三: 使用promise寫法封裝一個讀文件操作函數
const fs = require('fs')
function readFile(filename) {
return new Promise((resolve, reject) => {
fs.readFile(filename, (err, res) => {
if (err) {
reject(new Error('所讀的文件不存在'))
return
}
resolve(res.toString())
})
})
}
readFile('./1.txt').then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
題,就像題目說的需要計算出時間差,雖然不太難,但這個需求經常會在項目中遇到的,我在這邊做一下整理,希望能夠盡量全的整理出來。有需要的朋友可以做一下參考,喜歡的可以點波贊,或者關注一下,希望可以幫到大家。
分享之前我先推薦下我自己的web前端學習交流群:675498134,不管你是小白還是大神,我都歡迎你們進群交流,不定期分享干貨,包括我自己整理的最新的前端資料和教程送給大家,歡迎初學和進階中的小伙伴,一起學習一起交流,共同進步。
計算時間差原理:
getTime()方法
方法定義: getTime() 方法可返回距 1970 年 1 月 1 日之間的毫秒數。
通常我們計算時間差都是通過獲取兩個時間數據,然后分別使用getTime()方法返回與固定的1970 年 1 月 1 日的時間差,通過對返回毫秒數的差,換算成時間單位,得出兩個時間的時間差。
開始操作:
首先你會有一串初始的時間數據,然后通過 new Date(你的時間數據),將你的數據轉成Date對象的形式。
var t1="2017/08/28 04:56:38"; //數據 var dateBegin = new Date(t1);//轉化為Date對象的形式 //Mon Aug 28 2017 04:56:38 GMT+0800 (中國標準時間) 這里就是Date對象的數據形式
時間格式
這里的話就要注意一下后端給的時間數據格式的問題,比如下面兩種:
第一種:"2017/08/28 04:56:38"http://這種格式不用再進行處理 第二種:"2017-08-01 18:56:38"http://這種格式就要進行處理
因為new Date()方法不能處理第二種數據,所以我們這里需要將第二種數據格式轉化為第一種數據的格式。
var t1="2017-05-12 00:13:53"; var dateBegin = new Date(d1.replace(/-/g, "/"));//replace方法將-轉為/
不知道大家是什么情況,反正因為我們后端給我的數據就是第二種的,所以我會提一下這個東西(捂臉)。
另一個時間數據:
既然是時間差的話,就肯定要有兩個數據,不然怎么兩相比較,一般兩個數據中都會有一個當前時間的數據。
var dateEnd = new Date();//當前時間數據
完整計算時間差(天、小時、分鐘、秒)的代碼:
先獲取之間的毫秒差,通過毫秒差換算出你所需要的時間單位,然后時間單位之間的換算根據的是他們的倍數關系。
function timeFn(d1) {//di作為一個變量傳進來 //如果時間格式是正確的,那下面這一步轉化時間格式就可以不用了 var dateBegin = new Date(d1.replace(/-/g, "/"));//將-轉化為/,使用new Date var dateEnd = new Date();//獲取當前時間 var dateDiff = dateEnd.getTime() - dateBegin.getTime();//時間差的毫秒數 var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000));//計算出相差天數 var leave1=dateDiff%(24*3600*1000) //計算天數后剩余的毫秒數 var hours=Math.floor(leave1/(3600*1000))//計算出小時數 //計算相差分鐘數 var leave2=leave1%(3600*1000) //計算小時數后剩余的毫秒數 var minutes=Math.floor(leave2/(60*1000))//計算相差分鐘數 //計算相差秒數 var leave3=leave2%(60*1000) //計算分鐘數后剩余的毫秒數 var seconds=Math.round(leave3/1000) console.log(" 相差 "+dayDiff+"天 "+hours+"小時 "+minutes+" 分鐘"+seconds+" 秒") console.log(dateDiff+"時間差的毫秒數",dayDiff+"計算出相差天數",leave1+"計算天數后剩余的毫秒數" ,hours+"計算出小時數",minutes+"計算相差分鐘數",seconds+"計算相差秒數"); } var t3="2017-08-18 04:56:38"; timeFn(t3);
demo時間差數據截圖
不成熟的計算月、年:
//這里的dayDiff就是上文計算出的天數差 let monthDiff=Math.floor(dayDiff/30);//以30天為一個月不夠精準嚴謹 //獲取相差的月份 if (monthDiff<12){ timeThis=monthDiff+"個月前發布";//獲取相差的月份 return } let yearDiff=Math.floor(monthDiff/12);//獲取相差的年份 if(yearDiff>=1){ timeThis=yearDiff+"年前發布"; return }
當天數相差較大的時候,單純計算天數已經不能滿足需求了,因為我們PM說的統一以30天為一個月的分界線,然后這里月份的計算情況感覺很復雜的樣子沒有繼續研究下去。
獲取當前月份的天數
function getDays() { //構造當前日期對象 var date = new Date(); var year = date.getFullYear();//獲取年份 var mouth = date.getMonth() + 1;//獲取當前月份 var days;//定義當月的天數; if (mouth == 2) {//當月份為二月時,根據閏年還是非閏年判斷天數 days = year % 4 == 0 ? 29 : 28; } else if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10 || mouth == 12) { //月份為:1,3,5,7,8,10,12 時,為大月.則天數為31; days = 31; } else { //其他月份,天數為:30. days = 30; } return days; }
網上找了個獲取當前月份天數的函數,上面的注釋也足夠全,我就一起貼上來,連接在下面。
后話
上面就是本文計算時間差的內容了,希望看完本文能給大家一點幫助。最后一個提示:一般需要處理的數據不會只有一兩個,很可能會給一個數組,你需要處理每個數組元素的時間數據,這時候建議用forEach()函數遍歷整個數組。
如果覺得我的文章對您有用,請點贊收藏。您的支持將鼓勵我繼續創作。
知識分享到這里就結束了,web前端學習的可以來我的群,群里每天都有對應資料學習:675498134,歡迎初學和進階中的小伙伴。
在JavaScript或Vue中獲取當前時間并格式化輸出到精確的時分秒,你可以使用Date對象結合字符串拼接或者模板字符串來實現。下面是一個簡單示例,展示了如何在Vue中完成這項任務:
<template>
<div>
<p>當前時間:{{ formattedTime }}</p>
</div>
</template>
<script>
export default {
data() {
return {
formattedTime: ''
};
},
mounted() {
this.updateTime();
setInterval(this.updateTime, 1000); // 每秒更新一次
},
methods: {
updateTime() {
const now = new Date();
// 使用模板字符串進行格式化
this.formattedTime = `${now.getFullYear()}-${this.padZero(now.getMonth() + 1)}-${this.padZero(now.getDate())} ${this.padZero(now.getHours())}:${this.padZero(now.getMinutes())}:${this.padZero(now.getSeconds())}`;
},
// 輔助函數,用于補零操作
padZero(num) {
return num < 10 ? '0' + num : num;
}
},
beforeDestroy() {
// 清除定時器,避免內存泄漏
clearInterval(this.timer);
}
};
</script>
在這個示例中,我們在Vue組件的mounted生命周期鉤子中初始化了一個定時器,每秒鐘調用updateTime方法來更新當前時間,并在組件銷毀前通過beforeDestroy鉤子清理定時器。
updateTime方法中,我們創建了一個新的Date對象來獲取當前時間,然后使用模板字符串和輔助函數padZero來確保月份、日期、小時、分鐘和秒數如果是個位數,則在其前補零,以便格式統一和美觀。
這樣,頁面上就會顯示一個實時更新的當前時間,格式為“年-月-日 時:分:秒”。
在Vue3中,雖然一些API和寫法有所變化,但獲取和格式化當前時間的基本邏輯與Vue2相似。以下是使用Vue3 Composition API的一個示例:
<template>
<div>
<p>當前時間:{{ formattedTime }}</p>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
const formattedTime = ref('');
let timer = null;
const updateTime = () => {
const now = new Date();
formattedTime.value = `${now.getFullYear()}-${padZero(now.getMonth() + 1)}-${padZero(now.getDate())} ${padZero(now.getHours())}:${padZero(now.getMinutes())}:${padZero(now.getSeconds())}`;
};
const padZero = (num) => {
return num < 10 ? '0' + num : num;
};
onMounted(() => {
updateTime();
timer = setInterval(updateTime, 1000); // 每秒更新一次
});
onBeforeUnmount(() => {
// 清除定時器
clearInterval(timer);
});
</script>
在這個Vue3的示例中,我們使用了Composition API來管理狀態和生命周期鉤子。ref用于定義響應式數據formattedTime,而onMounted和onBeforeUnmount分別替代了Vue2中的mounted和beforeDestroy生命周期鉤子。
updateTime函數和padZero輔助函數的功能與Vue2示例相同,用于獲取當前時間并進行格式化處理,以及在數字小于10時前面添加零。
這樣,你就可以在Vue3應用中實現實時更新并格式化顯示當前時間的功能。
使用TypeScript可以為你的代碼增加類型安全。下面是如何封裝一個獲取并格式化當前時間的公共函數,這個函數可以在Vue3的項目中作為公共方法使用。
首先,在你的Vue3項目的某個公用文件夾(如src/utils)下創建一個名為dateTimeUtils.ts的文件,并編寫如下代碼:
// src/utils/dateTimeUtils.ts
export function formatCurrentTime(): string {
const now = new Date();
return `${now.getFullYear()}-${padZero(now.getMonth() + 1)}-${padZero(now.getDate())} ${padZero(now.getHours())}:${padZero(now.getMinutes())}:${padZero(now.getSeconds())}`;
}
function padZero(num: number): string {
return num < 10 ? '0' + num : num.toString();
}
這個模塊導出了一個formatCurrentTime函數,它返回當前時間的格式化字符串。同時,內部使用了padZero輔助函數來保證數字的格式正確。
然后,在你的Vue3組件中,你可以這樣使用這個公共函數:
// 某個Vue3組件.vue文件
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { formatCurrentTime } from '@/utils/dateTimeUtils'; // 根據你的實際路徑調整
const formattedTime = ref('');
onMounted(() => {
formattedTime.value = formatCurrentTime();
setInterval(() => {
formattedTime.value = formatCurrentTime();
}, 1000);
});
</script>
<template>
<div>
<p>當前時間:{{ formattedTime }}</p>
</div>
</template>
這里,我們導入了formatCurrentTime函數,并在組件掛載時設置初始值,之后每秒更新一次顯示的時間。注意,為了避免潛在的內存泄漏,如果組件需要銷毀時停止時間更新,你可能還需要在適當的生命周期鉤子中清除定時器,正如之前Vue2和Vue3 Composition API示例中所示。不過,在此示例中為了保持簡潔,省略了該部分代碼。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。