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"//这种格式不用再进行处理 第二种:"2017-08-01 18:56:38"//这种格式就要进行处理
因为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小时内与您取得联系。