1.引用类型有哪些?非引用类型有哪些
非引用类型它们都是保持在栈内存中的简单数据。变量中直接存值
string boolean number null undefined
引用类型 变量中通常存储一个地址(指针),指向的实际内容在堆内存中
function Arry object 正则
2.如下代码输出什么?为什么
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);false //因为obj1和obj2两个变量保存的储存地址,分别指向两个不同的堆内存空间
console.log(obj1 = obj2); {a:1,b:2} //此处是赋值将obj2的指针地址赋给了变量obj1
console.log(obj1 == obj2);true //经过赋值操作后obj1和obj2存储的地址相同,都指向同一处堆内存空间
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) //1
//输出1将a的值复制一份传递给aa 值传递
console.log(bb) //2
非引用类型来说 var bb = b将b值复制一份给bb
对于引用类型来说,cc = c是指针的拷贝,它们指向了同一块堆内存。 c.name = 'hello'就是改变了这一款堆内存中的内容。所以
对于引用类型来说,dd = d是指针的拷贝,它们指向了同一块堆内存。 d[2]['age'] = 3就是改变了这一款堆内存中的内容。
console.log(cc)//{name: "hello", age: 3}
console.log(dd) // [1, 2, {name: "hello", age: 3}]
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)
当调用f1(a)在f1函数内部,隐式声明了var n =a;将a的值复制一份给了n所以当n自增变为2时时a的值不会变为1
当调用f2(c)在f1函数内部,首先隐形声明var obj = c;把c的指针的值给了obj,obj和c指向的堆内存是同一个,所以函数内部操作++obj.age实际是改变了同一个堆内存中的内容 age变为3
当调用f1(c.age) 在f1函数内部,隐式声明了 var n = c.age ;把c.age的值,(拷贝一份赋给)传递给了n
所以当n自增变为4时,c.age的值是不变的仍为3
5.过滤如下数组,只保留正数,直接在原数组上操作
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); //当有一个数被删除时,下一个数的index就变成了现在的这个值。如果继续循环就会错过下一个元素
i--;
}
}
}
filter(arr)
console.log(arr) // [3,1,2]
6.过滤如下数组,只保留正数,原数组不变,生成新数组
方法一:
var arr = [3,1,0,-1,-3,2,-5];
function filterArry(arr){
var newArry = [];
for(var i = 0; i < arr.length; i++){
if(arr[i] > 0){
newArry.push(arr[i])
}
}
return newArry
}
filterArry(arr)
方法二:
var a = [3,1,0,-1,-3,2,-5];
function filterArry(arr){
return arr.filter(function (elem) { //数组的filter方法会创建一个包含所有通过测试的元素的新数组
return (elem > 0);
})
}
filterArry(a);
7.写一个深拷贝函数,用两种方式实现
浅拷贝示例:
var obj = {
name:'luoqian',
friend:{
name:'pangzi',
sex:'male'
}
}
function copyObject(obj){
var newObj = {};
for(key in obj){
newObj[key] = obj[key]
}
return newObj
}
obj2 = copyObject(obj)
obj2 = copyObject(obj)
obj.friends.newfriends.age = 30;
console.log(obj2)
//对原对象obj进行操作,obj2还是30 内嵌的函数 还是引用类型的赋值
//----------------------------
深拷贝示例
function copyObject(obj){
var newObj = {};
if(obj.hasOwnProperty){
for(key in obj){
if(obj[key] == 'number' || typeof obj[key] == 'string' || typeof obj[key] == 'boolean' || obj[key] == null || obj[key] == undefined ){
newObj[key] = obj[key]
}else{
newObj[key] = copyObject(obj[key])
}
}
}
return newObj
}
obj2 = copyObject(obj)
obj.friends.newfriends.age = 30;
console.log(obj2)
//此时对obj1操作,对obj2的影响是不变的完全拷贝了过来
function deepCopy(obj){
var newObject = {};
var content = JSON.stringify(obj);//失去对象的意义了,例如一个人很多细胞组成
newObject = JSON.parse(content)//重新组合就会变成另外一个人了
return newObject
}