摘要:熟悉的同學(xué)都知道,它的數(shù)據(jù)類型一般分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型復(fù)雜數(shù)據(jù)類型?;緮?shù)據(jù)類型基本數(shù)據(jù)類型有種新增。動態(tài)的屬性基本數(shù)據(jù)類型的值是沒有辦法添加屬性和方法的。類型檢測根據(jù)它的原型鏈來識別引用類型。
熟悉js的同學(xué)都知道,它的數(shù)據(jù)類型一般分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型(復(fù)雜數(shù)據(jù)類型)。那么他們之間到底有什么不同?
從下面這個例子入手:
var a = 1; var b = a; a = 2 console.log(a === b)//false console.log(b) //1 var obj = {}; var obj1 = obj; obj.a = 1; console.log(obj === obj1) //true console.log(obj1) // {a:1}
可以看出來,b復(fù)制了a的值后,對a再進行修改,b是完全不知道的!而修改對象obj后,obj的復(fù)制值obj1竟然也改變了,始終===。這是為什么?
原因是基本類型值指的是簡單的數(shù)據(jù)段,基本數(shù)據(jù)類型是按值訪問的,因為可以操作保存在變量中的實際的值。引用類型的值是保存在內(nèi)存中的對象,通過引用地址來訪問,對象添加a:1后,引用地址并沒有改變,所以obj === obj1。下面從4個方面看一下基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的區(qū)別。
js基本數(shù)據(jù)類型有6種:null、undefined 、boolean、number、string 、symbol(es 6新增)。
1.動態(tài)的屬性
基本數(shù)據(jù)類型的值是沒有辦法添加屬性和方法的。
var a = 1; a.b = 2;//報錯: Uncaught TypeError: Cannot create property "b" on number "1"
2.復(fù)制變量值
可以看到,在從一個變量向另一個變量復(fù)制基本類型值時,num1中的5和num2中的5是相互獨立的,所以修改num1或者num2是互不影響的。
3.參數(shù)傳遞
var a = 1 function fn(a){ return a += 5 } var b = fn(a) //6 console.log(a) // 1
可以看出,基本數(shù)據(jù)類型值做為函數(shù)參數(shù)傳遞時,a的值是不會改變的,只是在函數(shù)內(nèi)新復(fù)制了一份a,函數(shù)內(nèi)部的a跟外部的沒有任何關(guān)系。
4.類型檢測
var s = "Nicholas"; var b = true; var i = 22; var u; var n = null; var o = new Object(); alert(typeof s); //string alert(typeof i); //number alert(typeof b); //bollean alert(typeof u); // undefined alert(typeof n);//object alert(typeof o);//object
正常情況下,對基本數(shù)據(jù)類型值的檢測可以通過typeof返回,但是typeof null會返回object?
在 javascript 的最初版本中,使用的 32 位系統(tǒng),為了性能考慮使用低位存儲了變量的類型信息: 000:對象 1:整數(shù) 010:浮點數(shù) 100:字符串 110:布爾 有 2 個值比較特殊: undefined:用 - (?2^30)表示。 null:對應(yīng)機器碼的 NULL 指針,一般是全零。引用數(shù)據(jù)類型
1.動態(tài)屬性
var person = new Object(); person.name = "Nicholas"; console.log(person.name); //"Nicholas" delete person.name console.log(person.name);//undefined
2.賦值變量
var obj1 = new Object(); var obj2 = obj1; obj1.name = "Nicholas"; console.log(obj2.name); //"Nicholas"
obj1賦值新對象時,只是向obj1中存如指向object的引用地址,向obj2賦值obj1時,僅僅是將obj1中儲存的引用地址復(fù)制給obj2,所以對象改變時,obj1和obj2會同時響應(yīng)。
3.參數(shù)傳遞
參數(shù)傳遞只有值傳遞,不存在引用傳遞。也就是說,把函數(shù)外部的值復(fù)制給函數(shù)內(nèi)部的參數(shù),就和把值從一個變量復(fù)制到另一個變量一樣?;绢愋椭档膫鬟f如同基本類型變量的復(fù)制一樣,而引用類型值的傳遞,則如同引用類型變量的復(fù)制一樣。有不少開發(fā)人員在這一點上可能會感到困惑,因為訪問變量有按值和按引用兩種方式,而參數(shù)只能按值傳遞。
function fn(obj){ obj.name = "new" return obj } var obj = new Object(); var newObj = fn(obj) console.log(obj)//{name:new} console.log(newObj)//{name:new}
看上面結(jié)果不就是引用傳遞嗎?obj傳進去已經(jīng)被修改了??!以上代碼中創(chuàng)建一個對象,并將其保存在了變量 person中。然后,這個變量被傳遞到 setName() 函數(shù)中之后就被復(fù)制給了 obj。在這個函數(shù)內(nèi)部,obj 和 person 引用的是同一個對象。換句話說,即使這個變量是按值傳遞的,obj也會按引用來訪問同一個對象。于是,當在函數(shù)內(nèi)部為 obj 添加 name 屬性后,函數(shù)外部的 person 也將有所反映;因為 person 指向的對象在堆內(nèi)存中只有一個,而且是全局對象。有很多人錯誤地認為:在局部作用域中修改的對象會在全局作用域中反映出來,就說明 參數(shù)是按引用傳遞的。為了證明對象是按值傳遞的,我們再看一看下面這個經(jīng)過修改的例子:
function fn(obj){ obj.name = "new" obj = new Object(); obj.name = "Greg"; return obj } var obj = new Object(); var newObj = fn(obj) console.log(obj)//{name:new} console.log(newObj)//{name:Greg}
如果 person是按引用傳遞的,那么 person 就會自動被修改為指向其 name 屬性值 為"Greg"的新對象。
4.類型檢測
instanceof 根據(jù)它的原型鏈來識別引用類型。
person instanceof Object
所有引用類型的值都是 Object 的實例。因此,在檢測一個引用類型值和 Object 構(gòu)造 函數(shù)時,instanceof 操作符始終會返回 true。當然,如果使用 instanceof 操作符檢測基本類型的 值,則該操作符始終會返回 false,因為基本類型不是對象。
看到這里,知道引用數(shù)據(jù)類型賦值是引用地址,對象值是存放在堆中的。現(xiàn)在,在對象中A中嵌套對象B,那么A對象內(nèi)存堆中存放的是A對象內(nèi)存?還是A內(nèi)存的引用尼?是如何賦值的?
var obj = { arr:[1,2,3] } var obj1 = obj; //復(fù)制obj的引用地址 var arr = obj.arr //復(fù)制obj中arr的引用地址 var arr1 = obj1.arr // 復(fù)制arr中引用地址 arr1[0] = [1] console.log(arr) //[[1],1,2,3] console.log(arr1 === obj.arr) //true //地址還是相同 obj.arr = [4,5,6] //突然改變obj中arr,指向新對象,obj中arr的引用也隨之改變 console.log(arr) //[[1],1,2,3] //而此時arr、arr1的引用還沒有改變 console.log(obj1.arr === obj.arr) //true //obj的引用沒有改變 console.log(obj1.arr === arr) //false
從上面的例子可以看出,object1中儲存的是arr的引用地址,與arr、arr1擁有同一個引用地址。將obj1的arr重新賦值新的對象后,obj1中的引用地址會重新分配,obj里的arr也跟隨改變。假如,object中存放的是arr的內(nèi)存,那么obj1中arr重新指向新對象時,obj中的arr將會之斷開聯(lián)系,像arr1一樣,顯然不是。
如有不妥!歡迎指正!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106452.html
摘要:例子中,屬于基本類型對象。基本數(shù)據(jù)類型和引用類型作方法入?yún)r的差異通常,在函數(shù)調(diào)用時,如果入?yún)榛緮?shù)據(jù)類型時,函數(shù)的參數(shù)將以值傳遞的方式傳遞。 前言:再次翻閱JS高程(第3版)過程中,看到了基本包裝類型,趁熱留下此文,對JS的數(shù)據(jù)類型做個較為深入的小結(jié)(2018-10-19)。 雖然JS與其他強類型語言不一樣,聲明中無需預(yù)設(shè)數(shù)據(jù)類型,但是JS也是有數(shù)據(jù)類型區(qū)分的。 基本數(shù)據(jù)類型(...
摘要:前兩天看到大神的關(guān)于基本數(shù)據(jù)類型和引用類型的區(qū)別的文章覺得寫得非常不錯,就想著在其基礎(chǔ)上加上自己平時看到的一些知識點和理解,所以就有了以下的文章基本數(shù)據(jù)類型基本數(shù)據(jù)類型包括基本數(shù)據(jù)類型是按值訪問的,就是說我們可以操作保存在變量中的實際的值基 前兩天看到kraaas大神的關(guān)于基本數(shù)據(jù)類型和引用類型的區(qū)別的文章覺得寫得非常不錯,就想著在其基礎(chǔ)上加上自己平時看到的一些知識點和理解,所以就有了...
摘要:前言中的類型只有種,其中基本數(shù)據(jù)類型有種分別為,引用類型有一種,就是,是一個大的綜合體,在中除了那個基本數(shù)據(jù)類型以外,其他的一切皆對象。 前言 JS中的類型只有6種,其中基本數(shù)據(jù)類型有5種分別為string,number,boolen,null,undefined,引用類型有一種,就是object,object是一個大的綜合體,在JS中除了那5個基本數(shù)據(jù)類型以外,其他的一切皆對象。 正...
摘要:這也解答了我曾經(jīng)的一個疑問同樣的道理,在調(diào)用屬性的瞬間,也是使用先來實例化一個對象,所以那一瞬間他們的構(gòu)造函數(shù)以及原型對象是相同的,但也僅僅是那一瞬間。 經(jīng)常在國內(nèi)的各大網(wǎng)站博客上看到一句話,叫做JS中萬物皆對象,那是否真是如此? 那么,我們先來捋一捋JS中的數(shù)據(jù)類型,JS中的數(shù)據(jù)類型有下面幾種 Undefined Null Boolean Number String Symbol ...
摘要:中的數(shù)據(jù)類型變量包含兩種不同的數(shù)據(jù)類型的值基本類型值和引用類型值。對于引用類型返回均為使用檢測引用型數(shù)據(jù)類型時的最佳選擇是因為根據(jù)規(guī)定,所用引用類型的值都是的實例,因此都是返回引用類型與基本包裝類型的主要區(qū)別就是對象的生存期。 javaScript中的數(shù)據(jù)類型 ECMAScript 變量包含兩種不同的數(shù)據(jù)類型的值:基本類型值和引用類型值 。 基本數(shù)據(jù)類型指的是簡單的數(shù)據(jù)段,而引用數(shù)據(jù)類...
閱讀 3338·2021-11-16 11:45
閱讀 4412·2021-09-22 15:38
閱讀 2857·2021-09-22 15:26
閱讀 3366·2021-09-01 10:48
閱讀 875·2019-08-30 15:56
閱讀 730·2019-08-29 13:58
閱讀 1500·2019-08-28 18:00
閱讀 2181·2019-08-27 10:53