首頁 web前端 js教程 談談Javascript中的void操作符

談談Javascript中的void操作符

Dec 13, 2016 pm 01:24 PM

由於JS表達式偏囉嗦,於是最近便開始採用Coffeescript來減輕負擔。舉個栗子,當我想取屋裡的第一條dog時,首先要判斷house物件是否存在,然後再判斷house.dogs是否存在,最後取house.dogs[0]。在JS需要這麼寫

var dog = (typeof house !== 'undefined && house !== null) && house.dogs && house.dogs[0]
登入後複製

在Coffee中,我只需要這麼寫:

dog = house?.dogs?[0];
登入後複製

寫到這裡,讀者會問,這跟標題《Javascript中的void》有一毛錢關係? Coffee的本質就是JS,之所以Coffee能運作的很好,是因為它產生出了高效而且健壯的JS程式碼,我們可以看看它的產生結果。

var dog, _ref;
dog = typeof house !== "undefined" && house !== null ? (_ref = house.dogs) != null ? _ref[0] : void 0 : void 0;
登入後複製

短短一行Coffee程式碼產生瞭如此長的JS程式碼,看上去似乎比我最前面自己用JS寫的更靠譜更安全,末尾還出來了兩個void 0,這究竟是何方神聖?

結構化一下上面的範例:

dog = (typeof house !== "undefined" && house !== null) ? 
        ((_ref = house.dogs) != null ? _ref[0] : void 0 ) 
        : void 0;
登入後複製

如果house未定義或house為null時,返回void 0

如果house.dogs為null時,返回void 0

可void 0很容易測試:

typeof void 0 //得到"undefined"console.log(void 0) //输出undefined
登入後複製

似乎void 0就是undefined了,但這樣子路數太野,也不夠嚴謹,即無法回答:void 100, void hello(), void i++這無數可能組合的值是什麼?

我們來瞅瞅規範是怎麼說的吧。

規範是這麼說的

在ECMAScript 262規範,有如下描述:

The void Operator
The production UnaryExpression : void UnaryExpression is evaluated as follows:
Let expr be the result of evaluating UnaryExpression.
Call GetValue(expr).
Return undefined.
NOTE: GetValue must be called even though its value is not used because it may have observable side-effects.
登入後複製

搬譯一下:

void操作符
产生式 UnaryExpression : void UnaryExpression 按如下流程解释:
令 expr 为解释执行UnaryExpression的结果。
调用 GetValue(expr).
返回 undefined.
注意:GetValue一定要调用,即使它的值不会被用到,但是这个表达式可能会有副作用(side-effects)。
登入後複製

重點在於:無論void後的表達式是什麼,void操作符都會返回undefined. 因此由上面Coffee編譯出來的程式碼我們可以認為是這樣的:

dog = (typeof house !== "undefined" && house !== null) ? 
        ((_ref = house.dogs) != null ? _ref[0] : undefined ) 
        : undefined ;
登入後複製

問題來了,既然(void 0) === undefined,那直接寫undefined不就行了麼?

為什麼要用void?

因為undefined在javascript中不是保留字。換言之,你可以寫出:

function joke() {
    var undefined = "hello world";
    console.log(undefined); //会输出"hello world"
}
console.log(undefined); //输出undefined
登入後複製

對的,你可以在一個函數上下文內以undefined做為變數名,於是在這個上下文寫的程式碼便只能透過從全域作用域來取到undefined,如:

window.undefined //浏览器环境
GLOBAL.undefined //Node环境
登入後複製

但要注意的是,即便window, GLOBAL仍然可以在函數上下文被定義,故從window/GLOBAL上取undefined並不是100%可靠的做法。如:

function x() {
   var undefined = 'hello world',
       f = {},
       window = {
           'undefined': 'joke'
       };
   console.log(undefined);// hello world
   console.log(window.undefined); //joke
   console.log(f.a === undefined); //false
   console.log(f.a === void 0); //true
}
登入後複製

於是,採用void方式取得undefined便成了通用準則。如underscore.js裡的isUndefined便是這麼寫的:

_.isUndefined = function(obj) {
    return obj === void 0;
}
登入後複製

除了採用void能保證取到undefined值以外,還有其它方法嗎?有的,還有一種方式是透過函數呼叫。如AngularJS的源碼裡就用這樣的方式:

(function(window, document, undefined) {    //.....
})(window, document);
登入後複製

透過不傳參數,確保了undefined參數的值是一個undefined。

其它作用

除了取undefined外,void還有什麼其它用處嗎?

還有一個常見的功能,填充href。下面是一個微博截圖,它的轉發, 收藏, 討論都是超鏈接,但是用戶並不希望點擊它們會跳轉到另一個頁面,而是引發出一些交互操作。

談談Javascript中的void操作符

理論上而言,這三個超連結都是沒有URL的,但如果不寫的話,呵呵,點擊它會刷新整個頁面。於是便用上了href="javascript:void(0)的方式,確保點擊它會執行一個純粹無聊的void(0)。

另一種情況是,如果我們要產生一個空的src的image,最好的方式似乎也是src='javascript:void(0)'

寫在最後

回到void的定義,有一句話特別讓人迷惑:

注意:GetValue一定要調用,即使它的值不會被用到,但是這個表達式可能會有副作用(side-effects)。

这是什么意思?这表示无论void右边的表达式是什么,都要对其求值。这么说可能不太明白,在知乎上winter大神有过阐述关于js中void,既然返回永远是undefined,那么GetValue有啥用?,我且拾人牙慧,代入一个场景,看代码:

var happiness = 10;
var girl = {
    get whenMarry() {
        happiness--;
        return 1/0; //Infinity
    },
    get happiness() {
        return happiness;
    }
};

console.log(girl.whenMarry); //调用了whenMarry的get方法
console.log(girl.happiness); // 9

void girl.whenMarry; //调用了whenMarry的get方法
console.log(girl.happiness); // 8

delete girl.whenMarry; //没有调用whenMarry的get方法
console.log(girl.happiness); //还是8
登入後複製

上述代码定义了一个大龄文艺女青年,每被问到什么时候结婚呀(whenMarry),happiness都会减1。从执行情况可以看出,无论是普通访问girl.whenMarry,还是void girl.whenMarry都会使她的happiness--。而如果把void换成delete操作符写成delete girl.whenMarry,她的happiness就不会减了,因为delete操作符不会对girl.whenMarry求值。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1325
25
PHP教程
1272
29
C# 教程
1252
24
JavaScript引擎:比較實施 JavaScript引擎:比較實施 Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

從C/C到JavaScript:所有工作方式 從C/C到JavaScript:所有工作方式 Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript和Web:核心功能和用例 JavaScript和Web:核心功能和用例 Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

JavaScript在行動中:現實世界中的示例和項目 JavaScript在行動中:現實世界中的示例和項目 Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

了解JavaScript引擎:實施詳細信息 了解JavaScript引擎:實施詳細信息 Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:社區,圖書館和資源 Python vs. JavaScript:社區,圖書館和資源 Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

Python vs. JavaScript:開發環境和工具 Python vs. JavaScript:開發環境和工具 Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

See all articles