掌握ECMAScript数据类型划分;掌握typeof运算符运算规则;掌握强制类型转化规则(parseInt(),parseFloat(),Number(),String(),Boolean())
JS三大核心:
- ECMAScript : js的核心语法,数据类型,运算符,运算过程等。
- DOM:文档对象模型,对页面元素进行的相关操作
- BOM:浏览器对象模型。对浏览器的相关操作
1.数据类型
为什么要划分数据类型(不同类型的数据会有相关的不同特征及不同的操作方法,使用的地方也不一样)
ECMAScript数据类型划分(**):
- 原始类型(基础类型,简单类型):
- Number:数字,可进行运算
- String:字符串,JS中一对引号之间的0到多个字符串
- Boolean:布尔值(true,false),可作为判断条件等
- null:空值,获取不到元素时就会返回null。对空值进行任何属性操作都会报错
- undefined:未定义,声明了变量但是未赋值
- symbol:ES6新增类型,代表唯一值
- 复合类型(复杂类型):
- Object对象:Array数组,function函数,element元素,elements元素组,obj { key:val,key1:val1 }对象。对象可以存储任意、多种类型的值。
注:json本身是字符串,json不是对象,只是对象格式的字符串
对象写法:obj{
key: 'val',
key1:val1
}
对象获取:obj.key
注意:
- 定义时值必须使用引号引起来,如果是数字,如年龄就不需要引号。
- 将对象转为JSON使用JSON.stringify(obj)方法
var obj = {
name : 'lmf',
age : 26
};
console.info(obj.name+"年龄为:"+obj.age);//lmf年龄为:26
console.info(JSON.stringify(obj));//将对象转为字符串 {"name":"lmf","age":26}
2.typeof 运算符
typeof运算符的六类数据类型:number、string、boolean、function、undefined、symbol、object
作用:用于检测数据的类型(注意:typeof检测的结果和标准规定略有差异)
用法:typeof使用时不需要括号,typeof (nub);是为了提升运算优先级,而不是typeof本身有括号
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>typeof运算符</title>
</head>
<body>
<div class="boxs"></div>
<div class="ele"></div>
<script>
// typeof运算符用于检测数据的类型(注意:typeof的检测结果和标准规定略有差异)
var num = 100;
console.log("num的类型是:"+typeof num);//Number 数字
var str = 'abc';
console.log("str的类型是:"+typeof str);//String 字符串
var b = true;
console.log("b的类型是:"+typeof b);//Boolean 布尔值
var a;
console.log("a的类型是:"+typeof a);//undefined 未定义(定义了未赋值)
var s = Symbol();
console.log("s的类型是:"+typeof s);//Symbol 唯一值
var obj = {};
console.log("obj对象的类型是:"+typeof obj);//Object对象:object对象
var arr = ['a','b'];
console.log("arr数组的类型是:"+typeof arr);//Object对象:数组
var ele = document.querySelector(".ele");
console.log("ele一个元素的类型是:"+typeof arr);//Object对象:一个元素
var boxs = document.querySelectorAll(".boxs");
console.log("boxs一组元素的类型是:"+typeof boxs);//Object对象:一组元素
//typeof检测的数据类型和标准规定的差异
console.log("---------------typeof检测的数据类型和标准规定的差异--------------");
var box = document.querySelector(".box");
console.log("没有box元素时的类型是:"+typeof box);//Object:标准定义中获取不到元素属于null类型,但是typeof是object类型
var func = function (){};
console.log("func函数的类型是:"+typeof func);//function:标准定义中函数时Object对象类型,但typeof是function类型
</script>
</body>
</html>
typeof检测的结果和标准规定差异:
- 标准定义中获取不到元素属于null类型,但是typeof是object类型
- 标准定义中函数是Object对象类型,但typeof是function类型
结果:
3.typeof案例
点击div让整个div往后移100px
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>typeof 小例子</title>
</head>
<body>
<div class="box" style="width: 100px; height: 100px; background: red; position: absolute; left:0; top:0; transition: .5s;"></div>
<script>
//每次点击div,整个div往右移动100px(将div的left+100)
var box = document.querySelector("div");
//元素的with必须通过元素.offsetWidth进行获取,直接使用元素.style.width是获取不到的
// var w = box.offsetWidth;
box.onclick = function(){
//如果样式写在style标签中,或者css样式文件中,是不能通过style.left获取到的
var l = this.style.left;
console.log(typeof l);//String
console.log(typeof parseInt(l));
//需要将其转为Number才能进行计算
this.style.left = parseInt(l) + 100 + 'px';
};
</script>
</body>
</html>
结果:通过元素获取到的值都是字符串,必须转换为Number才能进行计算
4.数据类型转换:把一种类型的数据,转换成另一种
数据转换为数字:parseInt(),parseFloat(),Number()
4.1Number parseInt(data[,radix]):
- 返回值为Number 方法名(参数1[,可选参数2]),此处可选参数为进制。将数据转换成一个整数,数据类型是数字,data为要转换或者取整的数据;可选参数:radix data的进制;返回值为取整之后的结果
parseInt(data, radix) 将数据转换为整数返回(直接去掉小数点,不进行四舍五入):
- 第一个参数接受的是个字符串也就是我们要转换的数据
- 第二个参数 基数,也可以理解为 标注出我们要转换的这个字符串是几进制的数字
parseInt转换规律:
- 从左向右一位一位进行转换,遇到非数字就停止,然后将之前的数字提取出来,转换成数字;
- 如果从0位开始就不是数字,返回NaN(Not a numer这不是一个数字)
- 进制转换:0x是十六进制的标识,0-f。parseInt进行进制转换,不能定义转换成几进制,只是告诉parseInt方法定义的数据是几进制
- parseInt如果接收的是一个数字类型的数据,就只做取整,不去做进制转换
- parseInt转换的是其他类型的数据(字符串以外类型),会先转换成字符串,再执行parseInt。数组:直接去掉[],如果是空数组直接返回NaN,如果数组第一位不是合法数字也返回NaN
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>parseInt()测试</title>
</head>
<body>
<script>
//parseInt从左向右一位一位进行转换,遇到非数字就停止,然后把之前的数字提取出来,转成一个完成的数字
var str = "10.1";
console.log("10.1在 parseInt后的结果为:"+parseInt(str)); //10
//遇到非数字就停止,然后把之前的数字提取出来,转成一个完成的数字
var str1 = "111abc";
console.log("111abc在 parseInt后的结果为:"+parseInt(str1));//111
//parseInt如果从第0位开始就不是数字,就直接返回NaN(不是一个数字)
var str2 = "abc11";
console.log("abc11在 parseInt后的结果为:"+parseInt(str2));//NaN
//parseInt进行进制转换,不能定义转换成几机制,只是告诉parseInt方法定义的数据是几进制
//如此处,0xf是16进制,第二个参数只能写16(用于告诉parseInt方法定义的数据是几进制),写成其他的进制,都会返回0
var str3 = "0xf";
console.log("0xf在 parseInt后的结果为:"+parseInt(str3));//15
//parseInt如果接受的是一个数字类型的数据,就只做取整,不去做进制转换
var str4 = 0xf;
console.log("0xf直接是数字类型时,在 parseInt转换后的结果为:"+parseInt(str4));//15
//parseInt如果接收的是其他类型的数据(字符串以外类型),会先转换成字符串,再执行parseInt。
//如果是数组,会直接去掉[],返回里面的数据;如果是空数组[],返回NaN;如果数组的第一位就不是合法数字,['a','1'],返回NaN
var arr1 = ['1','1'];
console.log("数组['1','1']parseInt后返回的数据为:"+parseInt(arr1));
//如果是空数组[],返回NaN
var arr2 = [];
console.log("空数组[]parseInt后返回的数据为:"+parseInt(arr2));
//如果数组的第一位就不是合法数字,['a','1'],返回NaN
var arr3 = [];
console.log("数组的第一位就不是合法数字,['a','1']parseInt后返回的数据为:"+parseInt(arr3));
</script>
</body>
</html>
结果:
4.2parseFloat():parseFloat(string) 转换成浮点数(也就是小数)
- 转换规则参考parseInt(),比parseInt()可以多转换一个小数点,如果有多个小数点也只会转一位,parseFloat()不能进行精度计算(保留所有位数的小数,不进行四舍五入);
- parseFloat()不能转进制(因为小数不能进行进制转换);
- JS中小数的计算会有精度问题,需要使用toFixed(位数)方法进行解决,toFixed方法会进行四舍五入;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>parseFloat()测试</title>
</head>
<body>
<script>
// 转换规则参考parseInt(),比parseInt()可以多转换一个小数点,如果有多个小数点也只会转一位,parseFloat()不能进行精度计算(保留小数);
var num1 = "10.0092";
console.log("10.0092进行parseFloat()后的数据为:"+parseFloat(num1));//10.0092
//如果有多个小数点也只会转一位
var num2 = "10.009.3452";
console.log("10.009.3452进行parseFloat()后的数据为:"+parseFloat(num2));//10.009
// parseFloat()不能转进制(因为小数不能进行进制转换);
// JS中小数的计算会有精度问题,需要使用toFixed(位数)方法进行解决;
var a = "0.1";
var b = "0.2";
console.log("a*b为:"+parseFloat(a*b));//0.020000000000000004
console.log("a*b toFixed后为:"+parseFloat(a*b).toFixed(2));//0.020000000000000004 toFixed方法会进行四舍五入
// 小数不能进行进制转换
</script>
</body>
</html>
结果:
4.3Number():将数据转换成数字
- - 字符串类型,使用 Number() 转换时,规则如下:
- - 当整段字符串都符合数字规则时,转换为数字返回
- - 空字符串,直接返回 0
- - 其余情况,有一项不为数字,直接返回 NaN
- - 布尔值类型,使用 Number() 转换时,true 返回 1,false 返回 0(除0以外的任何数字都返回true)
- - null,使用 Number() 转换时 返回 0
- - undefined,使用 Number() 转换时 返回 NaN
- - 对象类型,使用 Number() 转换时,调用的对象的toString()方法,然后再依照前面字符串的转换规则进行转换
- -Symbol类型不能使用Number()进行转换,会报错。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Number类型转换</title>
</head>
<body>
<script>
//字符串类型使用Number进行类型转换时:
//1.当整段字符串都符合数字规则时,转换为数字进行返回
var str = "1245";
console.log("字符串类型,1245整个字符串都符合数字规则时,使用Number进行转换后:"+Number(str));//1245
//2.当使用Number()转换空字符串时,直接返回0
var str2 = "";
console.log("使用Number()转换空字符串后:"+Number(str2));//0
//3.其余情况,有一项不为数字,直接返回 NaN
var str3 = "asd22";
console.log("asd22使用Number()转换空字符串后:"+Number(str3));//NaN
var str4 = "33re";
console.log("33re使用Number()转换空字符串后:"+Number(str4));//NaN
var str5 = NaN;
console.log("NaN使用Number()转换空字符串后:"+Number(str5));//NaN
//布尔值类型使用Number进行转换类型时:转换true返回1,转换false返回0(布尔值中,除了0以外的任何数字都是返回1)
var b = true;
console.log("b为true布尔值类型使用Number进行转换类型后:"+Number(b));//1
var b1 = false;
console.log("b1为false布尔值类型使用Number进行转换类型后:"+Number(b1));//0
//null使用Number进行转换类型时,直接返回0
console.log("null使用Number进行类型转换后:"+Number(null));//0
//undefined使用number进行转换类型时,直接返回NaN
console.log("undefined使用Number进行类型转换后:"+Number(undefined));//NaN
//对象类型使用Number进行转换类型时,调用对象的toString()方法,然后再依照字符串的转换规则进行转换
var arr = [];
var arr1 = ['a','b'];
var arr2 = ['1'];
var arr3 = ['1','2'];
console.log("空数组[]进行Number类型转换后:"+Number(arr));//0
console.log("非数字类型数组进行Number类型转换后:"+Number(arr1));//NaN
console.log("数字类型数组(只有一个元素)进行Number类型转换后:"+Number(arr2));//1
console.log("数字类型数组(多个元素)进行Number类型转换后:"+Number(arr3));//1,2 -> NaN
//对象类型函数使用Number进行类型转换时:
var f = function(){};
console.log("对象类型函数f使用Number进行类型转换后:"+Number(f));
//object对象使用Number进行类型转换时:
var obj = { name:'lmf',age:20};
console.log("object对象{ name:'lmf',age:20}使用Number进行类型转换后:"+Number(obj));
//一个元素使用Number进行类型转换时:
var body = document.querySelector("body");
console.log("一个元素document.querySelector('body')使用Number进行类型转换后:"+Number(body));
//一组元素使用Number进行类型转换时:
var bodys = document.querySelectorAll("body");
console.log("一组元素document.querySelectorAll('body')使用Number进行类型转换后:"+Number(bodys));
//Symbol类型不能进行Number类型转换
var s = Symbol();
console.log("Symbol使用Number进行类型转换后:"+Number(s));
</script>
</body>
</html>
结果:
5.NaN和isNaN()
- NaN是Number中的一个特殊值,NaN不是一个数字,但是NaN通过typeof后的数据类型是数字类型Number。
- 使用 NaN 时,要注意 NaN 不等于任何值,包括它自己,也就是 NaN 不等于 NaN。
- isNaN(val)如果val可以转成合法数字,就返回false,如果不能转化为合法数字,返回true;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>NaN理解</title>
</head>
<body>
<script>
//NaN是Number中的一个特殊值,NaN不是一个数字,但是其typeof后的类型是数字(Number)
console.log("NaN通过typeof的数据类型是"+ typeof NaN);//number
//NaN 和 isNaN
// - 在使用 NaN 时,要注意 NaN 不等于任何值,包括它自己,也就是 NaN 不等于 NaN。
var a = NaN;
console.log("检测a是否等于NaN:"+(a == NaN));//false
console.log("检测a是否等于NaN:"+(a === NaN));//false
// - 当我们要检测一条数据是否是 NaN 时,可以使用 isNaN(val) 来进行检测,
//在 isNaN 方法中,传入的数据 能被转换成 合法数字时,就会返回 false,当传入的数据不能被转换成 合法数字( 也就是NaN) 时,isNaN 就会返回 true
var b = "123";
var c = "a123";
var d = "123b";
console.log("123被isNaN检测后:"+isNaN(b));//false
console.log("a123被isNaN检测后:"+isNaN(c));//true
console.log("123b被isNaN检测后:"+isNaN(d));//true
</script>
</body>
</html>
结果:
6.Boolean转换为布尔值
- - 数字类型:非零的合法数字转换为 true, 零代表 false, NaN 代表 false
- - 字符串类型:空字符串转换为false,非空字符串转换为true
- - null:转换为false
- - 对象:转换为true。object空对象,空数组,空函数,空一组元素(未获得一组元素返回NodeList []),空Symbol都为true。但没有获取到一个元素返回的是null,Boolean转换后为false
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Boolean(val)转换成布尔值</title>
</head>
<body>
<script>
// - 数字类型:非零的合法数字转换为 true, 零代表 false, NaN 代表 false
var b = 1;
console.log("1使用Boolean转换类型后为:"+Boolean(b));//true
var b2 = -1;
console.log("-1使用Boolean转换类型后为:"+Boolean(b2));//true
var b3 = 0;
console.log("0使用Boolean转换类型后为:"+Boolean(b3));//false
var b4 = NaN;
console.log("NaN使用Boolean转换类型后为:"+Boolean(b4));//false
// - 字符串类型:空字符串转换为false,非空字符串转换为true
var str1 = "";
console.log("空字符串使用Boolean转换类型后为:"+Boolean(str1));//false
var str2 = "abcd";
console.log("非空字符串使用Boolean转换类型后为:"+Boolean(str2));//true
// - null:转换为false
console.log("null使用Boolean转换类型后为:"+Boolean(null));//false
// - 对象:转换为true,即使是空的,如object空对象,空数组,空函数,一组元素(未获得一组元素返回NodeList []),Symbol都为true,但没有获取到一个元素是null,Boolean转换后为false
var obj = {};
console.log("对象object使用Boolean转换类型后为:"+Boolean(obj));//true
var arr = [];
console.log("arr数组使用Boolean转换类型后为:"+Boolean(arr));//true
var box = document.querySelector(".box");
console.log("box未获取到一个元素:"+box);
console.log("一个元素使用Boolean转换类型后为:"+Boolean(box));//元素box不存在返回false
var boxs = document.querySelectorAll(".box");
console.log("box未获取到一组元素:"+boxs);//NodeList []
console.log("一组元素使用Boolean转换类型后为:"+Boolean(boxs));//true
var f = function(){};//true
console.log("函数使用Boolean转换类型后为:"+Boolean(f));//true
var s = Symbol();
console.log("唯一值Symbol使用Boolean转换类型后为:"+Boolean(s));//true
</script>
</body>
</html>
结果:
7.String(val) 转换成字符串
- - 数字类型,直接转换数据类型原样返回
- - undefined ,直接返回字符串 undefined。字符串undefined和类型undefined在控制台显示的颜色不一样
- - null,直接返回字符串 null
- - 布尔值,直接返回字符串 true 或者 false
- - 函数,直接把整个函数变成字符串 返回
- - 对象,直接调用对象的 toString 方法
-
对象1-{} [object,object]
-
对象2-元素对象 [object HTMLDivElement]
-
对象3-一组元素 [object NodeList]
-
对象4-数组:直接去掉方括号,把里面的值转为字符串。空数组,直接返回空字符串;一个元素,直接返回该元素;多个元素去掉[],返回所有元素且带有逗号“,”
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="box"></div>
<div class="boxs"></div>
<div class="boxs"></div>
<script>
// - 数字类型,直接转换数据类型原样返回
var num = 11.02;
console.log("数字类型11.02通过String类型转换后为:"+String(num)); //11.02
// - undefined ,直接返回字符串 undefined
console.log("undefined通过String类型转换后为:"+String(undefined)); //undefined
// - null,直接返回字符串 null
console.log("null通过String类型转换后为:"+String(null)); //null
// - 布尔值,直接返回字符串 true 或者 false
console.log("布尔值通过String类型转换后为:"+String(true)); //true
console.log("布尔值通过String类型转换后为:"+String(false)); //false
// - 函数,直接把整个函数变成字符串 返回
var f = function(){ var a=1; alert(a);};
console.log("函数通过String类型转换后为:"+String(f));//function(){ var a=1; alert(a);}
// - 对象,直接调用对象的 toString 方法
// 对象1-{} [object,object]
var obj = {};
console.log("空对象obj通过String类型转换后为:"+String(obj));//[object Object]
// 对象2-元素对象 [object HTMLDivElement]
var box = document.querySelector(".box");
console.log("单个元素对象box通过String类型转换后为:"+String(box));//[object HTMLDivElement]
// 对象3-一组元素 [object NodeList]
var boxs = document.querySelectorAll(".box");
console.log("一组元素对象boxs通过String类型转换后为:"+String(boxs));//[object NodeList]
// 对象4-数组:直接去掉方括号,把里面的值转为字符串。空数组,直接返回空字符串;一个元素,直接返回该元素;多个元素去掉[],返回所有元素且带有逗号“,”
var arr1 = [];
var arr2 = [1];
var arr3 = ['1'];
var arr4 = ['1','2'];
var arr5 = ['a','2'];
console.log("空数组对象[]通过String类型转换后为:"+String(arr1));
console.log("数组对象[1]通过String类型转换后为:"+String(arr2));
console.log("数组对象['1']通过String类型转换后为:"+String(arr3));
console.log("数组对象['1','2']通过String类型转换后为:"+String(arr4));
console.log("数组对象['a','2']通过String类型转换后为:"+String(arr5));
</script>
</body>
</html>
结果:
8.QQ号验证
要求:
- 不能为空;
- 只能输入5-10位;
- 必须是一个合法的整数;
- 不能以0开始;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>QQ号验证</title>
<style>
body { margin: 0; padding: 0; }
.wrap { width: 764px; height: 265px; background: url('img/bg.png') no-repeat; margin: 30px auto; position: relative;}
.txt, .btn { height: 40px; line-height: 40px; border-radius: 4px; outline: none; border:none; position: absolute; top:114px; }
.txt { width: 180px; background: #ffffff; left:310px; text-indent: 20px; }
.btn { width: 70px; background:none; background: #000000; color: #ffffff; left:500px; }
</style>
</head>
<body>
<div class="wrap">
<input type="text" class="txt">
<input type="button" class="btn" value="验证">
</div>
<script>
var txt = document.querySelector(".txt");
var btn = document.querySelector(".btn");
btn.onclick = function(){
var txtVal = txt.value;
// 不能为空;
if(txtVal == ''){
alert("QQ号不能为空");
// 只能输入5-10位;
//注意:不能获取txt元素的length而是获取txt.value的length
}else if(txtVal.length < 5 || txtVal.length > 10){
alert("QQ号必须在5-10位之间");
// isNaN 方法中,传入的数据 能被转换成 合法数字时,就会返回 false,当传入的数据不能被转换成 合法数字( 也就是NaN) 时,isNaN 就会返回 true
}else if(isNaN(txtVal)
|| txtVal != String(parseInt(txtVal)) //**代表txtVal本身有小数点,将数据转换成String,再进行比较。此时它会一位一位进行比较
|| txtVal<0){
alert("QQ号必须是一个合法的正整数");
// 不能以0开始;
}else if(txtVal[0]=='0'){
alert("QQ号首位不能为0");
}else{
alert("您输入的QQ正确");
}
};
</script>
</body>
</html>
结果:
检测小数:
当数据为10.22类似时,使用parseInt(num1) == parseFloat(num1)检测结果为false可行,但是小数位上全部为0时,如10.0,10.00等时,使用parseInt(num1) == parseFloat(num1)出来的结果为true结果不正确:
解决:转换成字符成再比较:String(num2) == String(parseFloat(num2)),如果num2本身是字符串就不用再转,但是后面都需要转
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>检测是否为小数</title>
</head>
<body>
<script>
//当小数为10.88类似时
var num1 = "10.88";
console.log("parseInt(num1) == parseFloat(num1)结果为:"+(parseInt(num1) == parseFloat(num1)));//返回false,代表有小数
//但当小数为10.0,小数位上全部为0时
var num2 = "10.00";
console.log("parseInt(num2) == parseFloat(num2)结果为:"+(parseInt(num2) == parseFloat(num2)));//返回true,此时小数没有被检测出来
//将数据转换成String,再进行比较。此时它会一位一位进行比较
console.log("num2 == String(parseInt(num2))结果为:"+(num2 == String(parseInt(num2))));//false
</script>
</body>
</html>
结果:
9.!=/==和!==/===区别:
!=/==会进行隐式类型转换,!==/===不会进行类型转换,类型不一样,直接返回不相等
10.数据筛选案例
- 所有的数字:-98765,34,-2,0,5
- 可以转数字的是:100px,-98765,34,-2,0,300,23.45元,5
- 最大值是:300
- NaN的位置是:1,14,17,19
注意点:
- Infinity 数字中的特殊值 Infinity无穷大 -Infinity 无穷小
- arr[i] === arr[i] NaN 不等于自己 如果自己等于自己说明不是NaN
- if(parseFloat(arr[i]))直接这样判断的话,值为0的项返回false,不会打印
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>数据筛选</title>
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<div class="box">
<div class="arrs">
var arr = [ '100px', 'abc'-6, [], -98765, 34, -2, 0, '300', ,
function(){alert(1);}, null, document, [], true, '200px'-30,'23.45元',
5, Number('abc'), function(){ alert(3); }, 'xyz'-90 ];
</div>
<!--
所有的数字:-98765,34,-2,0,5
可以转数字的是:100px,-98765,34,-2,0,300,23.45元,5
最大值是:300
NaN的位置是:1,14,17,19
-->
<div class="screen">
<p id="p1"></p>
<p id="p2"></p>
<p id="p3"></p>
<p id="p4"></p>
</div>
</div>
<script>
var arr = [
"100px",
"abc" - 6,
[],
-98765,
34,
-2,
0,
"300",
,
function() {
alert(1);
},
null,
document,
[],
true,
"200px" - 30,
"23.45元",
5,
Number("abc"),
function() {
alert(3);
},
"xyz" - 90
];
var p1 = document.getElementById("p1");
var p2 = document.getElementById("p2");
var p3 = document.getElementById("p3");
var p4 = document.getElementById("p4");
var p1Str = '所有的数字:';
var p2Str = '可以转数字的是:';
var p3Str = '最大值是:';
var p4Str = 'NaN的位置是:';
var maxVal = -Infinity;//**(记录标识,声明maxVal为无穷小,用到大于maxVal的就将其值赋到maxVal上)Infinity 数字中的特殊值 Infinity无穷大 -Infinity 无穷小
for(var i=0;i<arr.length;i++){
// 所有的数字:-98765,34,-2,0,5
//typeof 找到所有为number类型的数据,NaN也为数字类型,再通过!isNaN()去掉所有为NaN的数据
if(typeof arr[i] == 'number' && !isNaN(arr[i])){//// arr[i] === arr[i] NaN 不等于自己 如果自己等于自己说明不是NaN
p1Str += arr[i] + ',';
}
p1.innerHTML = p1Str.substring(0,p1Str.length-1);
// 可以转数字的是:100px,-98765,34,-2,0,300,23.45元,5
if(!isNaN(parseFloat(arr[i]))){//if(parseFloat(arr[i]))直接这样判断的话,值为0的项返回false,不会打印
p2Str += arr[i] + ',';
}
p2.innerHTML = p2Str.substring(0,p2Str.length-1);
// 最大值是:300
var curnum = parseFloat(arr[i]);
if(!isNaN(curnum) && curnum > maxVal){
//**用 maxVal 和数字中的每一位去比较,如果 nub 比 maxNub 大,就把 nub 的值 存入 maxNub 中,最后maxNub 和数组中每一位比较过后 maxNub 中保留就是 数组中的最大值
maxVal = curnum;
}
p3.innerHTML = p3Str + maxVal;
// NaN的位置是:1,14,17,19
if(typeof arr[i] == 'number' && isNaN(arr[i])){
p4Str += i + ',';
}
p4.innerHTML = p4Str.substring(0,p4Str.length-1);;
}
</script>
</body>
</html>
结果:
11.传值和传址(存值和存址)
- 基本类型在赋值过程中,传递的是具体的值;
- 对象在赋值过程中,传递的是在内存中的引用地址;
- 对象尽量不要使用=赋值,而使用拷贝
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>传值和传址</title>
</head>
<body>
<script>
//对象在赋值过程中,传递的是在内存中的引用地址
//arr传给arr2的是其在堆内存中的地址,因此,更改arr2的同时arr也改变了
//对象不要使用=赋值,需要使用拷贝
var arr = [1,2,3];
var arr2 = arr;
arr2[1] = 'b';
console.log(arr);//[1, "b", 3]
//基本类型在赋值过程中,传递的是具体的值
//b的值传给a后,b本身的值不会变
var b = 0;
var a = b;
a = 1;
console.log(b);//0
</script>
</body>
</html>
结果:
12.加性操作符
加法和减法都属于加性操作符。
加法运算符:
- 当左右两侧操作数,任意一侧为字符串,则另一侧非字符串的类型转为字符串类型,进行字符串拼接;
- 当左右两侧操作数都为Number,按如下规则返回结果:
- 左右两侧均为数值,执行常规加法计算;
- 任何数与NaN进行运算,返回结果都是NaN;
- 如果操作数是布尔值(转为0/1)、undefined(转为NaN)、null(转为0),则会使用Number将其转为数字类型,再进行计算,如果转换结果为NaN,则结果为NaN
- 加性操作符是从左至右进行计算的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>加性操作符之加法运算符</title>
</head>
<body>
<script>
//当左右两侧任意一侧为字符串时,进行拼接字符串操作
var str = '1' + 1;
console.log("'1' + 1 结果为:"+str);//11
//当左右两侧均为Number类型数据时:
//1.当左右两侧均为数值,进行正常加法运算
var num = 1 + 1;
console.log("1 + 1 结果为:"+num);//1
//2.任何数与NaN计算返回结果都是NaN
var num1 = NaN + 1;
console.log("NaN + 1 结果为:"+num1);//NaN
//如果操作数是布尔值(转为0/1)、undefined(转为NaN)、null(转为0),则会使用Number将其转为数字类型,再进行计算,如果转换结果为NaN,则结果为NaN
var num3 = true + 1;
console.log("true + 1 结果为:"+num3);//2
var num4 = undefined + 1;//Number(undefined)结果为NaN,任何数字和NaN进行计算结果都为NaN
console.log("undefined + 1 结果为:"+num4);//NaN
var num5 = null + 1;//Number(null)结果为0
console.log("null + 1 结果为:"+num5);//1
//加性操作符是从左至右进行计算的,所以会先将字符串1和数字2进行拼接即 '1' + String(2)->'12';再将'12' + String(3) ->123
var num6 = '1' + 2 + 3;
console.log("'1' + 2 + 3 结果为:"+num6);//123
</script>
</body>
</html>
结果:
减法运算符:
- 当左右两侧都为Number类型时,按照如下规则返回结果:
- 若左右两侧均为数值,执行常规的减法计算;
- 若其中一个操作数为NaN,则返回NaN;
-
若减法运算符的减数为负数,会转为加法运算符进行计算
-
减法运算符中没有字符串拼接,所以当其中一个数为字符串时会转为Number类型再进行计算
-
如果左右两侧都是负数,正常进行负数运算
- 如果任意一侧不为Number类型,如布尔值、字符串、undefined、null,则会先通过Number将其转为数字类型,然后再进行计算,如果其中转换结果为NaN,则结果为NaN。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>加性操作符之减法运算符</title>
</head>
<body>
<script>
// 当左右两侧都为Number类型时,按照如下规则返回结果:
// 若左右两侧均为数值,执行常规的减法计算;
var num1 = 3 - 2;
console.log("3 - 2 结果为:"+num1);//1
// 若其中一个操作数为NaN,则返回NaN;
var num2 = 3 - NaN;
console.log("3 - NaN 结果为:"+num2);//NaN
//若减法运算符的减数为负数,会转为加法运算符进行计算
var num3 = 3 - (-2);
console.log("3 - (-2) 结果为:"+num3);//5
//减法运算符没有字符串拼接,所以当其中一个数为字符串时会转为Number类型再进行计算
var num4 = '3' - (-2);
console.log("'3' - (-2) 结果为:"+num4);//5
var num5 = 3 - (-'2');
console.log("3 - (-'2') 结果为:"+num5);//5
//如果左右两侧都是负数,正常进行负数运算
var num6 = -5 - 6;
console.log("-5 - 6 结果为:"+num6);//5
// 如果操作数是Boolean、String、undefined、null,则会先通过Number将其转为数字类型,然后再进行计算,如果其中转换结果为NaN,则结果为NaN。
var num7 = 4 - true;
console.log("4 - true 结果为:"+num7);//3
var num8 = 4 - undefined;
console.log("4 - undefined 结果为:"+num8);//NaN Number(undefined)结果为NaN,如果其中转换结果为NaN,则结果为NaN
var num9 = 4 - null;
console.log("4 - null 结果为:"+num9);//4 Number(null)结果为0
var num10 = 4 - '3';
console.log("4 - '3' 结果为:"+num10);//3 String进行减法运算,会将其转为Number类型
</script>
</body>
</html>
结果:
减法为什么是加性操作符?
减号运算符作用于两个数字类型时表示减法,产生两个操作数之差,左边操作数是被减数左右是减数。给定操作符a和b,总是有a-b产生于a+(-b)产生相同结果。
13.隐式类型转换
隐式类型转换:我们没有主动对值进行转换,但因为我们的某些操作引起JS自动帮我们进行转换,这样的转换是在JS内部自己实现的。+/=等很多运算符都会进行隐式类型转换。
ECMAScript官网规则文档:
英文官方文档:http://www.ecma-international.org/ecma-262/5.1/#
中文 :http://www.fengfly.com/document/ECMAScript5.1/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>隐式类型转换测试</title>
</head>
<body>
<script>
//隐式类型转换参考ECMAScript规则
//隐式类型转换:本身v和v1不是同一类型,应该不相等,但是JS会自动将其进行类型转换,因此最终结果为true
var v = 100;
var v1 = "100";
console.log("v == v1结果为:"+(v == v1));//true
console.log("v + v1结果为:"+(v+v1));//true
console.log("'1'+1 结果为:"+('1'+1));
console.log("null+1 结果为:"+(null+1));
console.log("undefined+1 结果为:"+(undefined+1));
console.log("true+false+1 结果为:"+(true+false+1));
</script>
</body>
</html>
结果:
14.乘性操作符
乘法运算符、除法运算符、取模运算符都属于乘性操作符
14.1乘法运算符:
- 左右两侧都是Nubmer类型时:
- 左右两侧都为数值,进行正常的乘法运算
- 任何一侧为NaN,则结算结果都为NaN
- 左右两侧其中一侧不为Number类型(布尔型、null、undefined、字符串)时,则根据对应规则(Number)转为数字类型,然后进行计算。
<script>
// 左右两侧都是Nubmer类型时:
// 左右两侧都为数值,进行正常的乘法运算
console.log("2 * 3 结果为:"+(2 * 3));//6
// 任何一侧为NaN,则结算结果都为NaN
console.log("NaN * 3 结果为:"+(NaN * 3));//NaN
// 左右两侧其中一侧不为Number类型(布尔型、null、undefined、字符串)时,则根据对应规则(Number)转为数字类型,然后进行计算。
console.log("true * 3 结果为:"+(true * 3));//3
console.log("false * 3 结果为:"+(false * 3));//0
console.log("null * 3 结果为:"+(null * 3));//Number(null)*3 = 0*3 = 0
console.log("undefined * 3 结果为:"+(undefined * 3));//Number(undefined)*3 = NaN * 3 = NaN
console.log("'1' * 3 结果为:"+('1' * 3));//Number('1')*3 = 1*3 = 3
</script>
结果:
14.2除法运算符:
- 当左右两侧都为Number类型时,按如下规则返回结果:
- 如果左右两侧均为数值,则按照正常除法计算;
- 如果是非零的优先数被零除,则结果返回Infinity或-Infinity;(数学中不允许零作为除数)
- 如果是零被零除,则返回NaN;
- 如果有一个操作数是NaN,则结果返回NaN;
- 如果任意一侧不是Number类型,则(根据对应的规则)转为数字类型,然后进行计算
<script>
// 当左右两侧都为Number类型时,按如下规则返回结果:
// 如果左右两侧均为数值,则按照正常除法计算;
console.log("6/3 结果为:"+(6/3));//2
// 如果是非零的优先数被零除,则结果返回Infinity或-Infinity;(数学中不允许零作为除数)
console.log("6/0 结果为:"+(6/0));//Infinity
console.log("-6/0 结果为:"+(-6/0));//-Infinity
// 如果是零被零除,则返回NaN;
console.log("0/0 结果为:"+(0/0));//NaN
// 如果有一个操作数是NaN,则结果返回NaN;
console.log("0/NaN 结果为:"+(0/NaN));//NaN
console.log("NaN/2 结果为:"+(NaN/2));//NaN
// 如果任意一侧不是Number类型,则(根据对应的规则)转为数字类型,然后进行计算
console.log("true / 3 结果为:"+(true / 3));//0.3333333333333333
console.log("false / 3 结果为:"+(false / 3));//0
console.log("null / 3 结果为:"+(null / 3));//Number(null)/3 = 0/3 = 0
console.log("undefined / 3 结果为:"+(undefined / 3));//Number(undefined)/3 = NaN / 3 = NaN
console.log("'1' / 3 结果为:"+('1' / 3));//Number('1')/3 = 1/3 = 0.3333333333333333
</script>
结果:
14.3取模操作符:
进行除法计算,但是目的是为了得到余数,而不再是得到结果。
- 如果左右两侧均为Number类型时,按照如下规则返回结果:
- 如果左右两侧均为数值,按照常规除法进行计算,返回余数;
- 如果有一侧是NaN,则返回NaN;
- 如果除数是0,则结果返回NaN;
- 如果被除数是0,则结果返回0;
- 如果任意一侧不是Number类型(String,Boolean,null,undefined等),则(根据对应的规则Number)转为数字类型,然后再进行计算。
<script>
// 如果左右两侧均为Number类型时,按照如下规则返回结果:
// 如果左右两侧均为数值,按照常规除法进行计算,返回余数;
console.log("12%7 结果为:"+(12%7));//5
// 如果有一侧是NaN,则返回NaN;
console.log("12%NaN 结果为:"+(12%NaN));//NaN
console.log("NaN%7 结果为:"+(NaN%7));//NaN
// 如果除数是0,则结果返回NaN;
console.log("7%0 结果为:"+(7%0));//NaN
//如果被除数是0,则结果返回0;
console.log("0%7 结果为:"+(0%7));//0
// 如果任意一侧不是Number类型(String,Boolean,null,undefined等),则(根据对应的规则Number)转为数字类型,然后再进行计算。
console.log("'1'%7 结果为:"+('1'%7));//Number('1')%7 = 1
console.log("true%7 结果为:"+(true%7));//Number(true)%7 = 1
console.log("false%7 结果为:"+(false%7));//Number(false)%7 = 0
console.log("null%7 结果为:"+(null%7));//Number(null)%7 = 0
console.log("undefined%7 结果为:"+(undefined%7));//Number(undefined)%7 = NaN
</script>
结果:
14.4取模案例
<script>
//判断一个数字的奇偶数,如果能被2整除即为偶数,不能被2整除即为奇数,可以用于各行变色
var num = 21;
if(num%2){
alert("num为奇数");
}else{
alert("num为偶数");
}
15.一元操作符(一元加、减运算符)
一元操作符即正号和负号(+、-),只能操作一个值的操作符叫做一元操作符。
15.1一元加运算符:
- 如果操作数是Number类型时,正号放在数值前面,对其没有任何影响;
- 如果操作数是非Number类型即String,true,false,null,undefined,则(根据对应规则Number)将其转为数字类型(隐式类型转换),再进行运算。(Number转换非数字类型字符串返回NaN)
- 无论正号还是负号对NaN,都是没有影响的,结果都为NaN;
<script>
// 如果操作数是Number类型时,正号放在数值前面,对其没有任何影响;
console.log("+5的结果是:"+(+5));//5
// 如果操作数是非Number类型即String,true,false,null,undefined,则(根据对应规则Number)将其转为数字类型(隐式类型转换),再进行运算。
console.log("+'5'的结果是:"+(+'5'));//5
//如果String里不是数值类型,使用+会直接转为NaN
console.log("+'abc'的结果是:"+(+'abc'));//NaN
console.log("+true的结果是:"+(+true));//1
console.log("+false的结果是:"+(+false));//0
console.log("+null的结果是:"+(+null));//0
console.log("+undefined的结果是:"+(+undefined));//0
// 无论正号还是负号对NaN,都是没有影响的,结果都为NaN;
console.log("+NaN的结果是:"+(+NaN));//NaN
console.log("-NaN的结果是:"+(-NaN));//NaN
</script>
结果:
15.2一元减运算符
- 如果操作数是Number类型时,负号放在数值前,表示负数;
- 如果操作数不是Number类型,即String,true,false,null,undefined,则(根据对应规则Number)转为数字类型(隐式类型转换),再进行运算;
- 无论正号还是负号对NaN,都是没有影响的,结果都为NaN;
<script>
// 如果操作数是Number类型时,负号放在数值前,表示负数;
console.log("-5的结果为:"+(-5));
// 如果操作数不是Number类型,即String,true,false,null,undefined,则(根据对应规则Number)转为数字类型(隐式类型转换),再进行运算;
console.log("-'5'的结果为:"+(-'5'));//Number('-5')=-5
console.log("-'abc'的结果为:"+(-'abc'));//NaN
console.log("-true的结果为:"+(-true));//-1
console.log("-false的结果为:"+(-false));//0
console.log("-null的结果为:"+(-null));//0
console.log("-undefined的结果为:"+(-undefined));//NaN
// 无论正号还是负号对NaN,都是没有影响的,结果都为NaN;
console.log("-NaN的结果为:"+(-NaN));//NaN
</script>
结果:
16.巧妙利用运算符进行隐式类型转换
巧妙利用运算符进行隐式类型转换:偶尔可通过隐式类型转换来达到想要把数据转为另一种数据的目的。
总结:
“+”号的三种用法:
- 左右两侧都是数字类型时,进行加法运算;
- 左右两侧任意一侧为字符串时,进行字符串拼接;
- 只有一个数字使用+号时(一元运算符),如+10,可用作隐式类型转换;
<script>
//想要进行运算,但是有变量是字符串时
var num1 = "123";
var num2 = 2;
//如果直接num1+num2会进行字符串拼接 得到1232
console.log("num1+num2直接相加后结果为:"+(num1+num2));//1232
//传统方法:要想让其以数字类型进行计算需要使用Number()进行转换(注意:不能使用Number(num1+num2),这样会先进行字符串拼接,再转换)
console.log("Number(num1)+num2使用Number进行转换类型后结果为:"+(Number(num1)+num2));//125
//巧妙利用运算符进行隐式类型转换:可以直接使用+号一元运算符进行隐式类型转换
console.log("(+num1)+num2使用+号隐式类型转换后结果为:"+((+num1)+num2));//125
//想要进行字符串拼接但是变量都是数字类型时
var num3 = 10;
var num4 = 20;
// 两个数字类型直接相加,得到的是两个数之和
console.log("num3+num4两个数字类型直接相加后结果:"+(num3+num4));//30
//传统方法:通过String()方法让其转换为字符串,再进行拼接
console.log("String(num3)+String(num4)两个数字类型直接相加后结果:"+(String(num3)+String(num4)));//1020
//使用隐式类型转换:注意此处+ ''必须在两个变量中间,因为加法运算是从左到右依次进行计算,如果+''在最后,会先进行和计算再转为字符串
console.log("num3+ '' +num4两个数字类型直接相加后结果:"+(num3 + '' + num4));//1020
</script>
结果:
17.递增/递减运算符
- 单独对一个操作数进行递增/递减操作,不和其他数值进行计算时,结果是一样的,都只是进行相应的递增递减;
- 但是,当递增/递减操作和其他数值进行了计算时:(计算后的结果result会不一样,但是两个自增/自减的变量(num1和num2)在计算后值依然相等)
- 前置型递增/递减运算符:变量的值在语句被求值之前发生改变;
- 后置型递增/递减运算符:变量的值在语句被求值之后发生改变;
如下:num1和num2初始值都为0,分别对num1和num2进行了num1++和++num2操作,发现两种操作后num1和num2的结果都是一样的,值为1。所以,如果同样只单独对某一个操作数进行递增或递减操作,那么前置或后置递增/递减后的结果是相同的。
var num1 = 0;
var num2 = 0;
num1++;
++num2;
console.log("num1++后的结果为:"+num1);
console.log("++num2后的结果为:"+num2);
结果:
但是,当num1和num2进行了num1++和++num2操作,并且和其它数值进行计算后,使用前置递增/递减操作符的变量的值在语句被求值之前会发生改变;而后置递增/递减操作符的变量的值在语句被求值之后才会发生改变。计算后的结果result会不一样,但是两个自增/自减的变量(num1和num2)在计算后值依然相等。如下:
//单独对一个操作数进行递增/递减操作,不和其他数值进行计算时,结果是一样的,都只是进行相应的递增递减;
// 但是,当递增/递减操作和其他数值进行了计算时:
// 前置型递增/递减运算符:变量的值在语句被求值之前发生改变;
// 后置型递增/递减运算符:变量的值在语句被求值之后发生改变;
var num1 = 0;
var num2 = 0;
// num1++;
// ++num2;
// console.log("num1++后的结果为:"+num1);
// console.log("++num2后的结果为:"+num2);
var result = num1++ + 1;
var result2 = ++num2 + 1;
console.log("2+num1++后result的结果为:"+result);
console.log("2+(++num2)后result2的结果为:"+result2);
console.log("2+num1++后num1的结果为:"+num1);
console.log("2+(++num2)后num2的结果为:"+num2);
结果:
18.小数的计算失精度问题
这个问题主要是由于JS是基于IEEE754数值的浮点计算,ECMAScript并不是独此一家。很多其他的语言也存在这一问题。
解决方法:将小数转换成整数之后,进行计算,然后再转回会对应的小数即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>小数计算问题</title>
</head>
<body>
<input type="text" id="input1" value="0.1">
+
<input type="text" id="input2" value="0.2">
<button id="btn"> = </button>
<span id="result"></span>
<script>
var input1 = document.getElementById("input1");
var input2 = document.getElementById("input2");
var btn = document.getElementById("btn");
var result = document.getElementById("result");
btn.onclick = function(){
var txt1Val = input1.value;
var txt2Val = input2.value;
//直接使用小数计算(通过元素获取的内容都是字符串,所以会进行字符串拼接0.10.2)
//result.innerHTML = txt1Val + txt2Val;//0.10.2
//使用Number()转换成数字类型后,发现结果为0.30000000000000004
//result.innerHTML = Number(txt1Val) + Number(txt2Val);//0.30000000000000004
//解决:将txt1Val,txt2Val两个数都乘以小数位数的数十倍,将其转为整数再进行计算,得到计算结果后,再除以对应的数十倍即可
result.innerHTML = (Number(txt1Val) * 10 + Number(txt2Val) * 10) / 10; //0.3
};
</script>
</body>
</html>
结果:
直接转为数字类型进行计算(结果失去精度):
转为数字类型后,再乘以小数位数的数十倍,得到计算结果后再除以数十倍(结果正确):
19.赋值运算符
- 赋值运算符:=,+=,-=,*=,/=,%=;
- =等号:用于将右侧的值,赋给左侧的变量;
- +=,-=,*=,/=,%=:大部分的数学运算符和=号结合使用就可以完成复合赋值运算;要求:左侧变量必须和右侧变量一致
- 赋值运算符的隐式类型转换:+=,-=,*=,/=,%=赋值运算符只是对各种运算的简写,因此赋值运算符的隐式类型用法和其原本的隐式类型转换是一致的;
<script>
//=,+=,-=,*=,/=,%=
var num = 10;
//+=
num = num + 5;
console.log("num = num + 5后的结果为:"+num);//15
num = 10;
num += 5;
console.log("num += 5后的结果为:"+num);//15
//-=
var num2 = 10;
num2 = num2 - 5;
console.log("num2 = num2 - 5后的结果为:"+num2);//5
num2 = 10;
num2 -= 5;
console.log("num2 -= 5后的结果为:"+num2);//5
//*=
var num4 = 10;
num4 = num4 * 5;
console.log("num4 = num4 * 5后的结果为:"+num4);//50
num4 = 10;
num4 *= 5;
console.log("num4 *= 5后的结果为:"+num4);//50
// /=
var num6 = 10;
num6 = num6 / 5;
console.log("num6 = num6 / 5后的结果为:"+num6);//2
num6 = 10;
num6 /= 5;
console.log("num6 /= 5后的结果为:"+num6);//2
// %=
var num8 = 10;
num8 = num8 % 5;
console.log("num8 = num8 % 5后的结果为:"+num8);//0
num8 = 10;
num8 %= 5;
console.log("num8 %= 5后的结果为:"+num8);//0
//=,+=,-=,*=,/=,%=的隐式类型转换(和所有+-*/%的隐式类型转换一致)
var b = '2';
b += 2;
console.log("b = '2' +=后的结果为:"+b);//22
</script>
结果:
20.比较操作符
20.1比较操作符之关系操作符
<, <= ,>, >=用于比较大小,返回的结果可为="", true,false或 undefined(这说明 x、y 中最少有一个操作数是 NaN)。
- 左右两侧都是数字类型,就比较数值的大小;
- 如果不是数字的情况:
- 字符串的比较:即使字符串里面是数字,也不进行数值比较,而是会按字符编码ASCII码顺序进行比较;字符串的比较是逐位比较的;
- 如果比较运算符的其中一侧为NaN,则结果返回false;
- 如果其中一侧为null,undefined,true,false,最终会根据对应的规则进行转换,然后再进行比较;
- >=,<=,>和<,如果任意一侧为undefined(Number(undefined)=NaN),则返回false,否则返回true;
-
字符串和布尔值比较:如果左侧值小于右侧值的结果为true或undefined,则返回false,否则返回true
<script>
//字符串比较,比较的是字符串的ASCII字符编码中的大小;且从左往右一位一位的比较;
var str1 = 'A0';//A对应的编码为65
var str2 = '34';//3对应的编码为51
console.log("字符串A0和34比较的结果为:"+(str1>=str2));//true
//如果比较运算符的其中一侧为NaN,则结果返回false
console.log("NaN和34比较的结果为:"+(NaN>=str2));
console.log("A0和NaN比较的结果为:"+(str1>=NaN));
//如果其中一侧为null,undefined,true,false最终会根据对应的规则进行转换
// console.log(String(null));//110
// console.log(Number(null));// 0 对应的编码为48
console.log("如果其中一侧为null和34比较的结果为:"+(null>=str2));//此处结果为false
// >=,<=,>和<,如果任意一侧为undefined(Number(undefined)=NaN),则返回false,否则返回true
console.log("str2>=undefined比较的结果为:"+(str2>=undefined));//false
console.log("undefined>=str2比较的结果为:"+(undefined>=str2));//false
console.log("str2>undefined比较的结果为:"+(str2>undefined));//false
console.log("undefined>str2比较的结果为:"+(undefined>str2));//false
console.log("undefined<=str2比较的结果为:"+(undefined<=str2));//false
console.log("str2<=undefined比较的结果为:"+(str2<=undefined));//false
console.log("undefined<str2比较的结果为:"+(undefined<str2));//false
console.log("str2<undefined比较的结果为:"+(str2<undefined));//false
//字符串和布尔值比较:如果左侧值小于右侧值的结果为true或undefined,则返回false,否则返回true
console.log("str2>=true比较的结果为:"+(str2>=true));//true 34 1
console.log("true>=str2比较的结果为:"+(true>=str2));//false 1 34
console.log("-----------------------------");
console.log("str1>=true比较的结果为:"+(str1>=true));//false A0 1
console.log("true>=1比较的结果为:"+(true>=1));//true 1 1
</script>
结果:
20.2相等操作符
==相等 !=不等 ===全等 !==全部等,用于确认两个变量之间是否相等。
相等和全等:虽然都是比较两个值是否相等,但是在比较时,需遵循不一样的规则。
20.2.1相等:
比较两个操作数之间是否相等,如果相等会返回true,如果不相等返回false,比较时会进行隐式类型转换。
隐式转换规则:
- NaN不等于任何类型的数值,包括其本身,所以一定返回false;
- 如果都是String类型,比较字符编码值,如果完全一致,返回true,否则返回false;
- 如果两侧都是Number数值类型,比较值是否相同;
- 如果两边都是Object类型,比较地址是否相同;
- null==undefined返回true;(不会进行隐式类型转换)
- 如果一侧为String,一侧是Number,将String(String不可以转成数字类型的字符串)转换NaN之后,再进行比较;
- 如果一侧是Boolean,则把布尔值转为Number类型后,再根据上述规则进行比较;
- 具体参照ECMAScript规则;
<script>
//==会进行隐式类型转换,本身数据类型不同,但是JS会对其进行隐式类型转换,就可以比较了
console.info("1==1结果为:"+(1==1));//true
// NaN不等于任何类型的数值,包括其本身,所以一定返回false;
console.info("NaN==1结果为:"+(NaN==1));//false
console.info("NaN==NaN结果为:"+(NaN==NaN));//false
// 如果都是String类型,比较字符编码值,如果完全一致,返回true,否则返回false;
console.info("'abc'=='123'结果为:"+('abc'=='123'));//false
console.info("'abc'=='abc'结果为:"+('abc'=='abc'));//true
// 如果两侧都是Number数值类型,比较值是否相同;
console.info("1==1结果为:"+(1==1));//true
// 如果两边都是Object类型,比较地址是否相同;
var a = {name:'lmf'};
var b = {name:'lmf'};
console.info("a==b结果为:"+(a==b));//false
var c = b;
console.info("c==b结果为:"+(c==b));//true
// null==undefined返回true;
console.info("null==undefined结果为:"+(null==undefined));//true
// 如果一侧为String,一侧是Number,将String(String不可以转成数字类型)转换NaN之后,再进行比较;
console.info("'1'==1结果为:"+('1'==1));//true
console.info("'abc'==1结果为:"+('abc'==1));//false String("abc")=NaN Nan==1返回false
// 如果一侧是Boolean,则把布尔值转为Number类型后,再根据上述规则进行比较;
console.info("true==1结果为:"+(true==1));//true
</script>
结果:
20.2.2全等:
全等===也是比较两个操作数之间是否相等,但是与==不同,它从两个点进行考虑:
- 值是否相等;
- 类型是否相等
因为会判断类型,所有全等不会进行隐式类型转换:
- 一旦两个操作数的数据类型不同,直接返回false;
- 一旦出现NaN,直接返回false;
- 当类型一致时,比较值是否相同(为字符串时比较其字符编码是否相等),不同返回false,相同返回true;
<script>
//全等:首先必须类型一致,其次必须值一致,才会返回true;一旦出现NaN,返回false
//类型不一致
console.log("null==undefined结果为:"+(null==undefined));//true
console.log("null===undefined结果为:"+(null===undefined));//false
//当类型一致时,比较值是否相等
console.log("2===3结果为:"+(2===3));
console.log("'abc'==='abd'结果为:"+('abc'==='abd'));
</script>
结果:
20.2.3不等和全不等:
和相等和全等一样,不等和全部等在比较时:
- 前者只注重值,并且会进行隐式类型转换,转换规则与相等一致,只是返回的结果正好相反;
- 后者在注重值的同时,还是注重类型是否相同,转换规则和全等一致,只是返回结果正好相反;
21.逻辑运算符
&&,||,!最终的结果不一定是返回布尔值,而在if()里最终返回boolean值,是因为if会最终将其转为布尔值再进行后续操作。
21.1 &&与:如,alert(1 && 2)
- 作用在两个操作数之间,首先去看左侧的操作数,将其1进行隐式类型转换,转为boolean。true/false
- false,会直接返回左侧的操作数;
- true,会直接返回右侧的操作数;
21.2 || 或:如,alert(0 || 1)
- 作用在两个操作数之间,首先去看左侧的操作数,将其1进行隐式类型转换,转为boolean。true/false
- 如果为true,会直接返回左侧操作数;
- false,会直接返回右侧操作数;
21.3 !非:alert(!true)
- 取反,作用于一个操作数,得到的一定是布尔值。
- 会对这个操作数进行隐式类型转换,转换为Boolean
- !非也是一元运算符
- 使用!!num,两个!!就可以对numnum进行强制类型转换。
console.log("Boolean(1)转为布尔值:"+Boolean(1));
console.log("!!1转为布尔值:"+!!1);
结果:
非 :作用在一个操作符上,也是一元运算符之一,表示对该操作进行取反,所以会对数据进行隐式类型转换,转为布尔值,然后取反,最后返回一个布尔值。
非的隐式类型转换规则:(和其本身进行Boolean值转换后的结果相反)
- 如果操作数是Object类型,结果返回false(所有对象经过Boolean转换后均为true);
- 如果操作数是控制串,返回true;
- 如果是费控字符串,返回false;
- 如果是Number数值0,返回true;
- 如果是NaN,返回true;
- 如果是非0数值,返回false;
- 如果是null或undefined,返回false
!非运算符,不止可以写一个:
- !!!0 表示对0进行布尔值转换,再取反,结果为true。
- !!true表示对true进行取反,结果为false;
22.运算符优先级
<script>
var result1 = 2 + 3;
console.log("2 + 3 :"+result1);
var result2 = 2 + 3 * 2;
console.log("2 + 3 * 2: "+result2)
var result3 = 1 + 2 == 5 % 0;
console.log("1 + 2 == 5 % 0 : "+result3);//false 取模运算符> 赋值运算符>加法运算符
</script>
结果:
尽管我们之前说,计算是从左往右的,但是这只是在运算符优先级相同的情况下。一旦运算符的优先级不一致,则会先执行优先级高的,然后再执行低的。
运算符优先级查看地址:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence