By Viral Shah | Nov 26, 2018
js一門很容易入門但是很難精通的語言埠戳。我很認同這句話。這是因為js是一門古老的語言同時也是一門很靈活的語言。有著一堆神秘的語法和過時的功能闰靴。我已經使用js很多年了,迄今為止关霸,我時不時地會發(fā)現(xiàn)一些我從未知道的隱藏語法或技巧传黄。
我試圖列出一些鮮為人知的js特性。雖然有一些特性在嚴格模式下是不能用的队寇,但是它依然是一種不錯的js特性。然而章姓,請注意佳遣,我不建議你全使用上我介紹的特性。雖然它們很酷凡伊,但畢竟是鮮為人知的特性零渐,你的同事可能會看不懂。
void 操作符
js有一元運算符系忙。你可能已經見過了诵盼,像 void(0) 或者 void0 。它只有一個目的 - 在右邊評估表達式并返回undefined银还。使用0只是一種慣例风宁。不一定要使用0.它可以是任何有效的表達式,如
void <expression>
它仍然返回undefined蛹疯。
為什么要這樣子返回undefined戒财,直接返回undefined不好么?看起來這個特性很多余捺弦,不是么?
有趣的事實
好吧,事實證明蝇更,在ES5之前遵蚜,你實際上可以在大多數(shù)瀏覽器中為undefined重新分配值。類似這樣
undefined =“abc”
使用void的話會始終保持返回正確的undefined寞钥。
構造函數(shù)的括號是可選的
對的慌申,你沒看錯,當調用構造函數(shù)的時候凑耻,我們在類名后面加的圓括號——完全是可選的太示!??(前提是你不需要傳遞參數(shù))
下面的代碼樣式都被認為是有效的JS語法柠贤,并且會給你完全相同的結果!
IIFE的括號可以被跳過
IIFE的語法讓我感覺總是有點奇怪类缤。
IIFE所有的括號都有什么用臼勉?
那些額外的括號只是為了告訴js解析器,即將到來的代碼是函數(shù)表達式而不是函數(shù)餐弱。知道了這些宴霸,來想一想,有很多方法可以跳過這些額外的括號膏蚓,仍然可以制作有效的IIFE瓢谢。
void操作符告訴解析器這段代碼是函數(shù)表達式。因此驮瞧,我們可以省略包著函數(shù)的括號氓扛。你猜怎么著?我們可以使用任何一元運算符(void论笔,+ ,!采郎, - 等),這仍然有效狂魔。
真酷蒜埋!
然而,如果你觀察再仔細點最楷,你會有個疑問整份,
一元運算符不會影響IIFE返回的結果嗎?
好吧籽孙,它會影響結果烈评。但是有個好消息,如果你關心返回的結果并且把結果放在某個變量中蚯撩,那么你首先不需要額外的括號础倍。
這就對了!
我們添加這些括號只是為了更好的代碼可讀性胎挎。
with 聲明
你知道js有with聲明塊沟启?with一直是js的關鍵詞。語法如下:
with (object)
statement
// for multiple statements add a block
with (object) {
statement
statement
...
}
with可以對傳遞過來的對象進行解析犹菇,在with 塊里可以直接使用對象的屬性德迹。
有趣的事實
with塊看起來很酷對不對?甚至比object destructuring還好揭芍。
但是胳搞,并不是這樣的。
通常不鼓勵使用with語句,因為它已被棄用肌毅。 在嚴格模式下完全禁止筷转。 事實證明,with塊會增加語言中的一些性能和安全性問題悬而。Bummer
構造函數(shù)
function語句并不是定義新函數(shù)的唯一方法呜舒;你可以使用【Function()】這個構造函數(shù)和new運算符動態(tài)定義函數(shù)。
構造函數(shù)的最后一個參數(shù)是字符串化代碼笨奠,就是你寫的函數(shù)袭蝗。其他參數(shù)是該函數(shù)的參數(shù)。
有趣的事實
在js般婆,F(xiàn)unction構造函數(shù)是所有構造函數(shù)的構造函數(shù)到腥。也包括Object的構造函數(shù)。并且Function構造函數(shù)的構造函數(shù)就是它自身蔚袍。因此乡范,調用object.constructor.constructor...足夠多次后,在js中页响,最終會在任何對象返回Function構造函數(shù)篓足。
Function 的屬性
我們知道在js中,F(xiàn)unctions是首個對象闰蚕。因此,沒有人能阻止我們在Function對象上添加自己的屬性连舍。這是可以的没陡,但是很少會這樣做。
那有什么場景會應用到呢索赏?
有一些很好的用例盼玄。例如,
讓Functions可配置化
我們有個greet函數(shù)潜腻。我們想要讓我們的函數(shù)在不同的環(huán)境下打印不同語言的問候語埃儿。這個環(huán)境是可以配置的。我們可以在某處維護個全局環(huán)境變量融涣,或者使用上文所說的添加自定義屬性
Function的靜態(tài)變量
另一個相似的例子童番。假設你想要實現(xiàn)一個生成一系列有序數(shù)字的數(shù)字生成器。通常來說威鹿,你會用Class或者IIFE剃斧,在里面維護一個計數(shù)變量,然后輸出有序的值忽你。這樣我們就可以限制對計數(shù)器的訪問幼东,并避免使用額外的變量來污染全局空間。
但是,如果我們希望靈活地讀取甚至修改計數(shù)器并且不污染全局空間呢根蟹?
好吧脓杉,我們仍然可以創(chuàng)建一個Class,帶有一個計數(shù)器變量和一些額外的方法來讀取它; 或者我們可以懶一點简逮,只需在函數(shù)上使用屬性球散。
現(xiàn)在是中場休息時間,我們等你回來买决。如果你想接著繼續(xù)沛婴,你是一個勇敢的戰(zhàn)士,我向你致敬督赤。
繼續(xù)吧
Arguments屬性
我相信大多數(shù)人都知道函數(shù)中的參數(shù)對象嘁灯。 它是一個像對象一樣的數(shù)組(譯者:emmm),在所有函數(shù)中都能訪問到躲舌。它具有在調用函數(shù)時傳遞的參數(shù)列表丑婿,也有其他一些有趣的屬性。
- arguments.callee:指向當前調用函數(shù)
- arguments.callee.caller:指向當前被調函數(shù)的調用者没卸。
注意:雖然ES5禁止在嚴格模式下使用callee和caller羹奉,但在許多編譯庫中仍然常見。 所以约计,值得學習它們诀拭。
標記模版字面量
除非你是井底之蛙,你一定聽說過模版字面量煤蚌。模版字面量時es6的一個很酷的補充耕挨。然而,你聽說過Tagged模版字面量么(Tagged Template Literals)尉桩?
Tagged模板字面量允許您通過向模板字面量添加自定義標記來更好地控制將模板字面量解析為字符串筒占。Tagged只是一個獲取字符串模板解析后的所有字符串和值的數(shù)組的解析器函數(shù)。Tagged函數(shù)最終返回字符串蜘犁。
在下面的示例中翰苫,我們的自定義標記 - highlight,解釋模板文字的值这橙,并使用
<mark>
元素將解釋的值包裝在結果字符串中奏窑,以突出顯示。
Getter & Setter
在大多數(shù)情況下析恋,js對象時很簡單的良哲。比如說有一個對象叫user,我們嘗試使用user.age來讀取age屬性時助隧,如果有定義并賦值了筑凫,就有返回滑沧。如果沒有,就返回undefined巍实。簡單滓技。
但是,它不一定非常簡單棚潦。 JavaScript對象具有Getters和Setter的概念令漂。 我們可以編寫自定義的Getter函數(shù)來返回我們想要的任何內容,而不是直接返回對象上的值丸边。 設置值也是一樣的叠必。
這使我們可以在獲取或設置屬性時可以靈活的創(chuàng)造虛擬屬性、驗證屬性妹窖。
Getters和Setters不是es5的特性纬朝,它們是一直都存在的特性。es5只是添加了語法糖骄呼。
逗號操作符
JavaScript有一個逗號運算符共苛。 它允許我們在一行中編寫由逗號分隔的多個表達式,并返回最后一個表達式的結果
// syntax
let result = expression1, expression2,... expressionN
來看看上面的例子蜓萄,這里將會解析所有的表達式隅茎,并把result變量賦予expressionN返回的值。
你可能在循環(huán)里面使用過了
for (var a = 0, b = 10; a <= 10; a++, b--)
它可以幫助我們把語句寫在一行
function getNextValue() {
return counter++, console.log(counter), counter
}
或者寫lamda表達式
const getSquare = x => (console.log (x), x * x)
+ 加操作符
想要知道如何便捷地把字符串轉換成number嫉沽?
只要在字符串前面加個+號辟犀。
Plus運算符也適用于負,八進制绸硕,十六進制踪蹬,指數(shù)值。 更重要的是臣咖,它甚至可以將Date或Moment.js對象轉換為時間戳!
!! Bang Bang 操作符
好的漱牵,嚴格來講夺蛇,它不是一個單獨的JavaScript運算符。 它只是兩次使用的JavaScript否定運算符酣胀。
但是Bang Bang聽起來很酷刁赦!Bang Bang是一個可以講任何表達式轉換成布爾值的方法。
如果表達式是一個true闻镶,則返回true甚脉;否則返回false。
~ 位運算作符
來看一個沒人關注的位運算操作符铆农。我們什么時候用它呢牺氨?
好吧,有個日常用例。
當與數(shù)字一起使用時猴凹,Tilde運算符有效夷狰,像這樣
~N => -(N + 1)。
僅當N == -1時郊霎,此表達式的計算結果為“0”
我們可以通過在indexOf(...)函數(shù)前面放置?來進行布爾檢查是否有一項存在沼头。String或Array中都可以用這個。
注意:ES6和ES7分別在String&Array中添加了一個新的.includes()方法书劝。當然进倍,它比位運算運算符更清晰,以檢查項目是否存在于Array或String中购对。
標簽語句
js具有標簽語句的概念猾昆。它允許我們在js中命名循環(huán)和塊。然后洞斯,我們可以使用這些標簽在使用break或continue時使用毡庆。
帶標簽的語句在嵌套循環(huán)中特別方便。但是我們也可以使用它們來簡單地將代碼組織成塊或創(chuàng)建一個可退出的塊
注意:不像其他的語言烙如,js沒有goto語句么抗。因此,我們只能使用labels來搭配break和continue使用亚铁。