亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

基礎(chǔ)回顧-javascript數(shù)據(jù)類型

codergarden / 1254人閱讀

摘要:棧區(qū)由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。屬性返回對創(chuàng)建此對象的構(gòu)造函數(shù)的引用。所有的和都是宿主對象參考高級程序設(shè)計堆和棧的概念和區(qū)別全面解析中的數(shù)據(jù)類型與類型轉(zhuǎn)換

數(shù)據(jù)類型

數(shù)據(jù)類型劃分

javascript中定義了6中基本數(shù)據(jù)類型(原始值類型),和一種復(fù)雜數(shù)據(jù)類型(引用類型),所謂復(fù)雜類型,其本質(zhì)是由無序的名值對(key:value)組成的。

基本數(shù)據(jù)類型:

String

Number

Boolean

undefined

null

Symbol (ES6 新增)

復(fù)雜數(shù)據(jù)類型

Object

原始值引用值

上面提到了原始值引用類型,可能有些人對于引用類型很熟悉,但是原始值卻很陌生實際上,在ECMAScript中,變量可以存放兩種類型的值,即原始值和引用值。

原始值(primitive value)

原始值是固定而簡單的值,是存放在棧(stack)中的簡單數(shù)據(jù)段,也就是說,它們的值直接存儲在變量訪問的位置。

引用值(reference value)

引用值則是比較大的對象,存放在堆(heap)中的對象,也就是說,存儲在變量處的值是一個指針(pointer),指向存儲對象的內(nèi)存處。所有引用類型都集成自O(shè)bject。

之所以說原始值是固定的,原因是當(dāng)我們對原始值進行一些操作時結(jié)果返回的都是一個新的副本,但是對引用值操作時可能更改原值。

var str = "asdfghjkl";
var obj = {name:1,age:2};

var str2 = str;
var obj2 = obj;

str2 = "lkjhgfdsa";
obj2.name= 3;

console.log(str,str2,obj,obj2)  
//asdfghjkl lkjhgfdsa {name: 3, age: 2} {name: 3, age: 2} 

obj == obj2   //true 

通過以上代碼可以明確看出字符串是按值傳遞的,在賦值時會新建存儲空間,將str 和 str2 存放在不同的內(nèi)存空間內(nèi),對象是按引用傳遞的,obj = obj2時沒有新建堆內(nèi)存空間,而是在棧內(nèi)存中存放標(biāo)識符和值的引用地址,引用地址與obj的棧值相同,指向堆內(nèi)存中的存儲空間。

同時可以看到obj == obj2 返回true,這是為什么?

var obj3 = {name:3,age:2}
obj == obj3    //false

obj3 與 obj 的屬性和屬性值是一樣的,但是 obj == obj3 卻返回false, obj == obj2 返回true, 這說明引用類型在判斷相等的時候比較的是指針,即指向?qū)?nèi)存的地址。

提到原始值 引用值 內(nèi)存地址等詞,就不得不提數(shù)據(jù)的存儲空間

數(shù)據(jù)的存儲方式

堆棧

之前說到基本類型存儲在棧內(nèi)存中,復(fù)雜類型存儲在堆內(nèi)存中,那么什么是棧,什么是堆?

這里說的堆和棧并不是一種數(shù)據(jù)結(jié)構(gòu),而是指存儲空間,JVM內(nèi)存劃分為:寄存器,本地方法區(qū),方法區(qū),堆內(nèi)存,棧內(nèi)存,我們說的堆棧就是這里的堆內(nèi)存 和 棧內(nèi)存。

棧區(qū)(stack)

由編譯器自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。

堆區(qū)(heap)

一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收 。

堆棧區(qū)別

1.棧內(nèi)存存儲的是局部變量而堆內(nèi)存存儲的是實體;
2.棧內(nèi)存的更新速度要快于堆內(nèi)存,因為局部變量的生命周期很短;
3.棧內(nèi)存存放的變量生命周期一旦結(jié)束就會被釋放,而堆內(nèi)存存放的實體會被垃圾回收機制不定時的回收,前提是沒有任何引用。

關(guān)于堆和棧的內(nèi)存空間,這里只是簡單提起,強調(diào)指內(nèi)存空間并非數(shù)據(jù)結(jié)構(gòu)。

不同數(shù)據(jù)類型的存儲區(qū)別

var a = undefined;
var b = null;
var c = "asdfg";
var d = 123;
var e = true;

var f = [1,2];
var g = {name:1,age:2};
var h = g;

下圖解釋不同每一種類型的存儲方式

上圖體現(xiàn)出每種數(shù)據(jù)類型在內(nèi)存中的存儲方式:

基本類型undefined null String Number Boolean 直接將標(biāo)識符和值存儲在棧區(qū)內(nèi);

復(fù)雜類型對象,數(shù)組等,棧區(qū)內(nèi)只存放標(biāo)識符和指向堆內(nèi)存中的對象的指針,真真的對象值存儲在堆內(nèi)存中,同一對象的引用指針相同:g == h;

數(shù)據(jù)類型的判斷方式

數(shù)據(jù)類型的判斷有多種方式,下面簡單介紹

typeof

typeof 用于檢測數(shù)據(jù)的類型,返回值有

number

string

boolean

undefined

object

function

var u ,a = "asdf",b = 1,c = true,d = {},e = null,f = function(){}
typeof a;  // string
typeof b;  //number
typeof c;  //boolean
typeof u;  //undefined
typeof d;  //object
typeof e;  //object
typeof f;  //function

typeof a == "string"  //true
typeof a == String   //false

以上代碼可以看出

返回值為字符串,并且區(qū)分大小寫;

typeof null 返回 object,因為null是Object的一種,表示空引用,即棧內(nèi)存儲的指向堆中對象的指針為空;

typeof 可以判斷function的類型,并且對于非Object類型的數(shù)據(jù)區(qū)分類型比較方便;

不能區(qū)分Object的 具體類型,如 Array Date

instanceof

instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構(gòu)造函數(shù)的 prototype 屬性。

由于js可在多個frame之間交互,但是每個frame有自己的全局環(huán)境,所以不同frame和窗口之間Array是不同的,所以無法用 a 環(huán)境下的數(shù)組去判斷是否是 b 環(huán)境下的Array對象的實例

var a = "asdffgg";
var b = 1;
var c = new String("aaaa");
var arr = [1,2];
var date = new Date();

a instanceof String  //false   思考:為什么是false?
b instanceof Number  //false
c instanceof Number  //true    思考:a 和 c 同樣是字符串結(jié)果卻不一樣
arr instanceof Array   //true
arr instanceof Object  //true    思考:為什么 Array 和 Object都是true?
date instanceof Date  //true
date instanceof Object  //true

typeof a    //string    字面量的形式 返回基本類型 string
typeof c    //object    new 一個String的實例 返回復(fù)雜類型 object

通過以上的代碼段體現(xiàn)出以下特點和弊端:

instanceof 用于檢測Object類型的對象,基本類型的字面量值永遠返回false;

instanceof 由于對象的繼承關(guān)系,所以只能用來判斷兩個對象是否屬于實例關(guān)系,而不能判斷一個對象實例具體屬于哪種類型

數(shù)組即是Array的實例,又是Object的實例的原因詳解:
由于對象之間存在繼承關(guān)系,所以instanceof 能夠判斷出 [ ].__proto__ 指向 Array.prototype,而 Array.prototype.__proto__ 又指向了Object.prototype,最終 Object.prototype.__proto__ 指向了null,標(biāo)志著原型鏈的結(jié)束。這里關(guān)于原型鏈的知識點不細說

所以無法判斷實例對象具體是Object的哪一種類型。

constructor

constructor 屬性返回對創(chuàng)建此對象的構(gòu)造函數(shù)的引用。

當(dāng)定義一個函數(shù)Fn的時候,JS引擎會為其添加一個原型prototype,并為原型添加一個constructor屬性,將其指向Fn的引用

實例f的constructor是指向其構(gòu)造函數(shù)Fn的,所以通過constructor我們可以判斷其構(gòu)造函數(shù)是誰,從而間接的判斷對象的具體類型
但是由于constructor在實現(xiàn)繼承的時候可以被更改,實質(zhì)更改是由于子類繼承父類的時候可能重寫了子類的原型prototype,因此使子類的prototype上的constructor發(fā)生變化,因此類型判斷可能不準(zhǔn)確

undefined 和 null沒有constructor屬性

toString

Object.prototype.toString 方法可以返回對象的內(nèi)部屬性[[Class]],格式為[object,Xxxx],其中Xxxx為具體的類型

Object.prototype.toString.call("") //"[object String]"

Object.prototype.toString.call([1]) //"[object Array]"

Object.prototype.toString.call(new Date) //"[object Date]"

為什么不調(diào)用對象的toString方法,而是通過call調(diào)用Object.prototype.toString?

"11".toString() //"11"
[1,2].toString() //"1,2"
new Date().toString() //"Fri Jun 22 2018 14:44:52 GMT+0800 (CST)"

可以看到字符串輸出的是本身,數(shù)組輸出的是“,”鏈接的數(shù)組字符串,時間類型輸出的時間字符串,都不是內(nèi)部屬性[[Class]],原因是實例的構(gòu)造函數(shù)重寫了toString方法,所以要吊用Object對象的原型傷的toString方法。

類型轉(zhuǎn)換

轉(zhuǎn)數(shù)值類型

顯示轉(zhuǎn)換:Number() parseInt() parseFloat()

向Number 轉(zhuǎn)換規(guī)則 ToNumber

Boolean類型的true false,轉(zhuǎn)成1 和 0

數(shù)值直接轉(zhuǎn)成原始值,即本身

null 轉(zhuǎn)為0,undefined 轉(zhuǎn)為NaN

字符串類型,數(shù)值字符串轉(zhuǎn)為數(shù)值型數(shù)字;空字符串""轉(zhuǎn)為0;非數(shù)字字符串轉(zhuǎn)為NaN

對象,則調(diào)用對象的valueOf()方法,按前面規(guī)則轉(zhuǎn)為原始值,如果返回NaN,調(diào)用對象的toString()方法,返回值再依照前面規(guī)則轉(zhuǎn)數(shù)值

var a = {a:1}
Number(11)        //11
Number("123")     //123
Number(true)      //1
Number(null)      //0
Number(undefined) //NaN
Number("")        //0
Number(a)     //NaN   a.valueOf返回 {a:1},a.toString 返回 "[object,Object]",字符串轉(zhuǎn)數(shù)值 返回NaN

parseInt parseFloat 這里不細說

隱式轉(zhuǎn)換:操作符

+做為一元操作符,操作數(shù)轉(zhuǎn)化為數(shù)值類型

+作為二元操作符,兩個操作數(shù)中只要有一個是字符串類型,那么另一個也轉(zhuǎn)化成字符串類型

+作為二元操作符,兩個操作數(shù)均不是字符串類型,那么兩個操作數(shù)均各自隱式向數(shù)值型轉(zhuǎn)化,然后在計算

如果數(shù)值計算的操作符不是+操作符,那么操作數(shù)向數(shù)值轉(zhuǎn)化

轉(zhuǎn)String類型

顯示轉(zhuǎn)換 toString() String()

toString:返回相應(yīng)的字符串表現(xiàn),

向字符串轉(zhuǎn)換規(guī)則 ToString

數(shù)字類型,轉(zhuǎn)為數(shù)字字符串

字符串,返回原值

undefined null,沒有toString方法,可以用String()方法,返回"null"和"undefined"字符串

Boolean 轉(zhuǎn)為"true" "false"

對象,先調(diào)用toString得到原始值,如果是原始值類型則返回;不是則調(diào)用valueOf,返回結(jié)果如果是原始值類型則返回,不是在做toString調(diào)用,返回結(jié)果

var a = {a:1};var b = 11;var c = "11"; var e = "[1,3]";var d = true

a.toString()  //"[object,Object]"
b.toString()  //"11"
c.toString()  //"11"
d.toString()  //"true"
e.toString()  //"1,3"

隱式轉(zhuǎn)換同+操作符數(shù)值轉(zhuǎn)化

轉(zhuǎn)Boolean類型

顯示轉(zhuǎn)換:Boolean()

向Boolean轉(zhuǎn)換規(guī)則:

數(shù)字0,""空字符串,null,undefined,NaN轉(zhuǎn)為false,其余轉(zhuǎn)為true

隱式轉(zhuǎn)換操作符 if

什么是隱式轉(zhuǎn)換?

隱式轉(zhuǎn)換與執(zhí)行環(huán)境和操作符相關(guān),當(dāng)前操作期望某種值的時候,就會發(fā)生隱式轉(zhuǎn)換,實際上面提到的具體規(guī)則點就是隱式轉(zhuǎn)換的過程。

內(nèi)置對象(本地對象)、單體內(nèi)置對象,宿主對象

本地對象:不依賴于宿主環(huán)境的對象
Object Array Date Function RegExp String Boolean Number

單體內(nèi)置對象:由ECMAScript實現(xiàn)提供的,不依賴于宿主環(huán)境的對象,這些對象在ECMAScript程序執(zhí)行前就已經(jīng)存在了
Global(所有不屬于其他任何對象的屬性和方法都屬于Global,全局變量,方法),Math,一些數(shù)學(xué)公式和計算方法

宿主對象:由ECMAScript實現(xiàn)的宿主環(huán)境提供的對象,可以理解為:瀏覽器提供的對象。所有的BOM和DOM都是宿主對象 , Window

參考

javascript 高級程序設(shè)計
堆和棧的概念和區(qū)別
全面解析js中的數(shù)據(jù)類型與類型轉(zhuǎn)換

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

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/95802.html

相關(guān)文章

  • JavaScript 回顧學(xué)習(xí):變量

    摘要:變量的分類全局變量可以在任何地方使用的變量局部變量在函數(shù)內(nèi)聲明的變量只在函數(shù)內(nèi)有定義,作用域是局部性的什么時候使用當(dāng)一個數(shù)據(jù)需要被反復(fù)使用時,就要先保存在變量中。 第一篇回顧學(xué)習(xí),變量 什么是變量 變量就是在內(nèi)存中刨一個坑存一個數(shù)據(jù),再給這個坑起個名。為什么要給一個加引號呢,因為JavaScript是松散類型的,即一個變量可以用來保存任何類型的數(shù)據(jù)。變量的分類:全局變量:可以在任何地方...

    KitorinZero 評論0 收藏0
  • javascript基礎(chǔ)篇小結(jié)

    摘要:表示尚未存在的對象是一個有特殊意義的值??梢詾樽兞抠x值為,此時變量的值為已知狀態(tài)不是,即。用來初始化變量,清除變量內(nèi)容,釋放內(nèi)存結(jié)果為但含義不同。且它倆與所有其他值比較的結(jié)果都是。,需要兩個操作數(shù)同時轉(zhuǎn)為。 轉(zhuǎn)載請聲明出處 博客原文 隨手翻閱以前的學(xué)習(xí)筆記,順便整理一下放在這里,方便自己復(fù)習(xí),也希望你有也有幫助吧 第一課時 入門基礎(chǔ) 知識點: 操作系統(tǒng)就是個應(yīng)用程序 只要是應(yīng)用...

    hiyang 評論0 收藏0
  • 前端面試回顧(1)---javascript的面向?qū)ο?/b>

    摘要:每個類有三部分構(gòu)成第一部分是構(gòu)造函數(shù)內(nèi),供實例對象化復(fù)制用。第二部分是構(gòu)造函數(shù)外,直接通過點語法添加,供類使用,實例化對象訪問不到。組合繼承還有一個要注意的地方在代碼處,將子類原型的屬性指向子類的構(gòu)造函數(shù)。 前言 前一陣面試,過程中發(fā)現(xiàn)問到一些很基礎(chǔ)的問題時候,自己并不能很流暢的回答出來?;蛘哂龅揭恍┗A(chǔ)知識的應(yīng)用,由于對這些點理解的不是很深入,拿著筆居然什么都寫不出來,于是有了回顧一...

    animabear 評論0 收藏0
  • JS基礎(chǔ)知識回顧-1

    摘要:原始類型數(shù)組,循環(huán)變量不能以數(shù)字開頭,因為如果這樣編譯器則無法區(qū)別數(shù)字和變量??梢灾苯有薷臄?shù)組的值如就變成了輸出為循環(huán)和判斷 Part1 原始類型,數(shù)組,循環(huán) Variables 變量不能以數(shù)字開頭,因為如果這樣編譯器則無法區(qū)別數(shù)字和變量。 養(yǎng)成好習(xí)慣每句話后面加分號 Primitive data types 包括Number,String, Boolean, Undefined...

    CoorChice 評論0 收藏0
  • JavaScript回顧學(xué)習(xí):目錄篇

    摘要:前言之前說要重頭開始復(fù)習(xí),之前一直都在忙著找工作面試,現(xiàn)在工作也終于是找到了,雖然不那么盡人意,但總算有個歸屬,一段時間的適應(yīng)也有了自己穩(wěn)定的時間規(guī)劃,為了給懶惰捉急的自己一個前行的動力,這一篇的回顧學(xué)習(xí)目錄篇也就這樣提上了日程。 前言 之前說要重頭開始復(fù)習(xí)js,之前一直都在忙著找工作面試,現(xiàn)在工作也終于是找到了,雖然不那么盡人意,但總算有個歸屬,一段時間的適應(yīng)也有了自己穩(wěn)定的時間規(guī)劃...

    luckyw 評論0 收藏0

發(fā)表評論

0條評論

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