本已經(jīng)過原作者 Viduni Wickramarachchi 授權(quán)翻譯。
你是否經(jīng)歷過JavaScript中的某些值比較沒有得到預(yù)期結(jié)果的情況?
看下面的情況:
即使[]==0結(jié)果為真,if[]條件也沒有根據(jù)結(jié)果執(zhí)行。有沒有想過為什么會這樣?
本文主要說明這些值比較的工作原理以及影響它們的因素。在深入解釋之前,大家要熟悉一個概念:類型轉(zhuǎn)換。
這也稱為類型強制。對于不熟悉此概念的人來說,它只是將值從一種數(shù)據(jù)類型自動轉(zhuǎn)換為另一種數(shù)據(jù)類型。
看個例子,大家會更清楚明白。
在此示例中,定義的兩個變量具有兩種類型;字符串和數(shù)字。但是,當(dāng)我們使用 ==(非嚴格比較)進行比較時,結(jié)果為true。原因是當(dāng)我們使用==比較這兩個時,JavaScript 會自動嘗試將String類型轉(zhuǎn)換為Number類型以產(chǎn)生結(jié)果。這是一種強制轉(zhuǎn)換。
JavaScript中有多種強制類型。
在上述情況下,類型轉(zhuǎn)換沒有害處。但是,在許多情況下,類型強制會導(dǎo)致問題。
我們看下面例子。
在這里,JavaScript已將Number類型轉(zhuǎn)換為String。這與相等比較中發(fā)生的情況相反。我們預(yù)期的結(jié)果是450。但是,我們得到了String輸出。
現(xiàn)在,我們對類型轉(zhuǎn)換以及為什么要避免使用類型轉(zhuǎn)換有了清晰的了解,讓我們看看如何避免類型轉(zhuǎn)換。這是本文最重要的部分。因此,請坐下來,喝咖啡并集中精力
如果你需要對用戶輸入或任何其他值使用數(shù)學(xué)運算,則在執(zhí)行該運算之前,自己進行一次顯式轉(zhuǎn)換會更安全。這樣,可以避免任何意外行為。
如果需要連接兩個數(shù)字,則使用模板文字會更安全。特別是不確定值的類型。
也可以使用顯式轉(zhuǎn)換來導(dǎo)出相同的結(jié)果。
前面我們看到,當(dāng)使用==時,JavaScript 會執(zhí)行隱式類型轉(zhuǎn)換,這會導(dǎo)致不一致的結(jié)果。因此,在我們的生產(chǎn)代碼中使用它是不安全的。
為了得出預(yù)期的結(jié)果,應(yīng)該始終使用===進行比較。三等號隱含地表示:
我可以同時了解變量的值和類型
因此,如果將數(shù)字和字符串與值進行比較,結(jié)果將是false,因為它也會考慮變量的類型。
這是獲得預(yù)期一致結(jié)果的更安全的方法。
在JavaScript中,數(shù)據(jù)類型有兩種變體。
到目前為止,我們已經(jīng)討論了原始數(shù)據(jù)類型的類型轉(zhuǎn)換。我提供的第一個示例涉及非原始數(shù)據(jù)類型,例如數(shù)組。
所有非原始數(shù)據(jù)類型都有一個名為.toPrimitive()的內(nèi)置函數(shù)。比較非原始值和原始值時,此函數(shù)會自動將非原始類型轉(zhuǎn)換為原始類型。在我們看過的第一個示例中,當(dāng)使用此函數(shù)進行非嚴格比較時,空數(shù)組將轉(zhuǎn)換為空字符串。確切地說,用于執(zhí)行此轉(zhuǎn)換的確切函數(shù)是toString()。因此,空數(shù)組(將轉(zhuǎn)換為空字符串)等于0。
正如我們前面所看到的,當(dāng)在if條件中檢查空數(shù)組時,將執(zhí)行條件中的行。但是,如果空數(shù)組隱式轉(zhuǎn)換為0怎么辦?
這是在單獨的JavaScript條件下進行的: 真值和虛值 。除了true以外,JavaScript 將大部分有值的視為真值,除了少數(shù)值。例如,0,-0,""被視為虛值。由于空數(shù)組不被認為是虛值,當(dāng)在條件中檢查它時,它將作為真值執(zhí)行。(這里不會發(fā)生類型轉(zhuǎn)換,空數(shù)組保留為數(shù)組,這是類型轉(zhuǎn)換不一致的另一個例子。)
JavaScript作為一種松散類型語言,執(zhí)行隱式類型轉(zhuǎn)換。這會導(dǎo)致不一致和意想不到的結(jié)果。因此,我們應(yīng)該在任何時候都避免這種類型轉(zhuǎn)換。如果不確定值的類型,可以使用typeof檢查。檢查類型可以讓我們更好地理解應(yīng)該如何進行轉(zhuǎn)換。
~完,我是刷碗智,我要去刷碗了,骨的白~
作者:Viduni Wickramarachchi 譯者:前端小智 來源:stackabuse
原文:https://blog.bitc.io/how-to-avoid-javascript-type-conversions-29e1258f37d8
tml+css基礎(chǔ)一:html簡介和發(fā)展史
HTML全稱(hypertext markup language)譯為超文本標記語言,其譯文代表了HTML的含義,它和其他編程語言不同的是,HTML不是一門真正意義上編程語言,而是一種標記語言,通過帶有尖角號的標簽對文本進行標記,從而實現(xiàn)網(wǎng)頁的結(jié)構(gòu)搭建。
1.2、HTML發(fā)展史
HTML創(chuàng)始人(蒂姆·伯納斯-李)蒂姆·伯納斯-李除了是HTML的創(chuàng)始人,還是w3c組織的主席。
1、HTML1.0 (1991年12月)
1991年萬維網(wǎng)(www)在互聯(lián)網(wǎng)上首次露面,也隨之引起了巨大的轟動。
1989年,伯納斯-李寫了一份備忘錄,提出建立一個基于互聯(lián)網(wǎng)的超文本系統(tǒng)。同年和另外一個工程師一起進行聯(lián)合資金申請,但是這個項目并沒有通過。
1991年底的時候,伯納斯-李公開了一份“HTML Tag”的文檔,里面描述了組成HTML初始版本的18個元素
2、HTML2.0(1995年11月)
HTML 2.0是HTML語言的擴展。????
與原始版本的HTML不同,HTML 2.0被創(chuàng)建為Web標準,規(guī)定了常見的網(wǎng)頁結(jié)構(gòu)
3、HTML3.2(1996年1月)
慘淡的"第一次瀏覽器大戰(zhàn)時期(Netspace Vs IE)",兩大巨頭不斷推出重大舉措試圖控制整個領(lǐng)域。???????
網(wǎng)頁開發(fā)者是這場戰(zhàn)爭中的焦點。商業(yè)戰(zhàn)爭就像軍備競賽,各家公司為了保持領(lǐng)先,招兵買馬。各家都有各家的規(guī)則。?????????
那時候,你不得不寫兩份不同的網(wǎng)頁,一個用于網(wǎng)景的瀏覽器,另一個用于微軟的瀏覽器
4、HTML4(1997年12月)
瀏覽器大戰(zhàn)接近尾聲,W3C(世界萬維網(wǎng)聯(lián)盟)成立,他們打算通過制定統(tǒng)一的HTML標準,使整個產(chǎn)業(yè)能有序的發(fā)展。 ? ? ? ? ? ?
他們計劃用兩種語言分離出HTML的表達式(HTML 4.0)和結(jié)構(gòu)(CSS),并且說服瀏覽器廠商接受這些標準
這次發(fā)布提供了規(guī)范的三種變體:
Strict,嚴格版本;
Transitional,過渡版本;
Frameset,iframe框架集;
HTML4.0 采納了許多瀏覽器特定的元素類型及屬性,但是同時也把 Netscape 的視覺化標記標記為過時的尋求淘汰; 贊成使用樣式表; 同時在1998年4月對HTML4.0進行了微小的修訂,沒有增加版本號HTML5.0
5、HTML4.01(1999年12月)
像 HTML4.0 一樣提供了三種變體,并且他的最終錯誤修訂版在2001年的5月12日發(fā)布
6、XHTML 1.0(2000年1月)
各大瀏覽器廠商紛紛接受W3C標準的時候,新技術(shù)出現(xiàn)了。?????????????
HTML和另一種語言XML融合,XHTML(可拓展的超文本標記語言)就此誕生。???????????
它繼承了HTML的通用型和瀏覽器的兼容性,繼承了XML的嚴密性和可拓展性
7、HTML5(2014 年 10 月)
HTML5是HTML最新的修訂版本,由W3C制定,目標是取代1999年所制定的HTML 4.01和XHTML 1.0標準
我們現(xiàn)在使用的是html5版本,因為由于新興框架的出現(xiàn)和瀏覽器兼容性的提升,讓我們選擇了html5。
this字面意思是當(dāng)前,當(dāng)前執(zhí)行代碼的環(huán)境對象或者是上下文。代表著當(dāng)前方法執(zhí)行的環(huán)境上下文,那么何為環(huán)境上下文,通俗的說,誰調(diào)用了函數(shù),誰就是這個函數(shù)的環(huán)境上下文。
在js中,this只有兩種指向,一種是指向當(dāng)前的封閉作用域,或者是指向當(dāng)前作用域的外層,this的最頂層就是window對象。
關(guān)于this必須要了解的是嚴格模式,嚴格模式是js里面的一個子集,是具有限制性JavaScript變體,嚴格模式也是js的一種,但是加了一些限制。
比如:
進入"嚴格模式"的標志:"use strict";
// 為整個腳本開啟嚴格模式 "use strict"; var v = "Hi! I'm a strict mode script!"; ? // 為函數(shù)開啟嚴格模式 function strict() { 'use strict'; function nested() { return "And so am I!"; } return "Hi! I'm a strict mode function! " + nested(); }
在全局環(huán)境下,無論是否在嚴格模式下,在全局執(zhí)行環(huán)境下(任何函數(shù)體外部)this指向全局對象。也就是說在全局執(zhí)行環(huán)境,這個this永遠指向全局對象,這個全局對象在瀏覽器中就是window。
//瀏覽器環(huán)境 var name = 'Eric'; console.log(window.name === this.name); /* true */ console.log(window === this); /* true */
在函數(shù)體內(nèi)部,this的值取決于函數(shù)被調(diào)用的方式。函數(shù)被調(diào)用的方式有很多種:
簡單調(diào)用,也就是說沒有添加任何額外的操作,沒有添加一個this的綁定或者是改變。
簡單調(diào)用分為嚴格模式與非嚴格模式。
// 瀏覽器環(huán)境 function simple(){ return this; } console.log(simple() === window); // true
// 瀏覽器環(huán)境 function simple2(){ "use strict"; return this; } simple2() === undefined; // true window.simple2() === window; // true
this傳遞,在js中this綁定有兩種:
// 瀏覽器環(huán)境 var object = { name: 'Eric' }; var name = 'Iven'; function getName(arg) { return this.name; } ? getName(); /* Iven */ getName.call(object); /* Eric */ getName.apply(object); /* Eric */
name = 'Davy'; function bindThis(){ return this.name; } var getName1 = bindThis.bind({ name: "Eric" }); console.log(getName1()); /* Eric */ ? var getName2 = getName1.bind({ name: "Iven" }); console.log(getName2()); /* Eric */
箭頭函數(shù)在執(zhí)行的時候會形成一個封閉的作用域,this與封閉作用域的this保持一致,call/apply/bind都將會被忽略。
// 瀏覽器環(huán)境 var globalThis = this; var arrowsFunction = () => this; console.log(arrowsFunction() === globalObject); /* true */
作為對象的方法被調(diào)用(有一個靠近原則):在對象里面定義了一個函數(shù),然后通過對象去調(diào)用這個函數(shù)。
// 瀏覽器環(huán)境 var object = { name: 'Eric', ? getName: function() { return this.name; } }; console.log(object.getName()); /* Eric */ ? ? function getName2() { return this.name; } object.getName = getName2; console.log(object.getName()); /* Eric */ ? ? object.object = { getName: getName2, name: 'Iven' }; console.log(object.object.getName()); /* Iven */
setInterval()方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達式。
語法:setTimeout(code,millisec),參數(shù)code必需,要調(diào)用的函數(shù)后執(zhí)行的JavaScript代碼串;millisec必需,在執(zhí)行代碼前等待的毫秒數(shù)。
注意:setTimeout()只執(zhí)行code一次,如果需要多次調(diào)用,請使用setInterval()或者讓code自身再次調(diào)用setTimeout(),也就是利用遞歸。
setInterval()方法可按照指定的周期來調(diào)用函數(shù)或計算表達式。它會不停地調(diào)用函數(shù),指導(dǎo)clearInterval()被調(diào)用或者窗口被關(guān)閉。由setInterval()返回的ID值可以用作clearInterval()方法的參數(shù)。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。