1.引用类型有哪些?非引用类型有哪些
- 基本类型值(数值、布尔值、null和undefined):指的是保存在栈内存中的简单数据段;
- 引用类型值(对象、数组、函数、正则):指的是那些保存在堆内存中的对象,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象。
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);
console.log(obj1 == obj2);
输出false,因为两个引用类型的值虽然内容一样但指向不同的对象,指针不相等。
console.log(obj1 = obj2);
输出[object Object] { a: 1, b: 2},相当于把obj2的指针赋值给obj1,再输出指针指向的对象。
console.log(obj1 == obj2);
输出true,由于上句中已经把obj2的指针赋值给obj1,故此时两者指向同一位置,指针相同,故输出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)
console.log(aa)
输出1,因为a把它的值1赋给了aa,aa是基本类型值不随a的值变化而变化。
console.log(bb)
输出2,理由同上。
console.log(cc)
输出[object Object] { name: 'hello', age: 3 },因为c是引用类型值,c与cc指向同一个值,c变化了cc跟着变化。
同时c还是数组d中的一项,d[2]['age']与c.age指向同一个值。故d的变化能反映到cc上。
console.log(dd)
输出[1,2,[object Object] { 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)
console.log(a)
输出1,基本类型值不会因传参而发生改变。
console.log(c)
输出[object Object] { name: 'jirengu', age: 3 }。
引用类型值c传参把地址传入函数f2,f2修改了该地址上的age值,故c的值也发生改变。但f1函数传入的是基本类型值,不会影响c原本的值。
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);
i--;
}
}
}
filter(arr);
console.log(arr); // [3,1,2]
6.过滤如下数组,只保留正数,原数组不变,生成新数组
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); // [3,1,2]
console.log(arr); // [3,1,0,-1,-2,2,-5]
7.写一个深拷贝函数,用两种方式实现
递归方法:
var aaa = {
name: 'franky',
age: 100,
sex: 'male',
friend: {
name: 'xxx',
age: 25,
sex: 'female'
}
};
function copy(obj){
//新建一个对象
var newObj={};
//遍历传入对象属性
for(var key in obj){
// 判断传入对象实例中是否有该属性
if(obj.hasOwnProperty(key)){
// 判断属性是不是基本类型
if(typeof obj[key] === 'number' ||
typeof obj[key] === 'string'||
typeof obj[key] === 'boolean' ||
obj[key] === undefined||
obj[key] === null){
// 把基本类型值赋值给新对象
newObj[key] = obj[key];
}
// 引用类型的值通过递归再次执行一次copy函数
else{
newObj[key] = copy(obj[key]);
}
}
}
return newObj;
}
var bbb = copy(aaa);
console.log(bbb);
JSON方法:
var aaa = {
name: 'franky',
age: 100,
sex: 'male',
friend: {
name: 'xxx',
age: 25,
sex: 'female'
}
};
JSON.stringify(aaa);
var bbb = JSON.parse(JSON.stringify(aaa));
console.log(bbb);