1.引用類(lèi)型有哪些?非引用類(lèi)型有哪些
非引用類(lèi)型值笑陈,即基本類(lèi)型值(數(shù)值际度,布爾值,undefined涵妥,null):指保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段甲脏。
引用類(lèi)型值(對(duì)象,數(shù)組,函數(shù)块请,正則):值保存在堆內(nèi)存中的對(duì)象娜氏;變量實(shí)際保存的是一個(gè)指針,這個(gè)指針是用來(lái)指向另一個(gè)位置墩新,該位置用來(lái)保存對(duì)象贸弥。
2.如下代碼輸出什么?為什么
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);
console.log(obj1 = obj2);
console.log(obj1 == obj2);
結(jié)果:false ; object {a:1,b:2} ; true
obj1 == obj2是判斷兩個(gè)變量是否相等海渊;由于對(duì)對(duì)象聲明變量绵疲,變量實(shí)際保存的是對(duì)象在內(nèi)存中的位置的指針;所以是聲明的是兩個(gè)指針臣疑,故不相等盔憨。
obj1 = obj2;是把obj2的指針賦值給obj1讯沈,同時(shí)郁岩,他們指向同一塊內(nèi)存。所以缺狠,輸出obj1的值就是obj2的對(duì)象问慎。
之前由于obj1 = obj2,把obj2的指針賦值給obj1挤茄,所以他們是相等的如叼,結(jié)果為true。
3.如下代碼輸出什么? 為什么
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
var dd = d`
a = 11
b = 22
c.name = 'hello
d[2]['age'] = 3
console.log(aa)
console.log(bb)
console.log(cc)
console.log(dd)
結(jié)果:
aa=1;
因?yàn)閍是基本類(lèi)型值穷劈,在a=11笼恰,之前,a=1的值已經(jīng)賦值給aa歇终。
bb=2;
同理挖腰,b也是基本類(lèi)型值。
cc={name:hello, age:3}练湿;
因?yàn)閏是引用類(lèi)型值猴仑,所以cc=c,是把c的指針賦值給cc肥哎,令這兩個(gè)變量指向同一個(gè)內(nèi)存辽俗。故,對(duì)c的內(nèi)存的值改變篡诽,即會(huì)使cc的值發(fā)生改變崖飘。又由于d[2]['age'] = 3
,即數(shù)組d的第三個(gè)值的age屬性的值變?yōu)?杈女。直接改變的是值朱浴,而不是指針吊圾。
dd = [1, 2, {name: hello , age:3}];
同理翰蠢,dd 是引用類(lèi)型值项乒,由于c.name = 'hello'
和d[2]['age'] = 3
共同改變內(nèi)存中的值。
4.如下代碼輸出什么? 為什么
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)
console.log(c)
結(jié)果:
a=1梁沧;
執(zhí)行函數(shù)f1(a)檀何,在f1(n)函數(shù)中,發(fā)生了廷支,var n = a
频鉴,所以++n實(shí)際上是n=++n,
并沒(méi)有對(duì)a的值做出改變恋拍。故a=1垛孔。
{name:'jirengu',age:3}
施敢;
當(dāng)執(zhí)f2(c)
時(shí)周荐,在f2(obj)
函數(shù)中,發(fā)生了悯姊,var obj=c
,即c變量是把指針賦值給obj了贩毕,令這兩個(gè)變量指向同一個(gè)內(nèi)存悯许。當(dāng)++obj.age
,執(zhí)行的是對(duì)age屬性的值加1辉阶,故變量c的指針指向的內(nèi)存的值發(fā)生改變先壕。
當(dāng)執(zhí)行f1(c.age)
時(shí),在1(n)
函數(shù)中谆甜,發(fā)生了垃僚,var n=c.age
,
5.過(guò)濾如下數(shù)組规辱,只保留正數(shù)谆棺,直接在原數(shù)組上操作
1.利用push() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的末尾,并返回?cái)?shù)組的新長(zhǎng)度罕袋。
var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
var newArr = [];
for(var i=0 ; i<arr.length; i++){
if(arr[i]>0){
newArr.push(arr[i]);
}
}
return newArr;
}
filter(arr);
arr= filter(arr);
console.log(arr) // [3,1,2]
2.利用splice() 方法通過(guò)刪除現(xiàn)有元素來(lái)更改數(shù)組的內(nèi)容改淑。注意,如果添加進(jìn)數(shù)組的元素個(gè)數(shù)不等于被刪除的元素個(gè)數(shù)浴讯,數(shù)組的長(zhǎng)度會(huì)發(fā)生相應(yīng)的改變朵夏。
var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
for(var i=0 ; i<arr.length; i++){
if(arr[i]<=0){
arr.splice(i,1);//添加0個(gè)元素,刪除一個(gè)榆纽,length發(fā)生改變仰猖。
i--;
}
}
return
}
filter(arr)
console.log(arr)
6.過(guò)濾如下數(shù)組捏肢,只保留正數(shù),原數(shù)組不變饥侵,生成新數(shù)組
定義新的數(shù)組鸵赫,就會(huì)有新的指針,遍歷原數(shù)組到新數(shù)組即可爆捞。
var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
var newArr = [];
for(var i=0 ; i<arr.length; i++){
if(arr[i]>0){
newArr.push(arr[i]);
}
}
return newArr;
}
var arr2 = filter(arr)
console.log(arr2)
console.log(arr)
7.寫(xiě)一個(gè)深拷貝函數(shù)奉瘤,用兩種方式實(shí)現(xiàn)
淺拷貝:只拷貝對(duì)象的基本類(lèi)型值,如果某一個(gè)屬性是引用類(lèi)型值煮甥,拷貝的就是這個(gè)引用類(lèi)型的指針盗温。當(dāng)原對(duì)象的引用類(lèi)型值發(fā)生改變,則淺拷貝后的新對(duì)象的引用類(lèi)型值也會(huì)發(fā)生改變成肘,但非引用類(lèi)型值不變卖局。
深拷貝:拷貝對(duì)象的所有屬性,無(wú)論是引用類(lèi)型值還是非引用類(lèi)型值双霍,拷貝之后的新對(duì)象砚偶,與原對(duì)象沒(méi)有任何關(guān)系。
1洒闸、用遞歸實(shí)現(xiàn)深拷貝
var obj = {
name: 'ruoyu',
sex: 'male',
age: 30,
friend: {
name: 'hello',
age: 100
}
};
function deepCopy(oldObj){
var newObj = {};
for(var key in oldObj){
if(typeof oldObj[key]==='number'||typeof oldObj[key]==='string'||
typeof oldObj[key]==='boolean'||oldObj[key]=== 'undefined'
||oldObj[key]=== 'null'){
newObj[key] = oldObj[key] ;
}else
{
newObj[key] = deepCopy(obj[key]);
}
}
return newObj;
}
var obj2 = deepCopy(obj);
obj.friend.age = 10;
console.log(obj2)
其實(shí)是否是深拷貝染坯,還與obj.friend.age = 10;
和var obj2 = deepCopy(obj);
相對(duì)順序有關(guān),如果是
obj.friend.age = 10;
var obj2 = deepCopy(obj);
console.log(obj2)
則對(duì)obj.friend.age
重新賦值丘逸,再執(zhí)行函數(shù)单鹿,則是淺拷貝,實(shí)際運(yùn)用中當(dāng)注意這點(diǎn)深纲。
(typeof oldObj[key]==='number'||typeof oldObj[key]==='string'||
typeof oldObj[key]==='boolean'||oldObj[key]=== 'undefined'
||oldObj[key]=== 'null')
即使引用類(lèi)型值包括函數(shù)仲锄、正則,用這種基本類(lèi)型值判斷湃鹊,同樣可以深拷貝儒喊。
2、
使用JSON
function deepCopy(obj){
var newObj=JSON.stringify(obj)
var newObj1 = JSON.parse(newObj);
return newObj1;
}
注意:
復(fù)合類(lèi)型的值只能是數(shù)組或?qū)ο蟊液牵荒苁呛瘮?shù)怀愧、正則表達(dá)式對(duì)象、日期對(duì)象余赢。
簡(jiǎn)單類(lèi)型的值只有四種:字符串掸驱、數(shù)值(必須以十進(jìn)制表示)、布爾值和null(不能使用NaN, Infinity, -Infinity和undefined)没佑。