一、浮点精度问题
0.1+0.2=0.30000000000000004
0.1+0.7=0.7999999999999999
0.2+0.4=0.6000000000000001
0.3-0.2=0.09999999999999998
1.5-1.2=0.30000000000000004
35.41*100=3540.9999999999995
19.9*100=1989.9999999999998
1、产生原因
js数值型产生包含整数、浮点,---Number 统一按64位计算
最高位--符号位 存储指数 尾数位--超出部分自动舍弃
1 11位 52位
0.1 0.000 1100 1100.....(1100的循环)
0.2 0.0011 0011 0011.....(0011的循环)
0.1+0.2 相加有,多余部分被舍掉,产生误差
2、解决办法
0.1+0.2=0.3
(1)×10再计算
console.log((0.1*10+0.2*10)/10)
(2)toFixed()截取位数,四舍五入
a=0.1+0.2
a.toFixed(1) 0.3
1.35.toFixed(1) 1.4
1.335.toFixed(2) 1.33
1.3335.toFixed(3) 1.333
toFixed优化
Number.prototype.mytoFixed=function(){
}
二、包装类型
包装类型(引用类型之一):Number Boolean String 用new形式搭建
基本数据类型:string(s1="hello)
1、包装类型中的String
(1)new String() new创建
(2)typeOf 返回object
(3)s2=new String(1,2,3,4)当有多个参数时,只处理第一个
(4)s1=new String(++n,n++,++n)当
s1="hello" 后台操作:s1=new String("hello")
s2=s1.sbuString(2) s2=s1.sbuString(2)
s1=null 销毁
s3="hello"
s4=new String("hello")
2、包装类型Boolean
v1=false
v2=v1&&true false
v1=new Boolean//false
任何object对象转化为boolean都为true
v2=v1&&true//true
(1)
v3=false
v4=new Boolean(false)
typeOf(v3) 基本数据类型:Boolean
typeOf(v4) object
(2)
instanceof 判断是否为对象实例
v3 instanceof Boolean false
v4 instanceof Boolean true
3、包装类型Number
v1=23
v2=new Number(23)
typeOf(v1) number
typeOf(v2) object
v1 instanceof Number ture
v2 instanceof Number false
三、值类型与引用类型
1、值类型传递采用基础数据类型, String Number Boolean null undefined
存储在栈内存中
占据空间是固定的
2、引用类型采用地址传递, array function object
堆中存储的一般都是对象,通过一个地址编号(引用指针)传递给栈内存的变量
读取数据--由引用指针(地址编号)到堆内存中找数据块
占据空间是不固定的
值传递:
var a=2
function f1(x){
x=4
}
f1(a)
alert(a) //2
引用类型传递:
a1=[1,2,3]
function f1(x){
x[0]=50
}
f1(a1)
alert(a1[0])//引用类型---地址传递
3、拆箱与装箱
装箱:将值类型包装为对应的引用类型对象
var a=12
b=new Number(12) 装箱
拆箱:引用类型-->值类型 valueOf()
c=new Number()
var b=c.valueOf()
typeOf(d) number
四、深拷贝与浅拷贝
深浅拷贝针对的都是引用类型
1、浅拷贝:拷贝基本数据类型不会受到影响
拷贝基本引用类型源对象会被修改
仅拷贝对象地址
白话文:b复制啊,改a,b变
a1=[1,2,3]
a2=a1
console.log(a1,a2)
a1.push(4)
console.log(a1,a2)
2、深拷贝
拷贝一个对象的数据之前,先给拷贝对象创建一个堆地址,当拷贝的对象指向的堆里的对象时,被拷贝的对象堆中的数据不会改变
白话文:b复制a,改a,b不变
实现深拷贝方法:
(1)、创建新数组,for循环复制
a1=[1,2,3]
a2=[]
for(var i in a1){
a2.push(a1[i])
}
a1.push(4)
console.log(a1,a2)//a1变为[1,2,3,4],a2仍是[1,2,3]
(2)、数组方法slice
ar arr1 = ["1","2","3"];
var arr2 = arr1.slice(0);
arr2[1] = "9";
console.log("数组的原始值:" + arr1 );
console.log("数组的新值:" + arr2 );
过JS的slice方法,改变拷贝出来的数组的某项值后,对原来数组没有任何影响。
(3)、数组方法concat
var arr1 = ["1","2","3"];
var arr2 = arr1.concat();
arr2[1] = "9";
console.log("数组的原始值:" + arr1 );
console.log("数组的新值:" + arr2 );
通过JS的concat方法,改变拷贝出来的数组的某项值后,对原来数组没有任何影响。
(4)、Json.parse(JSON.Stringify)
1、var arr1 = ["1","2","3"];
var arr2 = JSON.parse(JSON.stringify(arr1));
arr1.push(4)
2、 var test={
a:"ss",
b:"dd"
};
var test1 = JSON.parse(JSON.stringify(test));
test.a="cc"
console.log(test);
console.log(test1);
3、 var test={
name:"hyw",
age:23 ,
friends:["dwz1","dwz2","dwz3"]
};
var test1 = JSON.parse(JSON.stringify(test));//拷贝数组,注意这行的拷贝方法
test.friends[0]="dwz4"
console.log(test);
console.log(test1);
3、手动封装深浅拷贝
copyfun(对象,true) true--深拷贝 false--浅拷贝
return 拷贝后的对象
a1 =[1,2,3]
a2=copyfun(a1,false) a1变,a2变
a3=copyfun(a1,true) a1变,a3不变
typeof(obj) --object
a1 instancOf Array
Object.prototype.copyfun=function (a,b){
if(typeof(a)=="object"){
if(b==true){
return a2=JSON.parse(JSON.stringify(this))
}else{
return a3=a
}
}else{
return a1=a
}
}
var f1=([1,2,3])
f2=f1.copyfun(f1,false)
f1.push(4)
console.log(f1,f2)