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