OMG,這些不爲人知的JavaScript 特性!

阿里雲最近在作活動,低至2折,有興趣能夠看看:
https://promotion.aliyun.com/...

爲了保證的可讀性,本文采用意譯而非直譯。javascript

javaScript 一般被認爲是最容易入門的語言,也是最難掌握的語言,我徹底贊成。這是由於 JavaScript 是一種很是古老且很是靈活的語言,它有着了神祕的語法和過期的特性。我已經使用 JavaScript 不少年了,直到如今,我偶爾會發現一些隱藏的語法或技巧,這些是我之前不知道的。雖然這些特性可能不太爲人所知,但它們仍然是衆所周知的。html

想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等着你!前端

圖片描述

注意:這裏沒有包括變量的提高、閉包、代理、原型繼承、異步等待、生成器等。

void操做符

JavaScript 有一個一元 void 操做符。你可能見過它被用做 void(0) 或 void 0。void的做用即是返回undefined,在它右邊的操做數會正常計算,可是不管結果是什麼,void都會返回undefined。使用「0」只是一種慣例。沒必要使用' 0 ',它能夠是任何有效的表達式,如void <表達式>,它仍然返回未定義的。java

圖片描述

// void operator
void 0                  // returns undefined
void (0)                // returns undefined
void 'abc'              // returns undefined
void {}                 // returns undefined
void (1 === 1)          // returns undefined
void (1 !== 1)          // returns undefined
void anyfunction()      // returns undefined
爲何要建立一個特殊的關鍵字來返回undefined而不是僅僅返回undefined? 聽起來有點多餘,不是嗎?
🚩 有趣的事實

實際上,在ES5以前,在大多數瀏覽器中,能夠爲原始的 undefined = "abc"分配一個新值。因此,在那些日子裏,使用void是一種確保始終返回 undefine 的原始值的方法。git

構造函數括號是可選的

是的,咱們在調用構造函數時在類名後添加的括號——徹底可選!😮(前提是不須要將任何參數傳遞給構造函數)github

下面的兩種代碼風格都被認爲是有效的 JS 語法並且結果都是同樣!express

圖片描述

// Constructor with brackets
const date = new Date()
const month = new Date().getMonth()
const myInstance = new MyClass()

// Constructor without brackets
const date = new Date
const month = (new Date).getMonth()
const myInstance = new MyClass

能夠省略 IIFE(當即執行函數)的括號

IIFE (當即調用的函數表達式)的語法對我來講老是有點奇怪,爲何要有那麼多的括號?segmentfault

實際上,這些額外的括號只是爲了告訴JavaScript解析器,即將解析的的代碼是一個函數表達式,而不是函數。知道了這一點,你能夠想象,有不少方法能夠省略那些額外的括號,仍然可使用 IIFE 有效的工做。數組

圖片描述

// IIFE

(function () {
  console.log('正常形式的 IIFE 調用')
})()

// 清爽的 IIEF 
void function() {
  console.log('酷酷的 IIFE 調用')
}()

void 操做符告訴解析器代碼是函數表達式。所以,咱們能夠跳過函數定義周圍的括號。你猜怎麼着? 咱們可使用任何一元運算符(void, +, !, -等等),這仍然有效!瀏覽器

這是否是比原始的寫法簡單並且 B 格多了呢?

可是,若是你是一個敏銳的觀察者,你可能會想,一元運算符不會影響 IIFE 返回的結果嗎?

它會影響結果。但好消息是,若是你只要的返回的結果並將其存儲在某個變量中,那麼就不須要額外的括號。

圖片描述

with 的聲明

JavaScript 有一個with語句塊, with 其實是JS中的關鍵字。 with 塊的語法以下:

圖片描述

with 語句能夠方便地用來引用某個特定對象中已有的屬性,可是不能用來給對象添加屬性。要給對象建立新的屬性,必須明確地引用該對象。

圖片描述

🚩 有趣的事實

with 塊看起來很酷,對吧? 它甚至比對象銷燬更好。好吧,其實不是。

一般不鼓勵使用 with 語句,由於它已被棄用,在嚴格模式下徹底禁止。事實證實,使用 with 塊會增長語言中的一些性能和安全性問題。

函數構造器

函數語句不是定義新函數的惟一方法,可使用function()構造函數和new 操做符動態定義函數。

圖片描述

🚩 有趣的事實

Function 構造函數是 JavaScript 中全部構造函數的母親。甚至 Object 的構造函數也是 Function 構造函數。而 Function 本身的構造函數也是 Function 自己。
所以,調用 object.constructor.constructor ...足夠屢次將最終在 JavaScript 中的任何對象上返回Function構造函數。

函數屬性

咱們都知道函數是JavaScript中的第一類對象。所以,沒有人阻止咱們向函數添加自定義屬性。在 JS 中這樣作是有效的,然而,它不多被使用。

那麼咱們何時要這樣作?

這裏有一些很好的用例。例如,

可配置函數

假設咱們有一個函數叫作 greet。咱們但願函數根據不一樣的地區打印不一樣的問候消息,這個區域設置也應該是可配置的。咱們能夠在某個地方維護全局 locale 變量,也可使用以下所示的函數屬性實現該函數

圖片描述

function greet () {
  if (greet.locale === 'ch') {
    console.log('中國,你好')
  } else if (greet.locale === 'jp') {
    console.log('扣你機哇!')
  } else {
    console.log('Hello World')
  }
}

greet() // Hello World
greet.locale = 'ch';
greet() // 中國,你好

具備靜態變量的函數

另外一個相似的例子。比方說,但願實現一個生成有序數字序列的數字生成器。一般您將使用帶有靜態計數器變量的 Class 或 IIFE 來跟蹤最後一個值。這樣咱們就限制了對計數器的訪問,同時也避免了使用額外的變量污染全局空間。

可是,若是咱們但願可以靈活地讀取甚至修改計數器,而又不污染全局空間,該怎麼辦呢?

咱們仍然能夠建立一個類,有一個計數器變量和一些額外的方法來讀取它;或者咱們能夠偷懶,使用函數自定義的屬性。

圖片描述

Arguments 的屬性

我相信大家大多數人都知道函數中的arguments對象。它是一個相似數組的對象,能夠在全部函數中使用。它具備在調用函數時傳遞給函數的參數列表。但它也有一些其餘有趣的性質:

  • arguments.callee: 當前調用的函數
  • arguments.callee.caller:調用當前函數的函數

圖片描述

注意:雖然ES5禁止在嚴格模式下使用callee & caller,但在許多編譯後的庫中仍然很常見。因此,學習它們是值得的。

標記模板字符串

模板字符串文字是ES6中許多很酷的附加內容之一,可是,知道標記模板字符串是比較少的?

圖片描述

標記模板字符串容許你經過向模板字符串添加自定義標記來更好地將模板文字解析爲字符串。Tag只是一個解析器函數,它獲取字符串模板解釋的全部字符串和值的數組,標記函數應返回最終字符串。

在下面的例子中,咱們的自定義標記 —— 高亮顯示,解釋模板文本的值,並將解釋後的值包裝在結果字符串中,使用<mark>元素進行高亮顯示。

圖片描述

Getters & Setters

在大多數狀況下,JavaScript對象是簡單的。假設咱們有一個 user 對象,咱們試圖使用user訪問它的age屬性。使用 user.age 獲得年齡屬性的值,若是沒有定義,咱們獲得未定義的值。

可是,並不必定要這麼簡單。JavaScript 對象具備 getter 和 setter 的概念。咱們能夠編寫自定義Getter函數來返回咱們想要的任何東西,而不是直接返回對象上的值,設置一個值也是同樣。

這使咱們能夠在獲取或設置字段時擁有強大的能力,如 virtual fieldsfield validationsside-effects

圖片描述

逗號操做符

JavaScript有一個逗號操做符。它容許咱們在一行中用逗號分隔多個表達式,並返回上一個表達式的結果。

圖片描述

在這裏,全部表達式都將被求值,結果變量將被賦值給expressionN返回的值。

咱們常常在for循環中使用了逗號操做符

for (var a = 0, b = 10; a <= 10; a++, b--)

有時在一行中編寫多個語句

function getNextValue() {
    return counter++, console.log(counter), counter
}

或者

const getSquare = x => (console.log (x), x * x)

+ 加號操做符號

想要快速地將字符串轉換爲數字嗎?

只需在字符串前面加上+運算符。加號運算符也適用於負數、八進制、十六進制、指數值。更重要的是,它甚至能夠轉換 Date 或者 Moment.js對象的時間戳!

圖片描述

!! 操做符

從技術上講,它不是一個單獨的JavaScript操做符。它只是兩次使用的 JavaScript 反運算符。

若是表達式爲true值,則返回true;不然返回false。

圖片描述

~ 非操做符

讓咱們面對它——沒有人關心位操做符。咱們何時才能使用它!

這裏有一個平常用例是關於波浪號或位非運算符的。

事實證實,當與數字一塊兒使用時,非運算符是有效的 ~N => -(N+1)這個表達式只有在 N爲-1時才計算爲 「0」。

咱們能夠經過將~放在theindexOf(…)函數前面來利用這一點,若是項目存在於字符串或數組中,則執行布爾檢查。

圖片描述

注意:ES6和ES7分別在字符串和數組中添加了一個新的 .include()方法。固然,這是一種比波浪號操做符更清晰的方法來檢查一個項目是否存在於數組或字符串中。

標籤 的使用

break和continue語句均可以與lebel語句聯合使用,從而返回代碼中特定的位置。用於嵌套循環,減小循環次數。

圖片描述

原文:https://blog.usejournal.com/l...

你的點贊是我持續分享好東西的動力,歡迎點贊!

交流

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

https://github.com/qq44924588...

我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!

關注公衆號,後臺回覆福利,便可看到福利,你懂的。

clipboard.png

相關文章
相關標籤/搜索