引用类型有哪些?非引用类型有哪些?
- 引用类型是指那些保存在堆内存中的对象。变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,由该位置保存对象。
- 引用类型有:对象、函数、数组、正则表达式
- 非引用类型有: string,number,boolean,undefined和null
如下代码输出什么?为什么?
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);// false,因为对象是引用类型,他们的变量保存的只是存储着相同对象的地址,这个地址是不相同的
console.log(obj1 = obj2);//返回{a:1,b:2},相当于将obj2的指针传递给obj1,obj1也指向了obj2的堆内存空间
console.log(obj1 == obj2);// 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
var dd = d
a = 11
b = 22
c.name = 'hello'
d[2]['age'] = 3
console.log(aa) //1,aa会开辟自己的栈空间
console.log(bb) //2,bb会开启自己的栈空间
console.log(cc) //{name:'hello',age: 2}对象c和cc都是引用类型,他们的指针指向同一个堆内存空间,改变其中任何一个都会改变他们共享的堆内存空间。
console.log(dd) //{1,2,{name:'hello',age:3}}跟上述的回答相同
如下代码输出什么? 为什么
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,因为a是原始类型,改变n的值不会影响到a
console.log(c) //输出{name:'jirengu',age:3},因为f2(c)的执行,会使obj中的age自增1变为3,f1(c.age)不影响obj中的age,因为它只是把obj中的值传给了参数,这个值是原始类型。
其实最简单的判断方法就是观察传递给函数的参数是原始类型还是引用类型,
如果是原始类型,那么不会影响到原来的原始类型,如果是引用类型,那么原来的引用类型里的值也会改变。
过滤如下数组,只保留正数,直接在原数组上操作
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--;
}
}
return arr;
}
filter(arr)
console.log(arr) // [3,1,2]
过滤如下数组,只保留正数,原数组不变,生成新数组
var arr = [3,1,0,-1,-3,2,-5]
function filter(arr){
var arr2 = [];
for(var i = 0;i<arr.length;i++){
if(arr[i]>0){
arr2.push(arr[i])
}
}
return arr2
}
var arr2 = filter(arr)
console.log(arr2) // [3,1,2]
console.log(arr) // [3,1,0,-1,-2,2,-5]
写一个深拷贝函数,用两种方式实现
第一种
function deepCopy(obj){
var obj1={}
for(var i in obj){
if(obj.hasOwnProperty(i)){
if(typeof obj[i]==="number"||"boolean"||"string"|| undefined || null){
obj1[i]=obj[i];
}
else{
obj1[i]=deepCopy(obj[i]);
}
}
}
return obj1;
}
第二种
function(obj){
var objCopy=JSON.parse(stringify(obj));
return objCopy;
}