成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入理解 JavaScript 中的 With 語句

開發(fā) 前端
With 語句存在明顯的性能問題,這在幾乎所有參考書中都有提到,但很少有例子來說明這一點(diǎn)。你可以自己進(jìn)行代碼測(cè)試,以更直觀地量化理解 with 語句的性能。

通常來說,所有 JavaScript 開發(fā)人員都有一個(gè)共同的概念:“避免使用 with 語句。” 這條準(zhǔn)則無疑是正確的,但并不是每個(gè)人都能很好地解釋為什么。雖然只記住“不要使用它”的結(jié)果就足夠了,但理解其背后的原因?qū)τ谏钊肜斫?JavaScript 語言和編寫高質(zhì)量代碼非常有幫助。

with 語句

with 語句的初衷是為了避免冗長(zhǎng)的對(duì)象調(diào)用:

foo.bar.baz.x = 1;
foo.bar.baz.y = 2;
foo.bar.baz.z = 3;

with(foo.bar.baz) {
    x = 1;
    y = 2;
    z = 3;
}

但實(shí)際上,使用變量替換是相當(dāng)簡(jiǎn)單的:

var p = foo.bar.baz;
p.x = 1;
p.y = 2;
p.z = 3;

因此,看起來一開始就不需要 with。如今,使用 with 的人已經(jīng)很少了。在嚴(yán)格模式下,使用 with 會(huì)直接報(bào)錯(cuò):

function foo() {
    'use strict';
    with ({}) {}
}

因此,with 已經(jīng)被完全廢棄,人們甚至懶得去關(guān)注其原因。

書中的陳述

既然是總結(jié),我想盡可能全面,所以讓我們先從書籍開始。關(guān)于 JavaScript 的書籍,以下是一些主要參考:

《JavaScript 權(quán)威指南》(第 5 版,David Flanagan,P109):

with (Object) statement with 語句用于暫時(shí)修改作用域鏈… 這種語句實(shí)際上是將對(duì)象添加到作用域鏈的開頭,然后執(zhí)行語句,再將作用域鏈恢復(fù)到原來的狀態(tài)… 盡管有時(shí)使用 with 語句更方便,但人們反對(duì)使用它。使用 with 語句的 JavaScript 代碼難以優(yōu)化,因此其執(zhí)行速度比不使用 with 語句的等效代碼慢得多。此外,在 with 語句中定義函數(shù)和初始化變量可能會(huì)產(chǎn)生與直覺相悖的意外行為(這種行為及其原因非常復(fù)雜,我們?cè)诖瞬辉俳忉專?/p>

《JavaScript 高級(jí)程序設(shè)計(jì)》(第 3 版,Nicholas C. Zakas,P60):

with 語句的目的是將代碼的作用域設(shè)置為特定對(duì)象… 由于頻繁使用 with 語句導(dǎo)致的性能下降,以及調(diào)試代碼的困難,不建議在開發(fā)大型應(yīng)用程序時(shí)使用 with 語句。

《JavaScript 語言精粹》(Douglas Crockford,P110):

這個(gè)語言中存在 with 語句嚴(yán)重影響了 JavaScript 處理器的速度,因?yàn)樗茐牧俗兞棵脑~法作用域綁定。它的初衷是好的,但如果沒有它,JavaScript 語言會(huì)稍微好一些。

《深入理解 ECMAScript 6》(Axel Rauschmayer,P153):

這本書是我唯一一本用了一頁(yè)多的篇幅詳細(xì)解釋了 JavaScript 中廢棄 with 的原因的基礎(chǔ)參考書。

好了,讀了這么多書,讓我們現(xiàn)在進(jìn)入本文的主要話題:

為什么不使用 with 語句?

綜上所述,主要考慮如下:

性能問題

with 語句存在明顯的性能問題,這在幾乎所有參考書中都有提到,但很少有例子來說明這一點(diǎn)。你可以自己進(jìn)行代碼測(cè)試,以更直觀地量化理解 with 語句的性能。

var a = {a: {a: 1}};
function useWith() {
    with (a.a) {
        for (var i = 0; i < 1000000; i++) {
            a = i; 
        }
    }
}

var b = {b: {b: 1}};
function noWith() {
    for (var i = 0; i < 1000000; i++) {
        b.b.b = i; 
    }
}

var t1 = new Date().getTime();
useWith();
alert(new Date().getTime() - t1);

var t2 = new Date().getTime();
noWith();
alert(new Date().getTime() - t2);

在對(duì)象屬性賦值一百萬次時(shí),性能差異是否顯著?

當(dāng)然,在實(shí)際使用中,極少有執(zhí)行數(shù)百萬次的循環(huán),損失在可接受范圍內(nèi)。因此,性能損失并不是廢棄 with 語句的主要原因。

不可預(yù)測(cè)性

使用 with 語句導(dǎo)致的不可預(yù)測(cè)性是廢棄 with 的根本原因。with 強(qiáng)行截?cái)嘣~法作用域,臨時(shí)將對(duì)象插入作用域鏈。這導(dǎo)致代碼變得難以捉摸。

例如:

function foo(a) {
    with (a) {
        console.log(a);
    }
}

foo("sword");     // 輸出: sword
foo({});          // 輸出: [object Object]
foo({a: "sword"}); // 輸出: {a: "sword"}

在這個(gè)簡(jiǎn)單例子中,字符串 "sword" 和空對(duì)象沒有問題。然而,當(dāng)傳遞的參數(shù)是具有名為 a 的屬性的對(duì)象時(shí),強(qiáng)行發(fā)生 a.a 訪問。

這只是一個(gè)參數(shù)的情況。如果有很多參數(shù)呢?當(dāng)不知道傳入?yún)?shù)有什么屬性時(shí),可以想象在多個(gè)參數(shù)之間引用各種屬性會(huì)有多么混亂。這就是所謂的“令人驚訝和違反直覺”的行為本質(zhì)。

此外,在 with 語句中聲明的變量并不屬于 with 指定的對(duì)象:

var a = {};   
with (a) {
    x = 'sword';
    var y = 'wang';
}

console.log(a.x);        // undefined
console.log(a.y);        // undefined
console.log(window.x);   // sword
console.log(window.y);   // wang

在 with 中聲明的變量被添加到外部函數(shù)中。

function foo() {
    with ({}) { x = 'sword'; }
    console.log(x);
}
foo();  // 輸出: sword

這可能和你想象的有些不同。

單單通過標(biāo)識(shí)符及其上下文,是無法確定語句中的標(biāo)識(shí)符指向什么的。這才是 with 被棄用的真正原因。它強(qiáng)行混淆了上下文,使程序的預(yù)測(cè)和解析變得困難,導(dǎo)致了后面會(huì)討論的優(yōu)化問題。

代碼無法優(yōu)化

由于無法預(yù)測(cè),代碼的含義不斷變化。不同的調(diào)用,甚至相同的調(diào)用,由于運(yùn)行時(shí)的變化可能會(huì)偏離,使得代碼無法優(yōu)化。

優(yōu)化涉及兩個(gè)方面。一方面,解析和執(zhí)行變慢,這指的是前面提到的性能。另一方面,對(duì)于代碼優(yōu)化和壓縮工具,如果無法確定是否正在使用變量或?qū)傩裕瑒t無法重命名(因?yàn)閷傩詿o法重命名)。

總結(jié)

在這個(gè)炎熱的夏天,我可能被熱氣蒸得有些思維散亂。心血來潮,我翻出了幾本關(guān)于 JavaScript 的書,想要探討一下這個(gè)被廣泛詬病的 with 語句。說著說著,似乎偏離了主題,胡亂扯了一些看似深?yuàn)W但不太實(shí)用的內(nèi)容。寫完之后,我自己都覺得“哇,這人真閑”。

哦,對(duì)了,文章開頭還有一個(gè)冷笑話,說 JavaScript 比 Java 多 60%。我只是在調(diào)侃它們的字符數(shù)。“JavaScript” 比 Java 多五個(gè)字母;如果你堅(jiān)持?jǐn)?shù)字符,那么大概是多了 60%。好吧,可能這個(gè)笑話有點(diǎn)冷,難怪外面這么熱——看來我得冷靜一下。

寫這些東西可以算是一種消暑和消磨時(shí)間的方式。希望你讀到這里時(shí),也能在這個(gè)夏季找到屬于你的涼爽享受。至于 with 語句——了解它并擱置一旁,因?yàn)槲覀兎凑粫?huì)用了,不是嗎?

責(zé)任編輯:姜華 來源: 大遷世界
相關(guān)推薦

2020-12-16 09:47:01

JavaScript箭頭函數(shù)開發(fā)

2013-11-05 13:29:04

JavaScriptreplace

2021-02-17 11:25:33

前端JavaScriptthis

2015-11-04 09:57:18

JavaScript原型

2011-03-02 12:33:00

JavaScript

2019-11-05 10:03:08

callback回調(diào)函數(shù)javascript

2024-09-02 14:12:56

2017-03-28 21:39:41

ErrorsStack trace代碼

2020-07-24 10:00:00

JavaScript執(zhí)行上下文前端

2017-04-25 15:30:23

堆棧函數(shù)JavaScript

2018-07-09 15:11:14

Java逃逸JVM

2016-08-31 15:50:50

PythonThreadLocal變量

2010-06-28 10:12:01

PHP匿名函數(shù)

2023-10-08 08:53:36

數(shù)據(jù)庫(kù)MySQL算法

2014-06-23 10:42:56

iOS開發(fā)UIScrollVie

2010-06-01 15:25:27

JavaCLASSPATH

2020-07-21 08:26:08

SpringSecurity過濾器

2016-12-08 15:36:59

HashMap數(shù)據(jù)結(jié)構(gòu)hash函數(shù)

2013-06-20 10:25:56

2012-11-22 10:11:16

LispLisp教程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 色综合久 | 91久久| 91伊人网| 国产一区二区成人 | 欧美极品一区二区 | 成人免费xxxxx在线视频 | 青青草原综合久久大伊人精品 | 先锋av资源网 | 日韩久久久久久 | 黄色一级免费 | 国产精品国产精品国产专区不卡 | 日韩视频免费看 | 亚洲欧美激情精品一区二区 | 日韩一区精品 | 久久久久久免费免费 | 夏同学福利网 | 欧美精品一区二区三区在线 | 成人性生交大免费 | 日韩有码一区 | 中国大陆高清aⅴ毛片 | 欧美久久久久久久 | 欧美视频三级 | 91精品国产手机 | 青青草免费在线视频 | 国产女人叫床高潮大片免费 | 中文成人在线 | 亚洲成人二区 | 精品在线| 国产精品美女久久久免费 | 成人在线免费网站 | 亚洲成人www | 欧美在线一二三 | 国产欧美日韩一区二区三区在线 | 人人干人人干人人干 | 天堂一区二区三区四区 | 视频一区二区在线观看 | 欧美视频 亚洲视频 | 久久久久国产精品人 | 日本天堂视频在线观看 | 日韩在线观看 | 亚洲一区二区国产 |