重点:两种类型的不同点
1:保存方式不同
A:再将一个值赋给变量时,解析器先要判断这个值是基本类型值还是引用类型值
a:基本数据类型值是按值访问的。它可以操作保存在变量中实际的值
b:引用类型的值报存在内存的对象中。但JavaScript不允许直接访问内存中的位置(不允许直接操作对象的内存空间)。所以操作对象时,实际上实在操控对象的引用而不是实际的对象。*引用类型的值按引用访问的 *(但在为对象添加属性时,操纵的是对象)
B:我们不能给基本类型添加属性(添加了虽然不会导致错误,但访问改属性时会返回undefind).所以我们只能给引用类型动态的添加属性
var person=new Object();
person.name="Letme";
alert(person.name); //"Letme"
var name="Letme";
name.age=27;
alert(name.age); //undefind
2:复制变量的方式不同
A:基本类型复制:(栈内存)
从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。这两个变量可以参与任何操作而不会相互影响。(按值访问 直接复制变量的值)
var a = 1;
var b = a;
a = 2;
console.log(a);//输出2;
console.log(b);//输出1;

从上面例子看出,当一个变量的值是基本类型,把它复制给另一个变量,复制完成后改变它的值,不会影响已经复制了它的值的变量
B:引用类型值是保存在堆内存中的对象,变量保存的只是指向该内存的地址,在复制引用类型值的时候,其实只复制了指向该内存的地址。
var a = { name: 'Kitty', age: '20', sex: 'man' };
var b = a;
a.name = 'Jack';
console.log(a);//输出{name: 'Jack',age: 20,sex: 'man'}
console.log(b);//输出{name: 'Jack',age: 20,sex: 'man'}

注意:如果两个变量的值是引用类型就算两个值是相同的,他们也是不相等的因为他们两个指向的地址是1不同的
var a ={ name:letme; age:21; work:上单 }
var b ={ name:letme; age:21; work:上单 }
a==b //false
3:对象的浅拷贝与深拷贝
当一个变量是对象,如果像上面那样直接将一个变量赋值给另一个变量,如果改变某个变量的值,另外一个变量也会跟着改变,如果我们不想发生这种情况,就需要写一个函数用来拷贝对象。
A:浅拷贝 (适用于对象中只有基本类型的时候)
var a = { name: 'Kitty', age: 12, sex: 'man' }
function copy(obj){
var newObj = {};
for(vl in obj){
newObj[vl] = obj[vl]
}
return newObj;
}
B:深拷贝 (适用于对象中还有对象的时候拷贝的方法)
(递归的方法)
function deepCopy(obj){
var newObj = {};
for(vl in obj){
if(typeof obj[vl] === 'object' && obj[vl] !== null){
newObj[vl] = deepCopy(obj[vl]);
}else{
newObj[vl] = obj[vl]; }
}
return newObj;
}
(2适用json的方法)
JSON.stringify(),将一个对象解析成字符串。
JSON.parse(),从一个字符串中解析出json 对象。
JSON.parsre(JSON.stringify());
4:传递参数
A:当向参数传递一个基本类型的值时,复制变量并将齐作为参数传递给函数。
function addNum(num){
num+=10;
return num;
}
var num=10;
var result=addNum(num);
console.log(num);
console.log(result);
当为函数传递参数的时候,是将此值复制一份传递给函数,所以在函数执行之后,num本身的值并没有被改变,函数中被改变的值仅仅是一个副本而已。
B:当向参数传递一个对象时
5:检测数据类型(4种方法)
**A:typeof() ** 他是检测一个变量是不是基本数据类型的最好的工具
var 姓名="letme"; alert(typeof 姓名);//string
var b=true; alert(typeof b);//boolean
var age=22; alert(typeof age);//number
var c; alert(typeof c);//undefind
var d=null; alert(typeof d);//object
var e =new Object(); alert(typeof e);//object
var f =function(){}; alert(typeof f);//function
var g=new Array(); alert(typeof g); //object
var h=new Date(); alert(typeof h); //object
var i=new RegExp(); alert(typeof i); //object
可以看到,typeof对于基本数据类型判断是没有问题的,但是遇到引用数据类型时是不起作用的(除function类型其余都返回object)。
**B:instanceof **检测引用类型的好方式
var 姓名="letme"; alert(姓名 instanceof String);//false
var b=true; alert(b instanceof Boolean);//false
var age=22; alert(age instanceof Number);//false
var c; alert(c instanceof Undefind);//控制台直接报错
var d=null; alert(d instanceof Null);//控制台直接报错
var e =new Object(); alert(e instanceof Object);//true
var f =function(){}; alert(f instanceof Function);//true
var g=new Array(); alert(g instanceof Array); //true
var h=new Date(); alert(h instanceof Date); //true
var i=new RegExp(); alert(i instanceof RegExp); //true
(1)对于基本类型
(2)对于Null和Undefind;浏览器压根不认识这两货,直接报错。在第一个例子你可能已经发现了,typeof null的结果是object,typeof undefined的结果是undefined
**C:constructor **
var 姓名="letme"; alert((姓名).constructor===String); //true
var b=true; alert((b).constructor===Boolean);//true
var age=22; alert((age).constructor===Number);//true
var c;//报错
var d=null;//报错
var e =new Object();alert((e).constructor===Object);//true
var f =function(){};alert((f).constructor===Function);//true
var g=new Array();alert((g).constructor===Array);//true
var h=new Date();alert((h).constructor===Date);//true
var i=new RegExp();alert((i).constructor===RegExp);//true
看上去除了null与undefind不符合该检测方法,其他好像都符合。其实不然
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn);//flase
console.log(f.constructor===Array);//true
声明一个造函数,并且把他的原型指向了Array的原型,所以这种情况下,constructor也显得力不从心了。
D:Object.prototype.toString.call()
上述所有情况全都符合
1:基本类型
A:Undefined
B:Null
C:Boolean
D:String
E:Number
F:symbol
2:引用类型
A:object类型
B:Array类型
C:Date类型
D:RegExp类型
E:Function类型