js 拾遺

最近複習 JavaScript 教程,發現好多沒記住的,特以此記~

Date

Dtae() 和 new Date() 區別,Date() 函數不能帶參數,屬於靜態方法

new Date()*1 === new Date().getTime() === Date.now() // 獲取時間戳
new Date(y, m, 0).getDate() // 獲取這個月有多少天,傳入年份和月份
new Date(y, m, 0).getDay() // 獲取這個月最後一天是星期幾
new Date(y, m-1, 1).getDay() // 獲取這個月第一天是星期幾

RegExp

. 點字符匹配除回車(r)、換行(n) 、行分隔符(u2028)和段分隔符(u2029)以外的所有字符

[^] 表示匹配一切字符,其中包括換行符

str.replace(/2/gi, '1') 第二個參數可以使用美元符號$,用來指代所替換的內容

$&:匹配子字符串
$`:匹配結果前面的文本
$':匹配結果後面的文本
$n:匹配成功的第n組內容,n是從1開始的自然數。
$$:指代美元符號$。
'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1')
// "world hello"
'abc'.replace('b', '[$`-$&-$\']')
// "a[a-b-c]c"

JSON.stringify

console.log(JSON.stringify(obj, null, 2)) 接受三個參數,打印對象格式化

  • 參數一
    如果對象的屬性是undefined、函數或 XML 對象,該屬性會被JSON.stringify過濾
    如果數組的成員是undefined、函數或 XML 對象,則這些值被轉成null
    正則對象會被轉成空對象
    忽略對象的不可遍歷的屬性
  • 參數二
    接受一個數組,作爲第二個參數,指定需要轉成字符串的屬性,只對對象的屬性有效
    還可以是一個函數,用來更改JSON.stringify的返回值
  • 參數三
    如果是數字,表示每個屬性前面添加的空格(最多不超過10個)
    如果是字符串(不超過10個字符),則該字符串會添加在每行前面
    JSON.stringify發現參數對象有toJSON方法,就直接使用這個方法的返回值作爲參數,而忽略原對象的其他參數

Error

new Error() // 拋出一個錯誤
new SyntaxError() // 語法解析錯誤
new ReferenceError() // 非法或不能識別的引用值,使用未聲明的變量
new TypeError() // 操作類型錯誤,使用自身沒有的方法,let a = 22 a.sort() a 是 Number 類型而非數組
new RangeError() // 數值越界,Maximum call stack,調用一個不終止的遞歸函數,計算的值超出最大範圍
new URIError() // encodeURIComponent() encodeURI() 等URI函數使用錯誤

Array

'a' in ['a', 1] 
for in for of 
arr.push(1, 2, 3)
[1, 2, 3, 4, 5].splice(2) 分離成兩個數組 [1, 2] [3, 4, 5] 

es6 明確把空位轉成 undefined
es5 有的跳過(forEach、filter、reduce、some、every)
map() 會跳過空位,但會保留這個值
join()toString() 會將空位視爲 undefined ,而 undefinednull 會被處理成空字符串

Number

function rand(num) { 
    let seed = Date() * 1;
    seed = (seed * 9301 + 49297) % 233280; // 爲何使用這三個數?
    let rc = seed / (233280.0);
    return Math.ceil(rc * num);
}
rand(10) // 取1~10的隨機數

0 / 0 NaN 
0 / 1 0 
1 / 0 Infinity

es6 分別用前綴 0b 0o 0x 表示 2 8 16 進制

base64 
    0~9 a~z A~Z '+' '/'    10 + 26 + 26 + 2 = 64
    不足補\x00(零值字節),然後在末尾加上1個或2個=號,表示補了多少個零值字節

Number.MAX_SAFE_INTEGER 9007199254740991 表示能夠精確表示的最大整數
Number.MIN_SAFE_INTEGER -9007199254740991 表示能夠精確表示的最小整數

Math

ES6 在 Math 對象上新增了 17 個與數學相關的方法。所有這些方法都是靜態方法,只能在 Math 對象上調用

Math.trunc() // 去除一個數的小數部分,返回整數部分
Math.trunc(4.1) // 4
Math.trunc(-4.1) // -4
Math.hypot(3, 4) // 5 返回所有參數的平方和的平方根
Math.cbrt(8) // 2 計算一個數的立方根

es6 新增指數運算符 2 ** 2 ** 2 => Math.pow(2, 4)
這個運算符的一個特點是右結合,而不是常見的左結合。多個指數運算符連用時,是從最右邊開始計算的。

'hello'[1] // "e" 直接對字符串使用方括號運算符,僅能獲取操作

String

substring 類似slice,但是使用規則違反直覺,因此不建議使用substring方法,應該優先使用slice

str.charAt() // 下標
str.charCodeAt() // 十進制 Unicode 碼點
String.fromCharCode(97) // 逆操作
str.substr(0, 4) // 從零開始取4個
str[0]
str.concat(str2)
str1.localeCompare(str2) // Unicode 碼點比較大小

事件循環

參考文章

宏任務                   瀏覽器 Node
I/O                     ✅   ✅
setTimeout              ✅   ✅
setInterval             ✅   ✅
setImmediate            ❌   ✅
requestAnimationFrame   ✅   ❌

微任務                   瀏覽器 Node
process.nextTick        ❌   ✅
MutationObserver        ✅   ❌
Promise.then            ✅   ✅

斐波那契數列

// 性能最好
function add(n) { 
    let res1 = 1;
    let res2 = 1;
    let sum = res2 
    for (let i = 2; i < n; i++) {
        sum = res1 + res2
        res1 = res2 
        res2 = sum 
    }
    return sum
}

// 把算過的存起來
var cache = []
function add(n) { 
    if (n <= 2) {
        cache[n] = 1
        return 1
    }
    if (cache[n] !== undefined) {
        return cache[n]
    }
    cache.push(add(n-1) + add(n-2))
    return cache[n]
}

// 最簡單,但是性能不行
function add() {
    if (n <= 2) {
        return 1
    }
    return add(n-1) + add(n-2)
}

嚴格模式

1. 變量必須顯示聲明
2. 禁用 with
3. 進制刪除變量 // delete x => 語法錯誤 
4. 禁用 fn.caller fn.arguments // 報錯 
5. 對象不能有重名的屬性
6. 函數不能有重名的參數
7. 進制八進制表示法 02 

Flex

flex-grow flex-shrink flex-basis 放大 縮小佔據的空間大小

flex: 0 1 auto; // 默認 
flex: 0 0 auto; // flex: none;
flex: 1 1 auto; // flex: auto;
flex: 1 1 0%; // flex: 1;

Babel

AST 抽象語法樹

babel-core 
    通過 babylon 把 es6 解析成 AST
    babel-traverse 對 ATS樹進行遍歷轉譯得到新的 AST樹 
    babel-generator 讀取 AST樹並將其轉換爲代碼和源碼映射

對於新的 API、新的屬性,兩種處理方式
    babel-polyfill 把 es6環境整體引入到代碼中
        regenerator-runtime、core-js 

    babel-plugin-transform-runtime 按需引入
        babel-runtime 
            regenerator-runtime、core-js 
        babel-helpers 只引入單個,通過此插件可以把多次引入變成一個,減少代碼體積

Webpack

把項目看成一個整體,通過給定的主文件,webpack 從這個主文件的入口開始找到項目中的所有依賴文件,然後使用
各種 loader 轉化、插件處理、文件處理,最後打包輸出到一個指定的文件夾中

webpack 打包優化措施

webpack.DllPlugin 拆分固定死的依賴文件,因爲不會變化所以可以預先打包好,後面直接引用
HappyPack 多進程,默認開啓三個
babel-loader 開啓緩存 cacheDirectory: true 
exclude include 
noParse: /^(vue|vue-router|vuex|vuex-router-sync|axios)$/
css 用 contenthash
    hash 每次構建都會變
    chunkhash .vue 文件變了就會變
    contenthash 只有 css 變了纔會變

快速排序、冒泡排序

function fast(arr) { // 快速排序
    if (arr.length <= 1) { // 終止遞歸條件
        return arr
    }
    
    let index = Math.floor(arr.length / 2) // 獲取中間值下標
    let val = arr.splice(index, 1)[0] // 刪除且獲取返回值
    let left = []
    let right = []

    for (let i = 0, len = arr.length; i < len; i++) { // 數組長度已經發生變化
        if (arr[i] < val) {
            left.push(arr[i]) // 小的放左邊
        } else {
            right.push(arr[i]) // 大的放右邊
        }
    }

    return fast(left).concat([val], fast(right)) // 合併數組
}

function maop(arr) { // 冒泡排序
    for (let i = 0, len = arr.length; i < len - 1; i++) {
        let flag = 0 

        for (let j = 0; j < len - i - 1; j++) {
            if (arr[j] > arr[j+1]) {
                let temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp 
                flag = 1
            }
        }

        if (flag === 0) {
            return arr
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章