1.javascript引用類型有哪些?非引用類型有哪些?
引用類型:對(duì)象白华、數(shù)組、函數(shù)贩耐、正則表達(dá)式弧腥,指保存在堆內(nèi)存中的對(duì)象,變量中保存的實(shí)際上是一個(gè)指針潮太,這個(gè)指針指向內(nèi)存中的另一個(gè)位置管搪,由該位置保存對(duì)象。
非引用類型: 數(shù)值铡买、布爾更鲁、字符串、null寻狂、undefined岁经,這些是基本類型朋沮,指的事保存在棧內(nèi)存中的簡(jiǎn)單數(shù)據(jù)段蛇券。
2.如下代碼輸出什么?為什么?
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);//輸出false 因?yàn)閛bj1和obj2指向不同的地址
console.log(obj1 = obj2);//輸出{a:1,b:2} obj1 = obj2賦值操作樊拓,
也就是obj2將儲(chǔ)存在變量對(duì)象中的值(即指向?qū)ο笪恢玫闹羔槪?fù)制了一份放到obj1的內(nèi)存空間中纠亚,這時(shí)obj1和obj2都指向堆內(nèi)存里的同一個(gè)對(duì)象
console.log(obj1 == obj2);//輸出true 因?yàn)樯弦徊降牟僮鱫bj1和obj2指向了同一個(gè)地址
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//復(fù)制的是指針
var dd = d//復(fù)制的是指針
a = 11
b = 22
c.name = 'hello'
d[2]['age'] = 3
console.log(aa) //輸出1, a為基本類型值,var aa=a只是將a的值賦給1,a和aa指向不同的棧內(nèi)存位置,互不影響
console.log(bb) //輸出2, 同上
console.log(cc) //輸出{name:'hello', age: 3},c為引用類型值,var cc = c是將c指向堆內(nèi)存的指針復(fù)制給cc,所以cc和c引用的是同一個(gè)對(duì)象,
對(duì)象c.name='hello',name改變,所以cc同樣改變, d[2]['age'] = 3同樣age也變?yōu)?
console.log(dd) //輸出[1,2,{name: 'hello', age: 3}], d為引用類型值,var dd=d是指d指向堆內(nèi)存的指針復(fù)制給dd,a和b是基本類型值按值傳遞,d引用類型的值改變,dd也相應(yīng)改變.
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) // 輸出1, 因?yàn)閒1(a)想當(dāng)于聲明了一個(gè)var n=a,把a(bǔ)的值1賦給了n,++n將n值加1,
它們?cè)诓煌臈?nèi)存位置中互不影響,所以a值不改變,最后輸出1
console.log(c)//輸出{ name: 'jirengu', age:3 } f2(c)相當(dāng)于在f2(obj)中聲明一個(gè) var obj=c,將c的指向堆內(nèi)存的指針復(fù)制給obj,
++obj.age,age加1,同樣改變了c.age為3
5.過濾如下數(shù)組筋夏,只保留正數(shù)蒂胞,直接在原數(shù)組上操作
var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
}
filter(arr)
console.log(arr) // [3,1,2]
如下:
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);//從第i個(gè)開始,刪除個(gè)數(shù)為1,即刪除數(shù)組第i個(gè)元素
i--//刪除之后數(shù)組長(zhǎng)度縮減 ,原位置的元素被新元素代替所以需減1
}
}
return arr
}
console.log(arr) // [3,1,2]
6.過濾如下數(shù)組,只保留正數(shù)条篷,原數(shù)組不變骗随,生成新數(shù)組
var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
}
var arr2 = filter(arr)
console.log(arr2) // [3,1,2]
console.log(arr) // [3,1,0,-1,-3,2,-5]
如下:
var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
var arr2=[]// 將[]的指向堆內(nèi)存的指針復(fù)制給arr2,這個(gè)堆內(nèi)存的位置與arr指向的堆內(nèi)存不一樣
for(var i=0;i<arr.length;i++){
arr2[i] =arr[i]
}
for(var i =0; i<arr.length;i++){
if(arr2[i]<=0){
arr2.splice(i,1)
i--
}
}
return arr2
}
var arr2 = filter(arr)
console.log(arr2) // [3,1,2]
console.log(arr) // [3,1,0,-1,-3,2,-5]
7.寫一個(gè)深拷貝函數(shù)蛤织,用兩種方式實(shí)現(xiàn)
深拷貝:在對(duì)含有指針成員的對(duì)象進(jìn)行拷貝時(shí),必須要自己定義拷貝構(gòu)造函數(shù)鸿染,使拷貝后的對(duì)象指針成員有自己的內(nèi)存空間指蚜,即進(jìn)行深拷貝
- 方法1:
var obj={
name:'fang',
friend:{
name:'haha',
age:18,
sex:'female'
}
}
function copy(obj){
var newObj={}
for(var key in obj){
if(obj.hasOwnProperty(key)){
if(typeof obj[key]==='number'||typeof obj[key]==='boolean'||typeof obj[key]==='string'||obj[key]===undefined
||obj[key]===null){
newObj[key]=obj[key]
}else{
newObj[key]=copy(obj[key])
}
}
}
return newObj
}
var obj2= copy(obj)
console.log(obj2)
- 方法2:
function copy(obj){
var newObj=JSON.parse(JSON.stringify(obj))// JSON.stringify(obj)把對(duì)象轉(zhuǎn)化為字符串,
JSON.parse(JSON.stringify(obj))把字符串重新生成一個(gè)對(duì)象
return newObj
}
var obj2= copy(obj)
console.log(obj2)