JS 中常用的小技巧,助你更簡短的實現一些功能

原創禁止私自轉載前端

廣告

部門長期招收大量研發崗位【前端,後端,算法】,歡迎各位大神投遞,踊躍嘗試。git

座標: 頭條,大量招人,難度有下降,大多能拿到很不錯的漲幅,未上市,offer 給力!歡迎騷擾郵箱!github

戳我: 戳我: hooper.echo@gmail.com面試


How to do

快速獲取毫秒數

const now = +new Date();

平鋪多維數組

// 僅僅適用於二維數組。不過,經過遞歸,咱們能夠平鋪任意維度的嵌套數組。
const arr = [11, [22, 33], [44, 55], 66];
const flatArr = [].concat(...arr); //=> [11, 22, 33, 44, 55, 66]

// flat 法
[1,2, [1, [2, [3]]]].flat()
// (4) [1, 2, 1, Array(2)]

// 提供另外一種場景化很強的思路。

// 其實有更簡單的. 任意維度數組均可以搞定,
arr.join().split(',')

// 可是存在風險: 類型會變。咱們能夠提供 轉換回調。
// 平鋪數字數組 + 轉換回調
[1,2, [1, [2, 1+ 2 +1, Number(true)]]].join().split(',').map((index) => Number(index))  // (6) [1, 2, 1, 2, 4, 1]

// 對於通式
Arr.join().split(',').map(fn)

這個方法可能限制不少,好比數組元素類型不一致, 好比非基礎類型等算法

第一個問題: 咱們不妨想一想,一個數組中既有 number,又有 string 是合理麼?實際上這種數組在邏輯,潛在風險和處理上存在很是多的問題。大多數狀況下是一個很差的設計。
可是若是在 Typescript 中每每有比較好的場景。typescript

第二個問題:非基礎類型則很差處理, 其實像這種比較 Hacker 的方法, 每每不是用於處理廣泛狀況的,每每是在特殊場景發揮奇效的。沒有最好的方案,只有最合適的方案。segmentfault

僅僅是另外一種思路。後端

快速取整

// api
Math.floor(10.8222)
// 雙位移
console.log(~~47.11) // -> 47
console.log(~~-12.88) // -> -12
console.log(~~1.9999) // -> 1
console.log(~~3) // -> 3
//失敗的狀況
console.log(~~[]) // -> 0
console.log(~~NaN) // -> 0
console.log(~~null) // -> 0
//大於32位整數則失敗
console.log(~~(2147483647 + 1) === (2147483647 + 1)) // -> 0

格式化輸出

const obj = {
    foo: { bar: [11, 22, 33, 44], baz: { bing: true, boom: 'Hello' } }
};
// The third parameter is the number of spaces used to
// beautify the JSON output.
JSON.stringify(obj, null, 4);
// "{
//     "foo": {
//         "bar": [
//             11,
//             22,
//             33,
//             44
//         ],
//         "baz": {
//             "bing": true,
//             "boom": "Hello"
//         }
//     }
// }"

大體測試一個JavaScript代碼塊性能的技巧

console.time("Array initialize");
const arr = new Array(100);
const len = arr.length;
for (let i = 0; i < len; i++) {
    arr[i] = new Object();
};
console.timeEnd("Array initialize");

您能夠建立一個 100% 純對象,它不會從 Object 繼承任何屬性或方法(例如,constructor,toString() 等)

const pureObject = Object.create(null);
console.log(pureObject); //=> {}
console.log(pureObject.constructor); //=> undefined
console.log(pureObject.toString); //=> undefined
console.log(pureObject.hasOwnProperty); //=> undefined

普通必傳參數校驗

const require = function( message ){
    throw new Error( message );
}
const getSum = (a = _err('a is not defined'), b = _err('b is not defined')) => a + b
getSum( 10 ) // throws Error, b is not defined
getSum( undefined, 10 ) // throws Error, a is not defined

裝飾器用做必傳參數校驗

以下爲主要代碼, 完整代碼須要 Typescript 環境。api

@validate
greet(p1, p2, p3, @required name: string, p5) {
    // p1-5 僅僅用於佔位, 用來測試 required 的第四個參數。
    return "Hello " + name + ", " + this.greeting;
}

// output
// throw (constructors.name + "." + String(method_1) + "[\u5B9E\u9645\u4E0A\u662F\uFF1A" + constructors.name + ".prototype." + String(method_1) + "]\u7B2C " +(index + 1) + " \u4E2A\u53C2\u6570\u662F\u5FC5\u4F20\u53C2\u6570\uFF0C\u8BF7\u63D0\u4F9B\u3002");
                        ^
// Greeter.greet[ Greeter.prototype.greet ] 第 4 個參數是必傳參數,請提供。

解構 arguments 轉數組

+function fn() {
    console.log([...arguments]);            // (4) [1, 2, 3, 4]
    console.log(Array.prototype.slice.call(arguments));
}(1,2,3,4)

庫的非 new 調用

一般庫遇到的問題每每是,用戶不按照你想要的方式調用,特別是 new 的問題,不少代碼中會存在一謝邏輯去校驗用戶是不是 new 調用。諸如:數組

  • 傳統式
var _ = function(obj) {
    if (obj instanceof _)
        return obj;
    if (!(this instanceof _))
        return new _(obj);
    this._wrapped = obj;
};
  • class 式
class Fn{}

// TypeError: Class constructor Fn cannot be invoked without 'new'
Fn();
function Foo() {
    if (!new.target) throw "Foo() must be called with new";
    console.log("Foo instantiated with new");
}

new Foo(); // logs "Foo instantiated with new"
Foo(); // throws "Foo() must be called with new"


// new.target 在構造中
class A {
    constructor() {
        console.log(new.target.name);
    }
}

new A();        // A

小數取整 && 強轉 boolean

~~2.8   // 2
!! 0    // false
鋪墊知識 [建議細看]

首先要明確的一點是,計算機內部在作數學運算時(也就是計算機的0和1的運算),都是以補碼爲標準的,說白了 計算機中就一種碼那就是補碼,而現實社會中的編碼規則,例如原碼、反碼都是咱們自定義的,爲了和計算機中的補碼造成轉換關係。因此說在咱們手工計算這類由計算機計算的01運算,要站在計算機的角度。所以首先就要將咱們的原碼反碼什麼的全都先轉爲補碼,再來計算^_^。這樣才能使得正數和負數的表示統一塊兒來,具體能夠參閱【補碼的歷史】,這裏不過多展開了。
接着來看那個問題,從問題入手,解決了實際問題,概念也就天然瞭然於心了。^_^

5 的補碼是它自己(ps:正數的原、反、補碼都是它自己;負數的原碼最高爲爲1開頭,反碼是最高符號位不變,其他位在原碼的基礎上取反,補碼是在反碼的基礎上+1便可獲得)
5的補碼:00000101

~5 (也就是5按位取反運算,下面涉及的是補碼運算):
00000101按位取反,這裏須要將原始01串徹底反轉過來,不存在最高符號位的概念,取反結果爲: 11111010

注意這裏的結果是用補碼錶示的,畢竟這仍是機器表示形式,轉化爲天然語言的編碼,把結果(補碼)轉化爲原碼就是:

  • 補碼-1轉爲反碼: 11111010 - 1 = 11111001
  • 反碼再取反轉爲原碼:11111001 = 10000110
  • 原碼轉爲十進制,答案就是-6

看看 [ ~ -6 = 5 ] 的計算過程, 假設有符號六位

  • ~(100110 > 111001 > 111010)(-6 的原碼轉補碼才能參與運算)
  • 000101 (運算結果是補碼)
  • 000101 > 000101 -> 5(轉換爲原碼[正數原碼是自身])
按位取反的快捷運算公式 -(x+1). 【~~x -> -( -(x + 1) + 1) -> -( -x - 1 + 1) -> --x -> x】

ps: 如下內容屬於廣告,選看

一二線大廠,可內推,急招人(50% 漲幅輕輕鬆鬆, 面試較難),研發最好,有興趣: hooper.echo@gmail.com 郵件私聊。

相關文章
相關標籤/搜索