成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript值介紹

hsluoyz / 674人閱讀

摘要:的數(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ù)組,都有.lengthindexof屬性。我們可以把它看成人妖,不男不女。好了,以后如果有人問你類數(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

相關(guān)文章

  • JS程序

    摘要:設(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ù)組的那些迭代方法~ ...

    melody_lql 評論0 收藏0
  • JavaScript類型介紹

    摘要:我們再用復(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)太...

    K_B_Z 評論0 收藏0
  • JavaScript ES5之Object.create函數(shù)詳解

    介紹 在創(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...

    zhaofeihao 評論0 收藏0
  • 前端學(xué)習(xí)之路-CSS介紹,Html介紹,JavaScript介紹

    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 選擇器名稱 { 屬性名:屬性值; ……. } 屬性與屬性之間用 分號...

    mtunique 評論0 收藏0
  • JavaScript深入之變量對象

    摘要:深入系列第四篇,具體講解執(zhí)行上下文中的變量對象與活動對象。下一篇文章深入之作用域鏈本文相關(guān)鏈接深入之執(zhí)行上下文棧深入系列深入系列目錄地址。 JavaScript深入系列第四篇,具體講解執(zhí)行上下文中的變量對象與活動對象。全局上下文下的變量對象是什么?函數(shù)上下文下的活動對象是如何分析和執(zhí)行的?還有兩個(gè)思考題幫你加深印象,快來看看吧! 前言 在上篇《JavaScript深入之執(zhí)行上下文?!分?..

    Zachary 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<