引用類型有哪些猿棉?非引用類型有哪些
引用類型:
Object、Array屑咳、Date萨赁、RegExp、Function兆龙、Math杖爽、Global、Error紫皇,指的是保存在堆內(nèi)存中的對象慰安。當(dāng)復(fù)制保存對象的某個變量時操作的是對象的引用,也就是指向該對象在內(nèi)存中所在位置的指針聪铺,為對象添加屬性時操作的是實際的對象化焕,引用類型的值按引用訪問。三個特殊的引用類型:
Boolean铃剔、Number撒桨、String:也叫基本包裝類型,每當(dāng)讀取一個基本類型值時键兜,后臺會創(chuàng)建一個對應(yīng)的基本包裝類型的對象元莫,從而讓我們能調(diào)用一些方法來操作這些數(shù)據(jù)。
不建議顯式地創(chuàng)造基本包裝類型對象蝶押。基本類型(非引用類型):
string、boolean火欧、null棋电、undefined、number苇侵、symbol赶盔,這六種基本類型指的是保存在棧內(nèi)存中的簡單數(shù)據(jù)段,基本類型的值按值訪問榆浓。
如下代碼輸出什么于未?為什么
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2); //false 原因:變量obj1和obj2中保存的是指向?qū)ο笤趦?nèi)存中位置的指針,也就是說obj1和obj2引用的是堆內(nèi)不同的兩個對象,所以不相等烘浦,返回false
console.log(obj1 = obj2); //{a:1,b:2} 原因:賦值操作抖坪,也就是obj2將儲存在變量對象中的值(即指向?qū)ο笪恢玫闹羔槪?fù)制了一份放到obj1的內(nèi)存空間中,這時obj1和obj2都指向堆內(nèi)的同一個對象
console.log(obj1 == obj2); //true 指向同一個對象了所以再判斷相當(dāng)與否就返回true
如下代碼輸出什么? 為什么
var a = 1
var b = 2
var c = { name: '饑人谷', age: 2 }
var d = [a, b, c]
var aa = a
var bb = b
var cc = c //復(fù)制指針
var dd = d //復(fù)制指針
a = 11
b = 22
c.name = 'hello' //改變堆內(nèi)存中c.name值為hello
d[2]['age'] = 3 //改變堆內(nèi)存中c.age值為3
console.log(aa) //1 原因:a是基本類型值闷叉,按值傳遞給aa擦俐,所以aa為1,之后除非顯式地指明aa=11握侧,打印的aa就是11蚯瞧,不然aa得到的就是a的值1,不會再改變品擎。如果把a=11放到var aa=a前面去埋合,打印aa也是11,以下打印bb原理相同所以不作解釋萄传。
console.log(bb) //2 原因:b是基本類型值甚颂,按值傳遞給bb,所以bb為2
console.log(cc) //{name:"hello",age:3} 原因:c是引用類型的值盲再,值按引用訪問西设,首先將變量c指向堆內(nèi)對象位置的指針復(fù)制給了cc,所以cc與c引用的是同一個對象答朋,接著變量c的name屬性值被修改為"hello"贷揽,d[2]['age']=3意為將數(shù)組d中索引為2的項,也就是變量c的age屬性的值修改為3梦碗,由于指針相同禽绪,cc也可以訪問到c的屬性和修改后的值,所以打印cc得到{name:"hello",age:3}
console.log(dd) //[1,2,{name:"hello",age:3}] 原因:d也是引用類型的值洪规,賦值操作后dd和d引用的是內(nèi)存中的同一對象印屁,a和b是基本類型按值傳遞,dd指針指向的內(nèi)存中保存的c的值已經(jīng)改變斩例,使用修改之后的值雄人。
如下代碼輸出什么? 為什么
var a = 1
var c = { name: 'jirengu', age: 2 }
function f1(n){
++n
}
function f2(obj){
++obj.age
}
f1(a)
f2(c)
f1(c.age)
console.log(a) //1 原因:調(diào)用f1(a),實際上是向f1(n)函數(shù)內(nèi)傳遞了一個參數(shù)a念赶,而a是基本類型础钠,值為1,所以實際上f1內(nèi)發(fā)生的是n = a = 1叉谜,所以++n和a沒關(guān)系旗吁,打印出來的a的值沒變化
console.log(c) //{name:"jirengu",age:3} 原因:c是引用類型的值,調(diào)用f2(c)停局,即將變量c指向堆內(nèi)對象位置的指針當(dāng)作參數(shù)傳遞給函數(shù)f2(obj)很钓,實際上在f2內(nèi)發(fā)生的是obj=c={name:"jirengu",age:2}香府,這兩個變量就指向同一內(nèi)存,接著執(zhí)行++c.age码倦,即++2企孩,執(zhí)行完畢后age值變?yōu)?,所以obj{name:"jirengu",age:3}叹洲,obj和c引用的是同一對象所以c可以訪問到修改后的值柠硕,所以打印c得到和obj相同的結(jié)果{name:"jirengu",age:3}
過濾如下數(shù)組,只保留正數(shù)运提,直接在原數(shù)組上操作
function filter(array) {
for (var i = 0; i < array.length; i++) {
if (array[i] <= 0) {
array.splice(i, 1)//刪除數(shù)組第I項位置的值
i-- //每刪除一項蝗柔,數(shù)組長度就減1,所以為了得到正確的結(jié)果必須加上i--
}
}
return array
}
var array = [3, 1, 0, -1, -3, 2, -5]
console.log(filter(array))//[3,1,2]
過濾如下數(shù)組民泵,只保留正數(shù)癣丧,原數(shù)組不變,生成新數(shù)組
function filter(array) {
var res = []
array.forEach(function (element) {
if (element > 0) res.push(element)
}, this);
return res
}
var array = [3, 1, 0, -1, -3, 2, -5]
console.log(filter(array))//[3,1,2]
console.log(array)//[3, 1, 0, -1, -3, 2, -5]