摘要:的數(shù)字類型是基于標(biāo)準(zhǔn)實(shí)現(xiàn)的,該標(biāo)準(zhǔn)也被稱為浮點(diǎn)數(shù)使用的是雙精度即位進(jìn)制由于數(shù)字值可以使用對象進(jìn)行封裝,因此數(shù)字值可以調(diào)用中的方法。
數(shù)組
和其他語言不同,在JavaScript中,數(shù)組可以擁有不同值類型,可以使字符串,數(shù)字,對象,還可以是數(shù)組(多維數(shù)組就是這樣形成的).
聲明數(shù)組后,可以直接通過索引的方式進(jìn)行賦值:
var arr = []; arr.length; //0 arr [0] = 12; arr [1] = "ok"; arr.length //2
我們還可以使用delete運(yùn)算符將單元從數(shù)組中移除:
避免冗余代碼,繼上寫
délete arr [0] arr.length //2 這是為什么呢? arr[0] // undefined
我們來看一下使用delete運(yùn)算符刪除后的數(shù)組到底是什么樣子的呢?
愿數(shù)組為 arr = [1,3,4,5],我們delete arr [1]
我們發(fā)現(xiàn)使用delete刪除數(shù)組單元,length屬性并沒有改變,對應(yīng)的數(shù)組單元中,也確實(shí)刪除了,我們對出現(xiàn)這種情況的數(shù)組,稱之為稀疏數(shù)組.
在JavaScript類型介紹中,我們講過,數(shù)組屬于對象的子類型,那么我們可不可以通過對象查找屬性的方式去訪問數(shù)組呢?
var arr = []; arr["node"] = "ok"; arr["node"] // "ok"
我們可以通過對象的鍵值去方位和操作它(但這些并不計(jì)算在數(shù)組的長度內(nèi))!
代碼繼上??
arr.length // 0 arr //lenght:0 node:"ok";
這里有個(gè)問題需要特別注意,如果字符串鍵值能夠被強(qiáng)制類型轉(zhuǎn)換為十進(jìn)制數(shù)字的話,就會被完全當(dāng)作數(shù)字索引來處理。
var arr = []; arr["13"] = 42; arr.length //14
我們?yōu)閍rr[”13“]賦值,0-12單元默認(rèn)為空(undefined),這說明數(shù)組在使用字符串鍵值時(shí)會對它進(jìn)行強(qiáng)制類型轉(zhuǎn)換,如果不能轉(zhuǎn)換為number類型,就只是單純的字符串鍵值。
再來看最后一個(gè)例子:
var obj = {name:"mark"} var arr = [] arr[obj] = "12"; arr[obj] //?????? arr["[object Object]"] //?????
好了不賣關(guān)子了,它們兩個(gè)的結(jié)果都是"12",我們只需要記住一句話:數(shù)組鍵值如不是number,那么就遵循:其他類型->字符串鍵值->數(shù)字鍵值 這一規(guī)律。這個(gè)例子當(dāng)中,我們在賦值“12”時(shí),就已經(jīng)把obj轉(zhuǎn)換成了字符串"[object Object]",由于這段字符不能轉(zhuǎn)換為number類型所以JavaScript會以字符串鍵值的形式儲存。讀取亦是如此。
類數(shù)組說到它,我們先來看一張圖:
我們發(fā)現(xiàn),類數(shù)組和純數(shù)組的區(qū)別在于純數(shù)組當(dāng)中的原型鏈多了一層Array(我們稱之為數(shù)組對象),而類數(shù)組直接使用了內(nèi)置的Object對象。
數(shù)組對象中包含了我們經(jīng)常使用的數(shù)組方法及屬性大家在控制臺中輸出看一下:
那是不是類數(shù)組就不可以使用純數(shù)組當(dāng)中的方法了呢?類數(shù)組當(dāng)中沒有其數(shù)組方法,正常不可以使用,但是不要忘記,我們還可以使用call方法。
function foo (){ Array.prototype.push.call(arguments,2017); //為了方便查看,我們輸出一下參數(shù) console.dir(arguments); } foo(1,2); //[1,2,2017]
以上直接操作的argumens,也可以用slice工具函數(shù)拷貝新數(shù)組:
function foo(){ var arr = Array.prototype.slice.call(arguments); arr.push(2017); console.dir(arr); } foo(1,2); //[1,2,2017]
使用ES6中內(nèi)置的工具函數(shù)from也可以轉(zhuǎn)換為純數(shù)組:
var arr = Array.from(arguments);
我們之后再詳細(xì)介紹ES6中的特性。這里暫且先不說.
數(shù)組和字符串很相似,我們可以把它們都看成類數(shù)組,都有.length和indexof屬性。我們可以把它看成人妖,不男不女。好了,以后如果有人問你類數(shù)組是什么,你就可以大聲的告訴他了...
可能有些童鞋對類數(shù)組的定義還是有些模糊,小編從犀牛書上找到了一句話,比較不錯(cuò),看??
JavaScript有一些特性是其他對象所沒有的:
當(dāng)有新的元素添加時(shí),數(shù)組length屬性更新
設(shè)置length為一個(gè)較小值,將截?cái)鄶?shù)組
從Array.prototype繼承一些方法
類屬性為 Array
這些屬性讓JavaScript數(shù)組和常規(guī)對象喲明顯的區(qū)別,但是他們并不是定制數(shù)組的本質(zhì)特性。一種常常完全合理的看法把擁有一個(gè)數(shù)值length屬性和對應(yīng)非負(fù)整數(shù)屬性的對象看做一種類型的數(shù)組。
字符串上面我們說過,字符串和數(shù)組都屬于類數(shù)組,字符串內(nèi)部的實(shí)現(xiàn)有沒有使用數(shù)組并不好說,但JavaScript中的字符串和字符數(shù)組并不是一回事,最多只是看上去相似而已。
例如:
var a = "foo"; var b = ["f","o","o"];
它們都有l(wèi)ength屬性以及indexof和concat方法。
許多數(shù)組函數(shù)用來處理字符串很方便,雖然字符串沒有這些函數(shù),但可以通過借用數(shù)組的非變更方法來處理字符串:
var a = "foo"; a.join; //undefined a.map; //undefined var c = Array.prototype.join.call(a,"-"); var d = Array.prototype.map.call(a,function(v){ return v.toUpperCase() }).join("."); c; // "f-o-o"; d; // "F.O.O";
還有一個(gè)不同點(diǎn)在于字符串反轉(zhuǎn)(JavaScirpt面試常見問題),數(shù)組有一個(gè)字符串字符串沒有的可變更成員函數(shù) reverse();
"".reverse; //undefined [].reverse(); //Function
注意:這里不可以用call借用數(shù)組的可變更成員函數(shù),因?yàn)樽址遣豢勺兊?。我們可以把字符串做一個(gè)轉(zhuǎn)換,再進(jìn)行操作:
var a = "string", c = "string" .split("") .reverse() .join(""); c; //gnirts
如果經(jīng)常要以字符數(shù)組的方式的話,還不如直接使用數(shù)組,避免來回折騰,有需要時(shí)再使用join轉(zhuǎn)換為字符.
數(shù)字JavaScript只有一種數(shù)值類型number,它沒有真正意義上的整數(shù),這也是他一直為人詬病的地方.所謂的整數(shù)就是沒有小數(shù)點(diǎn)的十進(jìn)制數(shù),所以42.0等同于42。JavaScript的數(shù)字類型是基于IEEE754標(biāo)準(zhǔn)實(shí)現(xiàn)的,該標(biāo)準(zhǔn)也被稱為浮點(diǎn)數(shù),使用的是雙精度(即64位2進(jìn)制);
由于數(shù)字值可以使用Number對象進(jìn)行封裝,因此數(shù)字值可以調(diào)用Number.prototype中的方法。例如toFixed方法可指定小數(shù)的部分的顯示位數(shù):
var a = 42.59; a.toFixed(0); //42 a.toFixed(1); //42.6 a.toFixed(2); //42.59 a.toFixed(3) //42.590
注意,上例中的參數(shù)數(shù)值如果大于當(dāng)前數(shù)位,其余部分則用0補(bǔ)充,另外大家也應(yīng)該看到,toFixed的參數(shù)數(shù)值如果小于其數(shù)字?jǐn)?shù)位就會進(jìn)行四舍五入。
toPrecision()方法用來指定有效數(shù)位的現(xiàn)實(shí)位數(shù):
var a = 42.59; a.toPrecision(1) //4e+1 a.toPrecision(2) //43 a.toPrecision(3) //42.6 a.toPrecision(4) //42.59
在這里介紹一種情況:
42.toFixed(); //SyntaxError
我們要注意,不可使用數(shù)字常量直接訪問其方法,因?yàn)镴avaScript會認(rèn)為.是常量的一部分,我們可以賦給變量進(jìn)行操作,或者可以這樣.
var a = 42; 42.toFixed(1); 42..toFixed(1);
我們使用變量和..解決,不過不推薦使用第二種方式,在寫程序時(shí)我們也不會直接拿常量直接使用,在這我們稍作了解即可.
較小的數(shù)值二進(jìn)制浮點(diǎn)數(shù)最大的問題就在于(所有使用IEEE754規(guī)范的語言都是如此),是會出現(xiàn)如下情況:
0.1 + 0.2 ===0.3 //false
從數(shù)學(xué)角度來講上面的例子應(yīng)該返回true,可是會什么會返回false呢?
是因?yàn)槎M(jìn)制浮點(diǎn)數(shù)中的0.2和0.3都不是非常精確,它們相加的結(jié)果并非剛好等于0.3,而是一個(gè)比較接近的數(shù)字:0.000000000004,所以條件判斷為false。
那么應(yīng)該怎樣判斷0.1+0.2是否相等呢?
最常見的方法是設(shè)置一個(gè)誤差范圍,通常稱為“機(jī)器精度”。
從ES6開始,該值定義在number.EPSILON中,我們可以直接拿來用,也可以為ES6之間的版本寫一個(gè)polyfill:
if(!Number.EPSILON){ Number.EPSILON = Math.pow(2,-52) }
可以使用Number.EPSILON來比較兩個(gè)數(shù)字是否相等(在指定的誤差內(nèi));
function numberCloseEnoughToEqual(n1,n2){ return Math.abs(n1 - n2) < Number.EPSILON; var a = 0.1 + 0.2; var b = 0.3; numberCloseEnoughToEqual(a,b); //true numberCloseEnoughToEqual(0.0000001,0.0000002); //false
能夠呈現(xiàn)的最大浮點(diǎn)數(shù)大約是1.798e+308(這是一個(gè)相當(dāng)大的數(shù)字),它定義在Number.MAX_VALUE中,最小浮點(diǎn)數(shù)定義在Number.MIN_VALUE中,大約是5e-334,它不是負(fù)數(shù),但無限接近于0!
整數(shù)類型檢測ES6當(dāng)中新增Number.isInteger方法
Number.isInteger(32) //true Number.isInteger(32.3) //false
為該方法添加polyfill:
if(!Number.isInteger){
Number.isInteger = funcion(n){{ return typeof n === "number" && n % 1 === 0; }
}
不是值的值對于null和undefined,undefined只有一個(gè)值為undefined, null類型也只有一個(gè)類型,即null,它們的名稱即是類型也是值。
null (空值)
undefined (未被賦值)
null為關(guān)鍵字,undefined為標(biāo)識符.
在我們非嚴(yán)格模式下,是可以對標(biāo)識符賦值的:
function foo (){ undefined = 12; //為undefined賦值 } foo(); function foo (){ "use strict" undefined = 12 //Type Error } foo();
我們只需要了解這一點(diǎn)就可以,實(shí)際使用當(dāng)中,是絕對不可以這樣做的.
void運(yùn)算符
undefined 是一個(gè)內(nèi)置的標(biāo)識符,我們可以用void運(yùn)算符來定義一個(gè)表達(dá)式的返回值;
void并不改變表達(dá)式的返回值,它只是讓表達(dá)式不返回值;
假如我們現(xiàn)在要寫一個(gè)setTimeout計(jì)時(shí)器,由于這個(gè)方法每次都返回唯一的標(biāo)識符,那么我們就可以使用void 掉它;
void setTimout(function(){})不是數(shù)字的數(shù)字
我們都知道在javaScript數(shù)字運(yùn)算中有一種情況為NaN,如:
1/"a" //NaN []/{} //NaN ""/{} //NaN
我們發(fā)現(xiàn)有兩種情況為NaN:數(shù)字運(yùn)算中(出現(xiàn)數(shù)字運(yùn)算符)值非Number類型時(shí),或者無法正常解析為10進(jìn)制或者16進(jìn)制的有效數(shù)字.
可以使用全局方法isNaN來判斷是否為NaN
var s = 1/"a" isNaN(s) //true
可怕的是NaN連它自己都不想等,這也是JavaScript中唯一一個(gè)非自反的值
NaN == NaN // false NaN === NaN //false NaN != NaN //true
NaN的寓意是不是一個(gè)數(shù)字(Not a Number) ,"不是一個(gè)數(shù)字" 說到我們不得這個(gè)不看一段代碼:
var str = "abc"; var no = 1/"a"; isNaN(no) //true isNaN(str) // true --暈
這個(gè)bug已經(jīng)存留很久,我們在程序中盡量不要直接使用isNaN方法,可以polyfill或使用ES6的Number.isNaN
var str = "abc"; var no = 1/"a"; Number.isNaN(no) //true; Number.isNaN(str) //false
polyfill有兩種寫法,這里一起貼代碼給大家:
// v1 if(!Number.isNaN){ Number.isNaN = function(n){ typeof n === "number" && window.isNaN(n) } } //v2 if(!Number.isNaN){ Number.isNaN = function(n){ return n !== n } }
第二種方法很簡潔,正是利用了我們上面講過的NaN是js中唯一一個(gè)不和自己全等的特性
大家在程序中如果使用isNaN方法,一定要進(jìn)行二次改造,否則程序有可能會出問題。可以直接在頁面script里加入我們js需要添加的polyfill;
無窮數(shù)javaScript中使用有限數(shù)字表示法,也就是我們之前介紹過的IEEE754浮點(diǎn)數(shù),所以它和純數(shù)字的數(shù)學(xué)運(yùn)算不同,JavaScript的運(yùn)算結(jié)果可能會溢出,此時(shí)結(jié)果為Infinity或者-Infinity。
var a = Number.MAX_VALUE; //1.7976931348623157e+308 1/0 //Infinity a + Math.pow(2,970) //Infinity a + Math.pow(2,969) //1.7976931348623157e+308 a + a //Infinity
規(guī)范規(guī)定,如果數(shù)學(xué)運(yùn)算的結(jié)果超出處理范圍,則由IEEE754規(guī)范中的"就近取整"來決定最后的結(jié)果,這里的Math.pow(2,969)更為接近Number.MAX_VALUE,
所以被向下取整, Math.pow(2,970) + Number.MAX_VALUE與Infinity更為接近,所以被向上取整。
那如果對Infinity進(jìn)行數(shù)字運(yùn)算呢?會出現(xiàn)什么情況?
Infinity + Infinity // Infinity Infinity / Infinity //NaN Infinity * Infinity //Infinity Infinity - Infinity //NaN
我們可以這樣理解由于+ 和 * 都無需知道Infinity它是多少值,他們肯定比現(xiàn)在的值大,所以一定是Infinity;
如果是- 或者 /運(yùn)算符,在這樣的條件下他們的值一定小于現(xiàn)在的值,無窮大本身就不是一個(gè)有效數(shù)字,那么小于它的值我們沒法判斷,所以JavaScript給出的解釋是NaN;
在js中 0 也有兩種表達(dá)方式:-0 和 0
我們先來看看代碼:
0 * -3 //-0 0 / -3 //-0
加法和減法不會產(chǎn)生-0,0全等于-0
""+-0 //"0" JSON.stringify(-0) //"0" +"-0" // -0
在把-0字符串化后,會轉(zhuǎn)化為0;把“-0”轉(zhuǎn)換為number時(shí)還會恢復(fù)過來,是不是很奇怪?
那么我門在程序中到底如何區(qū)分 0 與 -0呢?我們可以拿 1/-0 等于 - Infinity 來進(jìn)行條件判斷;
function isNegZero (n){ Number(n); return ( n === 0 && (1 / n === -Infinity) ) } isNegZero(-0) //true isNegZero(0) //false
拋開學(xué)術(shù),我們?yōu)槭裁葱枰?fù)零呢?
下面是來自《你不知道的JavaScript 中卷》的一句話;
有些應(yīng)用程序中的數(shù)據(jù)需要以級數(shù)形式來表示(比如動畫貞的移動速度),數(shù)字的符號位用來代表其他位置信息,
此時(shí)如果一個(gè)值為0的變量失去了它的符號位,它的方向就會丟失,所以保留0值就可以防止類似的事情發(fā)生。
以上說的只是一種情況,在實(shí)際開發(fā)當(dāng)中,我們面對復(fù)雜的業(yè)務(wù)需求,也有可能要使用它,所以這里我們要記牢它,以備日后之用。
以上我們寫了很多的檢驗(yàn)函數(shù),在ES6中,只有一個(gè)很好玩的方法,叫做Object.is,說到這個(gè)函數(shù)肯定會有很多人噴我,
如果早說這個(gè)方法就沒必要寫那些了,其實(shí)不然,我們了解的不僅是js的特性,也是解決問題的方法.
var a = 1/"asd"; //NaN var o = 1 * -0; //-0 Object.is(a,NaN) //true Object.is("a",a) //false Object.is(o,0) //false Object.is(o,-0) //true
當(dāng)然少不了polyfill
if(Object.is){ Object.is = function(v1,v2){ if(v1 === 0 && v2 === 0){ return 1/ v1 === 1/v2 } //為NaN比較時(shí); if(v1 !== v1){ return v2 !== v2 //以上條件判斷,參數(shù)1一定為NaN,然后再判斷第二個(gè)參數(shù),是否為NaN, } //如果都不是那么就做全等比較 return v1 === v2 // } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/82190.html
摘要:設(shè)計(jì)模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時(shí)候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計(jì)模式必須要先搞懂面向?qū)ο缶幊?,否則只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識只有分享才有存在的意義。 是時(shí)候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...
摘要:我們再用復(fù)合條件來檢測一下值的類型由此我們知道,隱式強(qiáng)制類型轉(zhuǎn)換成了反值為說明的布爾值為,并對它的類型做出全等比較,最后返回。 我的第一篇文章 從開始學(xué)前端直至現(xiàn)在已有一年的時(shí)間了,期間遇見了很多事情,也經(jīng)歷了各式各樣的技術(shù)問題,為了讓自己擺脫這些這些問題,最后養(yǎng)成了看書的習(xí)慣。因?yàn)槊看慰赐昕傆X得自己內(nèi)功又增了,哪怕只是一點(diǎn)??上У氖敲看慰赐甓紩粢恍绕涫菦]有自己的實(shí)踐和知識點(diǎn)太...
介紹 在創(chuàng)建對象的時(shí)候,我們有2種常用方法 一個(gè)是文本標(biāo)記法(var obj = {}),一種是運(yùn)用Object函數(shù)進(jìn)行對象的創(chuàng)建(new Object()). 但是這兩種方式并不是創(chuàng)建的一個(gè)完完全全干干凈凈的對象,這里的干凈只得是沒有繼承鏈. 幸運(yùn)的是,ES5為我們提供了一種創(chuàng)建完全干凈的對象的方法,Object.create函數(shù),接下我將向大家介紹Obje...
CSS介紹 學(xué)前端必備掌握CSS樣式,css為層疊樣式表,用來定義頁面的顯示效果,加強(qiáng)用戶的體驗(yàn)樂趣,那么如何用css到html中呢? style屬性方式 利用標(biāo)簽中的style屬性來改變顯示樣式 p標(biāo)簽 在head中加入style標(biāo)簽 p { color: #FFF000;} 鏈接方式 總結(jié)CSS 選擇器名稱 { 屬性名:屬性值; ……. } 屬性與屬性之間用 分號...
摘要:深入系列第四篇,具體講解執(zhí)行上下文中的變量對象與活動對象。下一篇文章深入之作用域鏈本文相關(guān)鏈接深入之執(zhí)行上下文棧深入系列深入系列目錄地址。 JavaScript深入系列第四篇,具體講解執(zhí)行上下文中的變量對象與活動對象。全局上下文下的變量對象是什么?函數(shù)上下文下的活動對象是如何分析和執(zhí)行的?還有兩個(gè)思考題幫你加深印象,快來看看吧! 前言 在上篇《JavaScript深入之執(zhí)行上下文?!分?..
閱讀 3877·2021-07-28 18:10
閱讀 2585·2019-08-30 15:44
閱讀 1098·2019-08-30 14:07
閱讀 3468·2019-08-29 17:20
閱讀 1587·2019-08-26 18:35
閱讀 3543·2019-08-26 13:42
閱讀 1827·2019-08-26 11:58
閱讀 1601·2019-08-23 18:33