讓JS程式碼Level提升的忍者秘籍(實用)

  • 2021 年 3 月 15 日
  • 筆記

本文章共2377字,預計閱讀時間5-10分鐘。

前言

沒有前言。

你準備好成為同事眼中深藏不露、高深莫測、陽光帥氣的前端開發了嗎?

那就開始吧!

本文秉承宗旨:程式碼實用與逼格並存。

提升JS程式碼Level

位運算取整(OS:這比parseInt香)

原理:因為浮點數是不支援位運算的,所以會先把1.1轉成整數1再進行位運算,就好像是對浮點數向下求整。
注意:以下取整方法適用於32位有符號整數(有符號整數使用 31 位表示整數的數值,用第 32 位表示整數的符號,0 表示正數,1 表示負數。數值範圍從 -2147483648 到 2147483647)

| 0取整

| 0 可以將指定數值轉為32位有符號整數,也就是取整,正負數都可以,但是超過32位數部分會被忽略。

// 程式碼演示:
11.23 | 0 
-> 11

-11.23|0
-> 11

~~取整

~ 是按位取反運算,~~ 是取反兩次。

~~ 的作用是去掉小數部分,因為位運算的操作值要求是整數,其結果也是整數,所以經過位運算的都會自動變成整數。

// 程式碼演示:

~~11.23
-> 11

~~-11.23
-> -11

<< 0取整

<<兩個小於號表示左移運算。它把數字中的所有數位向左移動指定的數量,當設置為0時,可達到取整的效果。

// 程式碼演示:
11.23 <<0
-> 11

-11.23 <<0
-> -11

^0取整

異或運算符^,參加運算的兩個數據,按二進位位進行”異或”運算。

// 程式碼演示:
11.23^0
-> 11

-11.23^0
-> -11

自動執行匿名函數(OS:不走尋常路)

自動執行匿名函數:
解釋:即定義和調用合為一體的函數。我們創建了一個匿名的函數,並立即執行它,由於外部無法引用它內部的變數,因此在執行完後很快就會被釋放,關鍵是這種機制不會污染全局對象。
作用:創建一個命名空間只要把自己所有的程式碼都寫在這個特殊的函數包裝內,外部就不能訪問。

// 程式碼演示:
+function(){}();
-> NaN

-function(){}();
-> NaN

+(function(){})();
-> NaN

-(function(){})();
-> NaN

!function(){}();
-> true

~function(){}();
-> -1

void function(){}();
-> undefined

使用&& || 代替if-else(OS:一行能實現絕不寫第二行)

||和&&都遵循「短路」原理,如&&中第一個表達式為假就不會去處理第二個表達式,而||正好相反。

// 程式碼演示:
// -> 常規寫法
var a;
if(a === 1){
    a = 0;
}else if(a === 5){
    a = 5;
}else{
     a = 2;
}

// -> 花式寫法
// 當(a===1)該條件為真時,則執行a=0
// 當((a===1)&&(a=0,true))條件為真時,則不會繼續執行,反之執行((a===5)&&(a=5,true))條件...以此類推,即達到if-else同等作用
var a;
((a===1)&&(a=0,true))||((a===5)&&(a=5,true))||(a=2)

+ 的妙用(OS:++++)

將String類型轉化為Number類型

// 程式碼演示:
+'123';   // -> 123

日期輸出時間戳

// 程式碼演示:
+new Date();   // -> 1615372877042 

布爾類型轉換為整型

// 程式碼演示:
+true;        // -> 1
+false;       // -> 0
+ !!'wewe';   // -> 1

16進位轉換

// 程式碼演示:
+'0xFF';   // -> 255

十進位指數(OS:再也不用寫那麼多0)

當數字的尾部為很多的零時(如10000),咱們可以使用指數1e4來代替這個數字,例如:

// 程式碼演示:
// -> 常規寫法
for (let i = 0; i < 10000; i++) {}
// -> 可以簡寫成如下
for (let i = 0; i < 1e4; i++) {}


// 下面都是返回 true
1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;

if、for、while省略大括弧{}(OS:我簡寫我驕傲)

注意當省略大括弧時,if、for、while只作用於最近的語句,也就是說當只有一句程式碼執行時可以省略大括弧。

// 程式碼演示:
// if 簡寫
if(i > 520) console.log('日月既往,不可復追');

 // for簡寫
for(var i=0; i<520; i++) console.log('花看半開,酒飲微醺。');

// while簡寫
while (i > 520) console.log('花開如火,也如寂寞')

獲取數組最大值 or 最小值(OS:apply就是神奇)

當給Math.max()或Math.min()函數傳參時,若參數中有非數值的項,則會返回NaN;
所以如果是要用於求一個數組中的最大值時,可以用Math.max.apply(Math,array),把this值指向Math對象,則第二個參數可以傳入任意數組。

// 程式碼演示:
// 第一個參數(Math)其實無關緊要。在本例中未使用它;
// apply的一個巧妙的用處:可以將一個數組默認的轉換為一個參數列表;([param1,param2,param3] 轉換為 param1,param2,param3) 這個如果讓我們用程式來實現將數組的每一個項,來裝換為參數的列表;
// 因為Math.max 參數裡面不支援Math.max([param1,param2]) 也就是數組,但是它支援Math.max(param1,param2,param3…),所以可以根據剛才apply的那個特點來解決
Math.max.apply(Math, [1,2,3]); // 會返回 3
Math.max.apply(" ", [1,2,3]); // 也會返回 3
Math.max.apply(0, [1,2,3]); // 也會返回 3

// 同理apply亦可以應用於Math.min
Math.min.apply(Math, [1,2,3]); // 會返回 1
Math.min.apply(" ", [1,2,3]);  // 也會返回 1
Math.min.apply(0, [1,2,3]);    // 也會返回 1

區間內的隨機數(OS:就很棒)

啥也不說了,這兩個方法看起來就很有感覺,用不到也得放進去。

// 程式碼演示:
// 區間內的隨機數
function RandomNumber(min, max) {
  return (min||0) + Math.random() * ((max||1) - (min||0));
}

// 區間內的隨機整數
function getRandom(min,max){
    return Math.floor(Math.random() *( (max-min)+1) + min);
}

Obeject凍結(OS:忍界凍結大法)

同事修改我的程式碼怎麼辦???使用對象凍結大法Object.freeze() ;效果極佳,

Object.freeze() 方法可以凍結一個對象。一個被凍結的對象再也不能被修改;凍結了一個對象則不能向這個對象添加新的屬性,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結一個對象後該對象的原型也不能被修改。freeze() 返回和傳入的參數相同的對象。

// 程式碼演示:
'use strict'
const obj = {
  prop: 42
};

Object.freeze(obj);

obj.prop = 33;
// Throws an error in strict mode -> 報錯

console.log(obj.prop);
// 輸出: 42

忍界判斷對象是否凍結大法Object.isFrozen()方法判斷一個對象是否被凍結

Object封閉(OS:忍界封閉大法)

同事老師亂修改我插件的配置怎麼辦???

對象封閉大法好,標記為不可配置,無法添加新屬性。
可以使用Object.seal()方法封閉一個對象,阻止添加新屬性並將所有現有屬性標記為不可配置。當前屬性的值只要原來是可寫的就可以改變。

// 程式碼演示:
const object1 = {
  property1: 42
};

Object.seal(object1);
object1.property1 = 33;
console.log(object1.property1);
// 輸入: 33

delete object1.property1; // 密封后無法刪除
console.log(object1.property1);
// 輸入: 33

讓一個對象密封,並返回被密封后的對象。密封對象是指那些不能添加新的屬性,不能刪除已有屬性,以及不能修改已有屬性的可枚舉性、可配置性、可寫性,但可以修改已有屬性的值的對象。

忍界判斷是否封閉大法Object.isSealed(obj)表示給定對象是否被密封的一個Boolean

如果這個對象是密封的,則返回 true,否則返回 false。密封對象是指那些不可 擴展 的,且所有自身屬性都不可配置且因此不可刪除(但不一定是不可寫)的對象。

Object對象阻止擴展(OS:忍界禁擴大法)

同事老師亂在我的插件加配置怎麼辦???

對象無法擴展大法,Object.preventExtensions()阻止對象擴展,讓一個對象變的不可擴展,也就是永遠不能再添加新的屬性,可以刪除對象屬性

const object1 = {};

Object.preventExtensions(object1);

try {
  Object.defineProperty(object1, 'property1', {
    value: 42
  });
} catch (e) {
  console.log(e);
  // 輸出: TypeError: 不能定義屬性property1,對象是不可擴展的
}

Object.isExtensible()判斷一個對象是否可擴展,即是否可以給它添加新屬性

處理報錯(OS:這個處理報錯真好用)

聽說用了這個方法的程式設計師都升職加薪了!

try {
    ....
} catch (err) {
    window.location.href = `//www.baidu.com/s?ie=UTF-8&wd=${err}`
}

結尾

好了,以上就是本篇全部的內容。

有更強的寫法,可在下方留言,我們大家一起完善!

碼字不易。如果覺得本篇文章對你有幫助的話,希望能可以留言點贊支援,非常感謝~

感悟

準備發布這篇文章的時候,一位一起工作兩年的朋友提了離職…

 曉不得我能堅持多久,
 文章寫到這裡也挺有感觸的,
 前些天還在探討各種問題,
 程式設計師的未來在哪裡?前端技術應該才能得到公司的重視?
 似乎沒有得到答案,就要離開了,
 錦繡山河,一定會大有作為。

只要有樹葉飛舞的地方,火就會燃燒,火的影子照耀著村子,新的樹葉就會發芽