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

資訊專欄INFORMATION COLUMN

JavaScript 封裝對(duì)象與強(qiáng)制類型轉(zhuǎn)換

Lin_YT / 3486人閱讀

摘要:拆封想要等到封裝對(duì)象中基本類型值,我們可以使用方法獲取。值類型轉(zhuǎn)換上面兩種方式,第一種我們稱為顯示強(qiáng)制類型轉(zhuǎn)換第二種稱之為隱式強(qiáng)制類型轉(zhuǎn)換。介紹強(qiáng)制與隱式類型轉(zhuǎn)換時(shí),我們需要掌握對(duì)字符串?dāng)?shù)字和布爾類型的轉(zhuǎn)換規(guī)則。

前面兩章介紹了幾大數(shù)據(jù)類型以及值類型,接下來的這個(gè)知識(shí)點(diǎn),我覺得它對(duì)于javascript程序員來說是很重要的,

認(rèn)識(shí)封裝對(duì)象

在開始之前,我們先看一個(gè)例子,以便之后更輕松的理解封裝對(duì)象的概念。

   "tick".toUpperCase    //function toUpperCase()
   String.prototype.toUpperCase   //function toUpperCase()
   "tick".toUpperCase  === String.prototype.toUpperCase //true
   // 這里使用恒等比較判斷 常量的方法是否和Sting構(gòu)造函數(shù)中的方法為同一個(gè).

我們先來閱讀以下幾條知識(shí)點(diǎn),以免對(duì)下文做出更好的理解。

通過直接量的方式訪問方法或?qū)傩裕@種值我們稱之為常量方式 例如上面的第一行代碼。

在JavaScript中對(duì)象類型包括:對(duì)象,數(shù)組,函數(shù)這三種子類型,我們通常有兩種術(shù)語,引用類型 復(fù)合值,引用類型值在做恒等比較時(shí)比較的是他們內(nèi)存指向,即是否引用同一個(gè)值.

javascript對(duì)象是一種復(fù)合值,它是屬性或已命名值的集合,通過.符號(hào)來讀取屬性值。

通過上面的代碼我們可以看到,在使用常量方式訪問某個(gè)方法時(shí),依然會(huì)返回其數(shù)據(jù)類型對(duì)應(yīng)的內(nèi)置構(gòu)造函數(shù)方法,上面的第三點(diǎn)已經(jīng)說了,javascript通過.操作符來訪問屬性或方法,可是常量真的是對(duì)象嗎?它在訪問屬性的過程中底發(fā)生了什么?別急,跟隨我的腳步,下面我會(huì)竭盡全力把我知道的,我的觀點(diǎn)統(tǒng)統(tǒng)都說出來.

內(nèi)部屬性

在JavaScript中所有復(fù)合類型(如:對(duì)象,數(shù)組,函數(shù))都包含一個(gè)內(nèi)部屬性[[calss]],此屬性可以看作是一個(gè)內(nèi)部分類。它并不是傳統(tǒng)面向?qū)ο笊系念?由于是內(nèi)部屬性,所以我們無法直接訪問,不過,可以轉(zhuǎn)換為字符串來查看.

  Object.prototype.toString.call([1,2,3]) // "[Object Array]"
  Object.prototype.toString.call(/^[1,2]$/)  // "[Object RegExp]"

這里補(bǔ)充一點(diǎn),我們也可以通過此種方式去判斷一個(gè)對(duì)象是否為數(shù)組。

我們看到每個(gè)不同的常量類型中的[[class]],都對(duì)應(yīng)著它們相應(yīng)的內(nèi)部構(gòu)造函數(shù),也就是對(duì)象的內(nèi)部[[Class]]屬性和創(chuàng)建該對(duì)象的內(nèi)建原生構(gòu)造函數(shù)相對(duì)應(yīng),但有些特例.

   //一說特例,我估計(jì)就有人想到j(luò)avascript中比較蛋疼的兩個(gè)類型
   Object.prototype.toString.call(null) // "[Object Null]"
   Object.prototype.toString.call(undefined) // "[Object Undefined]"

除了null和undefined,其他都是javascript的內(nèi)置構(gòu)造函數(shù)。這里再次說一個(gè)小細(xì)節(jié),InfinityNaN它們返回什么呢?我想不用說大家也可以猜到了,它們都屬于Number類型.

  Object.prototype.toString.call(42)  // "[Object Number]"
  Object.prototype.toString.call("42") // "[Object String]" 
  Object.prototype.toString.call(true) //  "[Object Boolean]"

上面的例子除了null和undefined,它們都有各自的構(gòu)造類,這些類是javascript內(nèi)置的.

封裝對(duì)象過程

在日常開發(fā)中,我們通常不直接使用內(nèi)置的構(gòu)造類,而是直接通過常量訪問.

   var arr = new String("1234")
   arr    //  {0:"1",1:"2",2:"3",3:"4"}

通過構(gòu)造函數(shù)實(shí)例出來的常量變成了對(duì)象,其實(shí)就是手動(dòng)創(chuàng)建其封裝對(duì)象,封裝對(duì)象上存在對(duì)應(yīng)的數(shù)據(jù)類型方法。我們?cè)谑褂贸A康姆绞街苯釉L問屬性和方法時(shí),javascript會(huì)自動(dòng)為你包裝一個(gè)封裝對(duì)象,相當(dāng)于上面我們手動(dòng)包裝在操作屬性或方法完成之后JavaScript也會(huì)釋放當(dāng)前封裝對(duì)象

說到這里,我們可能會(huì)想到一個(gè)問題,如果需要經(jīng)常用到這些字符串的屬性和方法,比如在for循環(huán)當(dāng)中使用i

其實(shí)我們的想法很好,但實(shí)際證明這并不是一個(gè)好辦法,因?yàn)闉g覽器已經(jīng)為.length這樣常見情況做了性能優(yōu)化,直接使用封裝對(duì)象來提前優(yōu)化代碼反而會(huì)降低執(zhí)行效率。

一般情況下,我們不需要直接使用封裝對(duì)象,最好是讓JavaScript引擎自動(dòng)選擇什么時(shí)候應(yīng)該使用封裝對(duì)象,換句話說,就是應(yīng)該優(yōu)先考慮使用"abc"和42這樣的原始類型值,而非new String(‘a(chǎn)bc’)和new Number(42)

看如下代碼,思考它們的執(zhí)行結(jié)果:

  var test = "abc";
  test.len = 123;
  var t = test.len;

此處t為undefined,第三行是通過新的原始對(duì)象訪問其.len屬性,這并不是上次添加的.len,上次的已經(jīng)被銷毀,當(dāng)前是一個(gè)新的封裝對(duì)象.

說了這么多的理論與例子,不如我們從頭到尾來整理一下,通過基礎(chǔ)類型值訪問屬性過程中,到底發(fā)生了什么。

  var s = "hello world";
  var world = s.toUpperCase();

我們就以它為例:
首先javascript會(huì)講字符串值通過new String(s)的方式轉(zhuǎn)換為封裝對(duì)象,這個(gè)對(duì)象繼承了來自字符串構(gòu)造函數(shù)的所有方法(這些操作都從第二行訪問方法時(shí)開始發(fā)生),當(dāng)前s已經(jīng)變成了一個(gè)封裝對(duì)象,接下來在封裝對(duì)象中查找需要的方法或?qū)傩?,找到了之后做出相?yīng)的操作.一旦引用結(jié)束,這個(gè)新創(chuàng)建的對(duì)象就會(huì)銷毀。這時(shí)候s.toUpperCase已經(jīng)運(yùn)行了該方法,隨即銷毀封裝對(duì)象。

拆封

想要等到封裝對(duì)象中基本類型值,我們可以使用valueOf方法獲取。

    var ss = new String("123");
    ss.valueOf()  //"123"

javascipt 在需要用到封裝對(duì)象中基本類型值時(shí),會(huì)發(fā)生自動(dòng)轉(zhuǎn)換,即隱式強(qiáng)制類型轉(zhuǎn)換

  var t = new String("123");
  t+"";  "123"
不可變的原始值和可變的對(duì)象引用

javascript原始值(undefined null 字符串 數(shù)字 布爾)是不可修改的,而對(duì)象是可以被引用和修改的.講值類型那章時(shí)我們說過JavaScript變量沒有所謂的類型而言,衡量類型的是值,即值類型,在原始值上,我們無法更改,任何方法都無法更改一個(gè)原始值,這對(duì)于數(shù)字本身就說不通,怎么更改數(shù)字本身呢?但是對(duì)于字符串來說,看似有點(diǎn)說得通因?yàn)樗袷峭ㄟ^字符組成的數(shù)組,我們可以期望通過指定的索引來修改其字符元素,但javascript并不允許這么做。字符串方法看上去返回了修改后的值,其實(shí)返回的是一個(gè)新字符串,與之前的沒有任何關(guān)系.

強(qiáng)制類型轉(zhuǎn)換

封裝對(duì)象與類型轉(zhuǎn)換有很大關(guān)聯(lián),我們只有弄懂封裝對(duì)象的概念,才能更好的理解類型轉(zhuǎn)換,還有之后的相等比較與恒等比較。

值類型轉(zhuǎn)換
  var num = 123;
  //1
  num.toString(); // "123"

  //2
  num + ""; //"123"

上面兩種方式,第一種我們稱為顯示強(qiáng)制類型轉(zhuǎn)換.第二種稱之為隱式強(qiáng)制類型轉(zhuǎn)換。類型轉(zhuǎn)換總是返回基本類型值,不會(huì)返回對(duì)象類型,

第一個(gè),num.toString()時(shí),把num常量通過內(nèi)部[[class]]生成臨時(shí)的封裝對(duì)象,再調(diào)用對(duì)象toString方法,返回轉(zhuǎn)換完成的字符串.

第二個(gè),由于+運(yùn)算符的其中一個(gè)操作數(shù)是字符串,所以是字符串拼接操作,結(jié)果是數(shù)字123被轉(zhuǎn)換成“123”。

介紹強(qiáng)制與隱式類型轉(zhuǎn)換時(shí),我們需要掌握對(duì)字符串?dāng)?shù)字和布爾類型的轉(zhuǎn)換規(guī)則。

toString

基本類型的轉(zhuǎn)換規(guī)則為,undefined -> “undefined”, null->"null",true->"true",數(shù)字則使用通用規(guī)則,如果有極大或極小的值則使用指數(shù)形式.
var num = 1.37 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000
num.toString() //"1.37e+21"
普通對(duì)象除非自定義,否則它會(huì)返回對(duì)象內(nèi)部的[[Class]]屬性.
var obj = {};
obj.toString() //"[object Object]"
數(shù)組的toStirng有些特殊,它是通過","連接的字符串.
var arr = [1,2,3,4];
arr.toString();  // "1,2,3,4"

這里捎帶講一下json字符串化.

JSON.stringify在將JSON對(duì)象序列化為字符串時(shí)也使用了toString方法,但需要注意的是JSON.stringify并非嚴(yán)格意義上的強(qiáng)制類型轉(zhuǎn)換,只是涉及toString的相關(guān)規(guī)則.

  var num = 123;
  var str = “123”; 
  JSON.stringify(num) //“123”
  JSON.stringify(str) // “”123”” //兩個(gè)引號(hào)

所有安全的JSON值都可以使用JSON.stringify序列化,那么, 何為不安全的值?例如: undefined,function,Symbol(es6新增),如果JSON中出現(xiàn)這些值,序列化時(shí)不能把它們識(shí)別,就把他們變成了null。

JSON.stringify([1,undefined,function(){}]) //"[1,null,null]"

如果對(duì)象定義了toJSON方法,會(huì)先調(diào)用此方法,然后用它的返回值來進(jìn)行序列化。

  var obj = {name:"Jack"}
  obj.toJSON = function(){ return {name:”Join"} }
  
  JSON.stringify(obj)   // “{“name”:”Join"}"

在序列化之前,會(huì)先調(diào)用對(duì)象的toJSON方法,以它的返回值來進(jìn)行序列化.默認(rèn)對(duì)象是沒有此屬性的,如果有需要可以手動(dòng)添加。

toJSON返回的不是一個(gè)經(jīng)過JSON字符串化后的值,它應(yīng)該是一個(gè)適當(dāng)的值,也就是沒有經(jīng)過任何處理的值.當(dāng)然,它應(yīng)該被返回一個(gè)可以被JSON化的值.

var ob = {
  val : [1,2,3],
  toJSON : function(){
    return this.val.slice(2)
  }
 }

  var obj = {
    val : [1,2,3],
   toJSON:  function(){ 
     return this.val.slice(1).join()
    }
  }
JSON.stringify(ob)  //“[2,3]"
 JSON.stringify(obj) //“”2,3”” 雙引號(hào)

以上我們講JSON字符串化完全是toString捎帶出來的,它和toString很相似,但是卻還有些不同。既然上面已經(jīng)講了些,我們不妨再來看看它的幾個(gè)參數(shù).

很多開發(fā)者在使用JSON字符串化時(shí)候,只使用了第一個(gè)參數(shù),其實(shí)它是有三個(gè)參數(shù)的。

我們先來看第一個(gè)參數(shù)和第二參數(shù).

  var obj = { 
   a:42,
   b:”42",
   c:[1,2,3]
  }

  JSON.stringify(obj,function(k,v){ 
    if(k !== "c" ) return v
  })

第一個(gè)參數(shù)不用多介紹了吧,主要是第二個(gè)參數(shù),它有兩個(gè)參數(shù),和map的參數(shù)正好相反,也有filter方法的那點(diǎn)意思,在JSON字符串化中指定哪些屬性應(yīng)該被處理.

等等,這里有個(gè)小細(xì)節(jié),以上第二個(gè)回調(diào)參數(shù)實(shí)際上比我預(yù)想的多執(zhí)行了一次,假設(shè)以上為例,三個(gè)屬性,它第一次為undefined,第二次才是屬性a。這是為什么呢?因?yàn)樗谔幚頃r(shí),obj也計(jì)入其中了。

第三個(gè)參數(shù)是縮進(jìn)的字符,如果它是一個(gè)數(shù)字,就代表縮進(jìn)多少空格符。如果是字符串,則固定以它為縮進(jìn)符號(hào)。

 var obj = {
   a:42,
   b:”42”,
   c:[1,2,3] 
  }

 JSON.stringify(obj,function(k,v){
   if(k !==“c”) return v
},”---")
//"{
//----"a": 42,
//----"b": "42”
//}"

在編輯代碼時(shí),由于編輯器原因,引號(hào)的格式很不好把握,所以大家在復(fù)制代碼運(yùn)行時(shí)可能會(huì)出錯(cuò),需檢查引號(hào)是否為中文格式.

ToNumber

有時(shí)候我們需要將非數(shù)字類型當(dāng)做數(shù)字來使用,比如說數(shù)字運(yùn)算

其中true轉(zhuǎn)1,false轉(zhuǎn)換為,null轉(zhuǎn)換為0,undefined轉(zhuǎn)換為NaN
toNumber時(shí)如不能轉(zhuǎn)換為數(shù)字類型就會(huì)返回NaN,它對(duì)以0開頭的數(shù)字并不是以16進(jìn)制來處理,而是10進(jìn)制

var str = “123”;
str - 0;   //123

Number(str)  //123

字符串轉(zhuǎn)為number很簡(jiǎn)單,這里不做介紹。讓我們來看一下復(fù)合類型是如何轉(zhuǎn)換為Number類型的.
認(rèn)真讀下面這句話:

為了將值轉(zhuǎn)化為基本類型值,抽象操作ToPrimite(參見ES5規(guī)范9.1節(jié))會(huì)首先(通過內(nèi)部操作DefaultValue)檢查該值是否具有valueOf()方法,如果有就返回基本類型值,并使用該值進(jìn)行強(qiáng)制類型轉(zhuǎn)換,如果沒有就使用toString()的返回值來進(jìn)行強(qiáng)制轉(zhuǎn)換.

`如果valueOf()和toString()均不返回基本類型值,則會(huì)產(chǎn)生TypeError錯(cuò)誤

  var obj = {
   valueOf:function(){ return "42" }
  }

  var obj_1 = {
     toString:function(){ return "42" }      
  }

  var arr = [1,2,3]
  arr.toString = function(){ return this.join(“") } //“123"

 Number(obj)  //42
 Number(obj_1) //42
 Number(arr) // 123

ToBoolean

關(guān)于布爾值,我們存在許多誤解和困惑,需要我們特別注意.

javascript中有兩個(gè)關(guān)鍵詞true和false,分別代表布爾類型中的真和假,我們常誤認(rèn)以為數(shù)值1和0分別等同于true和false,在有些語言中可能是這樣,但在javascript中布爾值和數(shù)字時(shí)不一樣的,雖然我們可以將1強(qiáng)制類型轉(zhuǎn)換為true,將0強(qiáng)制轉(zhuǎn)換為false,反之亦然,但他們并不是一回事.

我們可以把他們分為兩類
(1) 可以被強(qiáng)制轉(zhuǎn)換為false的值
(2) 其他(被強(qiáng)制類型轉(zhuǎn)換為true的值)

假值
JavaScript規(guī)范具體定義了一小撮可以被強(qiáng)制類型轉(zhuǎn)換為false的值。
以下是一些假值:
undefined
null
false
+0 -0 和 NaN
“”
假值的布爾強(qiáng)制類型轉(zhuǎn)換結(jié)果為false.

雖然javascript規(guī)范沒有明確指出除了假值以外都是真值,但我們可以暫時(shí)理解為假值以外的值都是真值。

假值對(duì)象不是假值

  var  bool = new Boolean(false);
  var number = new Number(0);
  var string = new String(“0”);

這些都是假值封裝后的對(duì)象,讓我們來用復(fù)合條件來判斷一下.

  var a = new Boolean( bool && number && string ); 
  a   //true

我們都知道web端的javascript依賴兩個(gè)環(huán)境,javascript語言引擎,與宿主環(huán)境,宿主環(huán)境包括 DOM BOM,我們?yōu)槭裁刺峒八鼈兡兀?br>因?yàn)閐ocument里面有一個(gè)類數(shù)組對(duì)象它會(huì)被轉(zhuǎn)換為false,它包含了頁面中所有的元素。

  var dom = document.all;
  Boolean( dom )  //false

真值

 var a = “false”
 var b = “0”
 var c = “‘""
 Boolean( a && b && c ) // true

上例的字符串看似假值,但所有字符串都是真值,不過””除外,因?yàn)樗羌僦盗斜碇械奈ㄒ蛔址?
真值列表可以無限長(zhǎng),無法一一列舉,所以我們以假值作為參考。

真值有很多,可以無限延長(zhǎng),[],function,{} 都是真值。大家可以用一點(diǎn)時(shí)間去控制臺(tái)上練習(xí)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/88248.html

相關(guān)文章

  • 深入理解JavaScript類型轉(zhuǎn)換

    摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結(jié)果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們?cè)诿刻斓木帉懘a過程中,無時(shí)無刻不在應(yīng)用著值類型轉(zhuǎn)換,但是很多時(shí)候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉(zhuǎn)換的內(nèi)部轉(zhuǎn)換規(guī)則,最近通過閱讀你...

    W4n9Hu1 評(píng)論0 收藏0
  • 深入理解JavaScript類型轉(zhuǎn)換

    摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結(jié)果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們?cè)诿刻斓木帉懘a過程中,無時(shí)無刻不在應(yīng)用著值類型轉(zhuǎn)換,但是很多時(shí)候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉(zhuǎn)換的內(nèi)部轉(zhuǎn)換規(guī)則,最近通過閱讀你...

    niuxiaowei111 評(píng)論0 收藏0
  • 深入理解JavaScript類型轉(zhuǎn)換

    摘要:等同于等同于其他類型和布爾類型之間的比較如果是布爾類型,則返回的結(jié)果。 showImg(https://segmentfault.com/img/bVburFq?w=796&h=398); 前言 JavaScript作為一門弱類型語言,我們?cè)诿刻斓木帉懘a過程中,無時(shí)無刻不在應(yīng)用著值類型轉(zhuǎn)換,但是很多時(shí)候我們只是在單純的寫,并不曾停下腳步去探尋過值類型轉(zhuǎn)換的內(nèi)部轉(zhuǎn)換規(guī)則,最近通過閱讀你...

    shuibo 評(píng)論0 收藏0
  • 33 個(gè) js 核心概念(四):顯式 (名義) 隱式 (鴨子)類型轉(zhuǎn)換

    摘要:相對(duì)于顯式使用,隱式轉(zhuǎn)換則更加簡(jiǎn)潔。隱式轉(zhuǎn)換為布爾值將其他類型值隱式轉(zhuǎn)換為布爾值是我們最常用的一種轉(zhuǎn)換。在以下場(chǎng)景中,都是進(jìn)行判斷,而只要傳入的值不是布爾值,都會(huì)通過隱式類型轉(zhuǎn)換轉(zhuǎn)為布爾值。原文地址阿木木的博客與隱式鴨子類型轉(zhuǎn)換 showImg(https://segmentfault.com/img/remote/1460000017309581); 前言 說實(shí)話,JavaScrip...

    hoohack 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Lin_YT

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<