日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

【JavaScript】封装对象与强制类型转换

發(fā)布時間:2023/12/20 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【JavaScript】封装对象与强制类型转换 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

認(rèn)識封裝對象

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

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

我們先來閱讀以下幾條知識點,以免對下文做出更好的理解。

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

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

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

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

    內(nèi)部屬性

    在JavaScript中所有 復(fù)合類型 (如:對象,數(shù)組,函數(shù))都包含一個內(nèi)部屬性 [[calss]] ,此屬性可以看作是一個內(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]'

    這里補充一點,我們也可以通過此種方式去判斷一個對象是否為數(shù)組。

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

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

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

    封裝對象過程

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

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

    通過構(gòu)造函數(shù)實例出來的常量變成了對象,其實就是手動創(chuàng)建其封裝對象,封裝對象上存在對應(yīng)的數(shù)據(jù)類型方法。?我們在使用常量的方式直接訪問屬性和方法時,javascript會自動為你包裝一個封裝對象,相當(dāng)于上面我們手動包裝?在操作屬性或方法完成之后JavaScript也會釋放當(dāng)前封裝對象

    說到這里,我們可能會想到一個問題,如果需要經(jīng)常用到這些字符串的屬性和方法,比如在for循環(huán)當(dāng)中使用i<a.length,那么一開始創(chuàng)建一個封裝對象也許更為方便,這樣JavaScript引擎就不用每次都自動創(chuàng)建和自動釋放循環(huán)執(zhí)行這些操作了。

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

    一般情況下,我們不需要直接使用封裝對象,最好是讓JavaScript引擎自動選擇什么時候應(yīng)該使用封裝對象,換句話說,就是應(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 ,第三行是通過新的原始對象訪問其 .len 屬性,這并不是上次添加的 .len ,上次的已經(jīng)被銷毀,當(dāng)前是一個新的封裝對象.

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

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

    我們就以它為例:

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

    拆封

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

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

    javascipt 在需要用到封裝對象中基本類型值時,會發(fā)生自動轉(zhuǎn)換,即 隱式強制類型轉(zhuǎn)換

    var t = new String("123");t+""; "123"

    不可變的原始值和可變的對象引用

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

    強制類型轉(zhuǎn)換

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

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

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

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

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

    介紹強制與隱式類型轉(zhuǎn)換時,我們需要掌握對字符串?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"普通對象除非自定義,否則它會返回對象內(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對象序列化為字符串時也使用了toString方法,但需要注意的是JSON.stringify并非嚴(yán)格意義上的強制類型轉(zhuǎn)換,只是涉及toString的相關(guān)規(guī)則.

    var num = 123;var str = “123”; JSON.stringify(num) //“123”JSON.stringify(str) // “”123”” //兩個引號

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

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

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

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

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

    toJSON返回的不是一個經(jīng)過JSON字符串化后的值,它應(yīng)該是一個 適當(dāng) 的值,也就是沒有經(jīng)過任何處理的值.當(dāng)然,它應(yīng)該被返回一個可以被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”” 雙引號

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

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

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

    var obj = { a:42,b:”42",c:[1,2,3]}JSON.stringify(obj,function(k,v){ if(k !== "c" ) return v})

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

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

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

    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” //}"

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

    • ToNumber

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

    其中true轉(zhuǎn)1,false轉(zhuǎn)換為,null轉(zhuǎn)換為0,undefined轉(zhuǎn)換為NaN

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

    var str = “123”; str - 0; //123Number(str) //123

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

    認(rèn)真讀下面這句話:

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

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

    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) //42Number(obj_1) //42Number(arr) // 123

    • ToBoolean

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

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

    我們可以把他們分為 兩類

    (1) 可以被強制轉(zhuǎn)換為false的值

    (2) 其他(被強制類型轉(zhuǎn)換為true的值)

    假值

    JavaScript規(guī)范具體定義了一小撮可以被強制類型轉(zhuǎn)換為false的值。

    以下是一些假值:

    undefined

    null

    false

    +0 -0 和 NaN

    “”

    假值的布爾強制類型轉(zhuǎn)換結(jié)果為false.

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

    假值對象不是假值

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

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

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

    我們都知道web端的javascript依賴兩個環(huán)境,javascript語言引擎,與宿主環(huán)境,宿主環(huán)境包括 DOM BOM,我們?yōu)槭裁刺峒八鼈兡?#xff1f;

    因為document里面有一個類數(shù)組對象它會被轉(zhuǎn)換為false,它包含了頁面中所有的元素。

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

    真值

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

    上例的字符串看似假值,但所有字符串都是真值,不過””除外,因為它是假值列表中的唯一字符串.

    真值列表可以無限長,無法一一列舉,所以我們以假值作為參考。

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

    總結(jié)

    以上是生活随笔為你收集整理的【JavaScript】封装对象与强制类型转换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。