進(jìn)階6 Math & Array & Date

Math任務(wù)

1、寫(xiě)一個(gè)函數(shù),返回從min到max之間的 隨機(jī)整數(shù),包括min不包括max

function random(min, max){
  return min + Math.floor(Math.random()*(max-min))
}

2、寫(xiě)一個(gè)函數(shù),返回從min都max之間的 隨機(jī)整數(shù),包括min包括max

function random(min, max){
  return min + Math.floor(Math.random()*(max+1 -min))
}

3、寫(xiě)一個(gè)函數(shù),生成一個(gè)長(zhǎng)度為 n 的隨機(jī)字符串,字符串字符的取值范圍包括0到9,a到 z,A到Z。

function getRandStr(len){
  var dict = '0123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP'
  var str = ''
  for(var i = 0; i < len; i++){
    str += dict[Math.floor(Math.random()*62)]
  }
  return str
}
var str = getRandStr(10)

4、寫(xiě)一個(gè)函數(shù),生成一個(gè)隨機(jī) IP 地址,一個(gè)合法的 IP 地址為 0.0.0.0~255.255.255.255

function getRandIP(){
  var arr = []
  for(var i = 0; i < 4; i++){
    arr.push(Math.floor(Math.random()*256))
  }
  return arr.join('.')
}

var ip = getRandIP()
console.log(ip)

5、寫(xiě)一個(gè)函數(shù),生成一個(gè)隨機(jī)顏色字符串,合法的顏色為#000000~ #ffffff

function getRandColor(){
  var dict = '0123456789abcdef'
  var str = ''
  for(var i = 0; i < 6; i++){
    str += dict[Math.floor(Math.random()*16)]
  }
  str = '#' + str
  return str
}
var color = getRandColor()
console.log(color)   // #a34fdb

數(shù)組任務(wù)

1.1 數(shù)組方法里push、pop、shift、unshift、join、splice分別是什么作用?

var arr = [1, 2, 3, 4]
arr.push('wangpeng') // 在數(shù)組的最后面添加一個(gè)元素, 返回?cái)?shù)組的長(zhǎng)度 5
console.log(arr)  //  [1, 2, 3, 4, 'wangpeng']
arr.pop() // 把數(shù)組的最后一個(gè)元素取出來(lái),返回這個(gè)元素 4
console.log(arr)  // [1, 2, 3]
arr.unshitf('wangpeng') //  在數(shù)組的最前面添加一個(gè)元素, 返回?cái)?shù)組的長(zhǎng)度 5
console.log(arr)  // ['wangpeng', 1, 2, 3, 4]
arr.shift() // 把數(shù)組的第一個(gè)元素取出來(lái),返回這個(gè)元素 1
console.log(arr)  // [2, 3, 4]
var str1 = arr.join()
// 把數(shù)組中的所有元素放入一個(gè)字符串, 元素是通過(guò)指定的分隔符進(jìn)行分隔, 參數(shù)為空則和數(shù)組一樣,用逗號(hào)分隔
console.log(str1)  // 1,2,3,4
console.log(arr)  // [1, 2, 3, 4]
var str2 = arr.join("") // 表示用空字符串連接
console.log(str2)  // 1234
var arr1 = arr.splice(1,2) // 從arr中,下標(biāo)為1的元素開(kāi)始,拿出2個(gè)元素作為數(shù)組返回,原數(shù)組發(fā)生改變 [2, 3]
console.log(arr) // [1, 4]

1.2 用 splice函數(shù)分別實(shí)現(xiàn)push、pop、shift、unshift方法

JavaScript提供了一個(gè)splice方法用于一次性解決數(shù)組添加、刪除(這兩種方法一結(jié)合就可以達(dá)到替換效果),方法有三個(gè)參數(shù)

  1. 開(kāi)始索引 (可以是負(fù)數(shù),表示從后向前索引, - 1 可以理解為 arr.length - 1)
  2. 刪除元素的位移
  3. 插入的新元素,當(dāng)然也可以寫(xiě)多個(gè)

splice方法返回一個(gè)由刪除元素組成的新數(shù)組,沒(méi)有刪除則返回空數(shù)組

arr.splice(arr.length-1, 0, 5) // push 在 arr 中最后面,添加元素 5
//  當(dāng)然這里的length-1 中  - 1 不是必須的,只要大于等于數(shù)組下標(biāo),添加的元素都會(huì)在最末尾
//  并且可以用 -1 來(lái)替換 arr.length 
arr.splice(arr.length-1, 1) // pop 從arr 中刪除最后一個(gè)元素,并返回這個(gè)由刪除元素組成的新數(shù)組,原數(shù)組改變
//這里也可以是 - 1,表示arr 最后一位, 但是和上面的添加元素不同,這里第一個(gè)參數(shù)超出 arr 最大下標(biāo)之后,返回空數(shù)組,也就是沒(méi)有刪除
arr.splice(0, 0, 0) // unshift 在 arr 中最前面,添加元素 0
arr.splice(0, 1) // shift 從 arr 中刪除第一個(gè)元素

2. 寫(xiě)一個(gè)函數(shù),操作數(shù)組,數(shù)組中的每一項(xiàng)變?yōu)樵瓉?lái)的平方,在原數(shù)組上操作

方法一: 雖然原數(shù)組變了,但是函數(shù)內(nèi)部,不是在原數(shù)組操作,而是把平方結(jié)果進(jìn)行賦值

function squareArr(arr){
  for(var i = 0; i < arr.length; i++){
    arr[i] = arr[i] * arr[i]
  }
}
var arr = [2, 4, 6]
squareArr(arr)
console.log(arr) // [4, 16, 36]

方法二: 使用splice方法, 在原數(shù)組上進(jìn)行替換(實(shí)際過(guò)程是: 刪除+新增)

function squareArr(arr){
  for(var i = 0; i < arr.length; i++){
    arr.splice(i,1,Math.pow(arr[i],2))
  }
}
var arr = [2, 4, 6]
squareArr(arr)
console.log(arr) // [4, 16, 36]

3. 寫(xiě)一個(gè)函數(shù),操作數(shù)組,返回一個(gè)新數(shù)組,新數(shù)組中只包含正數(shù)

首先是直接在原數(shù)組上操作,最后原數(shù)組發(fā)生改變

function filterPositive(arr){
  for(var i = 0; i < arr.length; i++){
    if( typeof arr[i] !== 'number' || arr[i] <= 0 ){
      arr.splice(i,1)
      i--
    }
  }
}
var arr = [3, -1,  2,  '饑人谷', true]
filterPositive(arr)
console.log(arr) //[3,  2]

正確方法是向新的數(shù)組內(nèi) push 元素,然后return 新的數(shù)組,這樣返回的才是新數(shù)組,而原數(shù)組不變

function filterPositive(arr){
  var newArr = []
  for(var i = 0; i < arr.length; i++){
    if(typeof arr[i] === 'number' && arr[i] > 0 ){
      newArr.push(arr[i])
    }
  }
  return newArr
}
var arr = [3, -1,  2,  '饑人谷', true]
var newArr = filterPositive(arr)
console.log(newArr) //[3, 2]
console.log(arr) //[3, -1,  2,  '饑人谷', true]

Date 任務(wù)

1、 寫(xiě)一個(gè)函數(shù)getChIntv,獲取從當(dāng)前時(shí)間到指定日期的間隔時(shí)間

function getChIntv(dateStr){
  var targetDate = new Date(dateStr) // 目標(biāo)時(shí)間的時(shí)間對(duì)象
  var curDate = new Date() // 當(dāng)前時(shí)間的時(shí)間對(duì)象
  var offset = Math.abs(targetDate - curDate) // 得到時(shí)間毫秒數(shù)的時(shí)間差 
  // 毫秒數(shù)如何變?yōu)?天時(shí)分秒呢?
  var totalSeconds = Math.floor(offset/1000) // 得到取整后的總的秒數(shù)
  var seconds = totalSeconds%60 // 得到無(wú)法轉(zhuǎn)換為分鐘數(shù)后,剩下的秒數(shù)
  var totalMinutes = Math.floor(totalSeconds/60)  // 總的整數(shù)分鐘數(shù)
  var minutes = totalMinutes%60 // 得到無(wú)法轉(zhuǎn)換為小時(shí)數(shù)后,剩下的分鐘數(shù)
  var totalHours =Math.floor(totalMinutes/60) // 總的整數(shù)小時(shí)數(shù)
  var hours = totalHours%24 // 得到轉(zhuǎn)換為天數(shù)后,剩下的小時(shí)數(shù)
  var totalDays = Math.floor(totalHours/24) // 得到總的整數(shù)天數(shù)
  // 取整后,總會(huì)由更小的單位來(lái)表示取整后表達(dá)不了的余數(shù), 
  // 或者理解為當(dāng)前的余數(shù)有表示單位了,更大的單位盡管放心取整,而不會(huì)損失精度
  return totalDays + '天' + hours + '小時(shí)' + minutes + '分' + seconds + '秒'
}

2、把hh-mm-dd格式數(shù)字日期改成中文日期

function getChsDate(dateStr){
  var targetDate = new Date(dateStr)
  var dict = '零一二三四五六七八九十'

  var strDigitYear = targetDate.getFullYear().toString() // 2015
  var strDigitMonth = (targetDate.getMonth() + 1).toString()  // 12
  var strDigitDay = targetDate.getDate().toString()  // 8
  var strYear = ''
  var strMonth = ''
  var strDay = ''

  for(var i = 0; i < 4; i++){
    strYear += dict[strDigitYear[i]] /*漢字*/ 
  }

  if(strDigitMonth.length === 2){
    if (strDigitMonth != 10){
      strMonth = '十' + dict[strDigitMonth[1]]
    }else{
      strMonth = '10'
    }
  } else{
    strMonth = dict[strDigitMonth]
  }

  if(strDigitDay < 11){
    strDay = dict[strDigitDay] // 0 ~ 10
  }else if(strDigitDay >10 && strDigitDay < 20){
    strDay = '十' + dict[strDigitDay[1]]
  }else if(strDigitDay == 20 || strDigitDay == 30){
    strDay = dict[strDigitDay[0]] + '十'
  }else if(strDigitDay >20 && strDigitDay < 30){
    strDay = '二十' + dict[strDigitDay[1]]
  }else{
    strDay = '三十一'
  }

  return strYear + '年' + strMonth + '月' + strDay + '日'
}

var str = getChsDate('2015-12-08');
console.log(str);  // 二零一五年十二月八日 0~10, 11~19, 20, 21~29, 30, 31

3、寫(xiě)一個(gè)函數(shù),參數(shù)為時(shí)間對(duì)象毫秒數(shù)的字符串格式,返回值為字符串。假設(shè)參數(shù)為時(shí)間對(duì)象毫秒數(shù)t,根據(jù)t的時(shí)間分別返回如下字符串:

剛剛( t 距當(dāng)前時(shí)間不到1分鐘時(shí)間間隔)

3分鐘前 (t距當(dāng)前時(shí)間大于等于1分鐘,小于1小時(shí))
8小時(shí)前 (t 距離當(dāng)前時(shí)間大于等于1小時(shí),小于24小時(shí))
3天前 (t 距離當(dāng)前時(shí)間大于等于24小時(shí),小于30天)
2個(gè)月前 (t 距離當(dāng)前時(shí)間大于等于30天小于12個(gè)月)
8年前 (t 距離當(dāng)前時(shí)間大于等于12個(gè)月)

function friendlyDate(time){
  var curDate = new Date()
  // 當(dāng)前時(shí)間的毫秒級(jí),這里的curDate是使用Date構(gòu)造函數(shù)創(chuàng)建的實(shí)例,不需要 Date.parse(),在與毫秒?yún)⑴c計(jì)算的時(shí)候,也會(huì)自動(dòng)轉(zhuǎn)化成毫秒級(jí),而下面的time,是外部手動(dòng)傳入的,如果是時(shí)間字符串,必須要解析成毫秒級(jí),才能參與毫秒計(jì)算
  var offset = curDate - time
  // 這里也可以把 time 改成  Date.parse(time) ,從而函數(shù)參數(shù)變?yōu)閭魅肴掌谧址?,這時(shí)候傳入'1994-05-01', 能計(jì)算出,我現(xiàn)在距離出生已經(jīng) 23年了
  var minutes = Math.floor(offset/1000/60) 
  var hours = Math.floor(minutes/60)
  var days = Math.floor(hours/24)
  var months = Math.floor(days/30)
  var years = Math.floor(months/12)  
  // 1年11個(gè)月29天23小時(shí)59分 ,這也是1年前, 而不是2年前,  邏輯判斷上和1年0個(gè)月0天0小時(shí)0分沒(méi)區(qū)別,所以之前各項(xiàng)取整的誤差累計(jì)不影響結(jié)果
  if(minutes < 1){
    return '剛剛'
  }else if( minutes >= 1 && minutes < 60 ){
    return minutes + '分鐘前'
  }else if( hours >= 1 && hours < 24 ){
    return hours + '小時(shí)前'
  }else if( days >= 1 && days < 30 ){
    return days + '天前'
  }else if( months >=1 && months < 12 ){
    return months + '個(gè)月前'
  }
  return years + '年前'
}
var str = friendlyDate(767750400000)
console.log(str) // 23年前

Date 中的坑

第一個(gè)坑

Date() 返回一個(gè)無(wú)用的字符串
"Fri Sep 01 2017 12:17:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"
new Date() 才是返回Date 對(duì)象
Fri Sep 01 2017 12:18:11 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)

第二個(gè)坑

d.getDate() 返回的是幾號(hào),而不是整個(gè)日期
d.getDay() 返回的是星期幾 0 ~ 6, 星期天是 0,而不是7

第三個(gè)坑

month 從 0 開(kāi)始

第四個(gè)坑

d.toLocaleString() 不可靠,當(dāng)?shù)貢r(shí)間不是JS能決定的,是依賴于本地操
作系統(tǒng)時(shí)間設(shè)置
new Date() 里面參數(shù)是不可靠的,是默認(rèn)當(dāng)?shù)貢r(shí)間
最好用時(shí)間戳或者UTC
一個(gè)時(shí)間距離1970-1-1 0點(diǎn)0分0秒的時(shí)間就是時(shí)間戳

Date.UTC(2000,0,1,0,0,0)
946684800000
new Date(Date.UTC(2000,0,1,0,0,0))
Sat Jan 01 2000 08:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)

寫(xiě)一個(gè)函數(shù),判斷某一年是不是閏年

能用API 為什么不直接調(diào)用時(shí)間函數(shù),2月如果有29天,那就是閏年,否則28天就是平年

// 年數(shù)能被400整除是閏年, 2月有29天也是閏年

function xxx(year){
  var d = new Date(year,1,29) // Date 如果發(fā)現(xiàn)當(dāng)天超出了,就順延到下一個(gè)月
  console.log(d.getDate())
  return d.getDate() === 29 // 直接 return  是否等于 29 的真假性
}
xxx(2016) // 29 true

同理, 想知道一個(gè)月有多少天,
把時(shí)間調(diào)到那個(gè)月的下個(gè)月第一天,然后往回?fù)芤幻?,獲取那時(shí)的日期就行了:

function 這個(gè)月多少天(year, month){
  var d = new Date(year, month , 1, 0, 0, 0 )  
  //  想知道某年2月份天數(shù),如果直接輸入2,那么js會(huì)認(rèn)為是3月份第一天
  var 前一天 = new Date(d - 1000)   // 因此,此處減去1s,就退回到2月份最后一天
  return 前一天.getDate()  // 接著獲取當(dāng)天的是幾號(hào)即可
}

作者:方應(yīng)杭
鏈接:https://www.zhihu.com/question/53364395/answer/134650535
來(lái)源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

結(jié)束語(yǔ)

實(shí)際項(xiàng)目中,關(guān)于Date,更多的是用 moment.js, 是一個(gè)時(shí)間方面非常好用的庫(kù),有很多更靠譜的API

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,679評(píng)論 0 4
  • Math 1、寫(xiě)一個(gè)函數(shù),返回從min到max之間的 隨機(jī)整數(shù),包括min不包括max 2、寫(xiě)一個(gè)函數(shù),返回從mi...
    Feiyu_有貓病閱讀 313評(píng)論 0 1
  • 1、寫(xiě)一個(gè)函數(shù),返回從min到max之間的 隨機(jī)整數(shù),包括min不包括max 2、寫(xiě)一個(gè)函數(shù),返回從min都max...
    饑人谷_一葉之秋閱讀 374評(píng)論 0 0
  • 二十歲學(xué)習(xí)盲文、適應(yīng)盲道、習(xí)慣聽(tīng)書(shū)不算晚,老易眼疾,多做準(zhǔn)備。 #汪汪,汪#
    仇志飛閱讀 237評(píng)論 0 0
  • 光陰畫(huà)了一個(gè)圈 街邊的小攤 圓盤飛快的旋轉(zhuǎn) 只是那個(gè)第一個(gè)給你買棉花糖的人 已不在人間
    伍丁零閱讀 299評(píng)論 0 0

友情鏈接更多精彩內(nèi)容