2.02.16数据类型和运算符
1.数据类型
- 虽然js是弱类型语言,但为了将数据分类,使得数据的意义更规范,所以需要数据类型
1. 数据类型分类
-
基本数据类型:
- number 数值型
- JavaScript中只有一种数字类型:64位的浮点数。它并没有为整数给出一种特定的类型,所以1和1.0的值相同。
- js中小数位转二进制是不精确的,所以涉及小数位的运算有时候是不精确的
- 解决方法:先放大到不存在小数位,再缩回原来的倍数
- 数据类型转换
- 使用Number()可以把其他数据类型转成number类型
- 例如:var i=“2022”; var k= Number(i);
- 用Number转类型,并不会影响原变量i的值与类型,只会将变量i存的值转换成number型赋给变量k
- 使用Number()可以把其他数据类型转成number类型
- NaN :不是数字的number类型(将非数字字符转换成number类型就会得到NaN的值)
- NaN不等于任何数,包括自己,即 NaN == NaN 的结果是false
- 任何数和NaN运算,结果都是NaN
- 数字类型与非数字类型运算的结果是NaN(+除外,因为+有连接符的作用)
- 可以用isNaN()判断一个变量是否是NaN,用!isNaN()判断一个变量是否是数字
- 语法:!isNaN(3) // true
- 如果一个数子字面量有指数部分,那么这个字面量的值等于e之前的数字与10的e之后数字的次方相乘。所以100和1e2是相同值
- String 字符型
- 字符串需要用’'或" "或 ``包裹
- 使用String()可以把其他数据类型转成String类型
- 注意单引号套双引号,双引号套单引号都行
- 转义字符: 在JavaScript \(反斜线)是转义符号用来将那些正常情况下不被允许的字符插入到字符串中,比如反斜线、引号和控制字符。
- \n 换行
- \t 制表符
- \b 空格
- \r 回车
- \f 换页
- 两个\ 斜杠
- \xnn 给定十六进制代码(n为0~F)的字符。例如, ‘\x41’ 表示 ‘A’
- \unnnn 给定十六进制代码(n为0~F)的Unicode字符。例如’\u0041’表示 ‘A’
- length属性: 字符串有一个length属性可以获取当前字符串的长度。例如 ‘seven’.length 是 5
- 字符串拼接:字符串是不可变的,一旦被创建就无法改变他。但你可以很容易的通过 + 运算符连接其他字符串来创建一个新的字符串
- 空字符""转能number就是0
- **注意:**当数字与字符串使用 + 号运算时,js 会将数字隐式转化为字符串
- boolean 布尔型
- 概念:布尔表示一个逻辑实体,可以有两个值:true 和 false。
- 其他类型转boolean类型
- 例如:console.1og( Boolean("-1") ); // true
- 数字类型转布尔类型,非0即真,其他数字都是真
- 字符串是真值
- 假值:空字符串、null、undefined、NaN、0、false 这些值转布尔类型都是假值
- null 空类型
- null表示一个空,想到得到null类型,只需要在定义变量的时候,赋值为nu11即可
- null一般用来释放内存
- null>0 false
- null < 0 false
- null==0 false
- null >= 0 true
- 转成number类型会变成0
- undefined 未定义
- undefined表示一个声明了没有赋值的变量,变量只声明的时候值默认是undefined
- 定义一个变量给其值赋值为undefined,然后直接打印或者使用这个变量,变量值也是undefined
- 后期我们学习函数以后,如果定义函数的时候没有返回值,那么调用函数 得到的结果也会是undefined
- number 数值型
-
引用类型:
6. object 对象类型
+ 对象object
+ 数组array
- 一个数组可以赋不同类型的数据
+ 函数function -
es6 象征类型Symbol
2. 查看数据类型
- 方法:typeof(变量) 或者 typeof 变量
- typeof 变量 返回一个描述数字类型的字符串,并且打印这个字符串
- typeof null
概念:在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。引用数据类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 “object”。曾有一个 ECMAScript 的修复提案,但被拒绝了。
3. 栈(stack)和堆(heap)
-
栈
- 内存小,速度快
- stack为自动分配的内存空间,它由系统自动释放
- 基本类型存放在栈内存中,数据大小确定,内存空间大小已知,赋给变量的值就是在栈中所开辟的内存本身。
-
堆
- 内存大,速度慢
- 而heap则是动态分配的内存,大小不定也不会自动释放
- 引用类型存放在堆内存中的对象,赋给变量实际保存的是一个指针,这个指针指向开辟在堆中的内存地址。每个空间大小未知。当我们需要访问引用类型的值时,首先从栈中获得该对象的地址指针,然后再根据地址从堆内存中取得所需的数据。
-
栈的赋值与堆的赋值
- 基本数据类型变量的赋值时"深拷贝",引用数据类型的赋值是"浅拷贝"
- 引用数据类型的赋值,浅拷贝变量赋值时只是拷贝了一份指向同一个数据堆内存的地址,赋值给了新的变量
- 基本数据类型变量的赋值,深拷贝在内存中重新开辟一段新的内存空间并拷贝其值赋值给新的变量
2.运算符
1. 运算符:运算符就是可以进行运算的符号
2. 运算符可以分为
- 一元运算符(只有一个操作数) a++
- 二元运算符(只有两个操作数) a+b
- 三元运算符(只有三个操作数) a?b: C
3. 运算符的分类
1. 字符串连接符
- 字符串连接符 + :用来连接两个字符串
- **隐式转换:**只要遇到字符串就会变成字符串拼接
-
i = “a”+1+ 2; 结果为:a12
-
i = 1+2+“a”; 结果为:3a
-
var arr = [“俄罗斯”,“乌克兰”,“三个方向”,“高达”];
console.log("arr => " + arr); //arr => 俄罗斯,乌克兰,三个方向,高达
-
2. 算术运算符
- ‘+’ 加 x = 5 + 2 x = 7
- ‘-’ 减 x = 5-2 x = 3
- ''乘 x = 52 x = 10
- ‘/’ 除 x = 5/2 x = 2.5
- ‘%’ 取模,也可以叫求余数 x = 5 % 2 x = 1
- **隐式转换:**除了+外,其他有隐式的数据类型转换的作用,把其他类型转成number类型
3.自增自减运算符
- ‘++’ 自增 x++ x = x + 1
- ‘–’ 自减 x-- x = x - 1
- ++、-- 在变量前面和后面是有区别的:(需要放在变量前后,用在数字前后会报错)
- 先自增再赋值:
var a = 5
var b = ++a // 先自增再赋值
console.log(a, b) // 6 , 6
- 先赋值再自增:
var a = 5
var b = a++ // 先赋值再自增
console.log(a, b) // 6 , 5
4.数值运算符
- 正号+
- 负号-
- **隐式转换:**在字符串前加+或-可以使得其变为number类型,只是值为NaN
- var i = +“123”;console.log(i, typeof i); //控制台输出为:NaN ‘number’
5.赋值运算符
- = x = 5
- += x += 5 x = x + 5
- -= x -= 5 x= x- 5
- *= x *= 5 x = x * 5
- /= x /= 5 x = x / 5
- %= x %= 5 x= x % 5
6.比较运算符(大小的比较,值是否相等的比较)
1.比较运算符类型
- ‘>’ 大于 18 > 17 true
- ‘<’ 小于 18 < 17 false
- ‘>=’ 大于等于 18 >= 18 true
- ‘<=’ 小于等于 18 <= 17 false
- == 等于 只需要比较值是否相等 1 == ‘1’ true
- != 不等于 1 != 2 true
- === 全等于 (要比较数据类型相等和值相等) 1 === ‘1’ false
- !== 不全等于 1 !== ‘1’ true
2.("> < >= <=")的隐式转化
- 数字与非数字比较,会把非数字转化成数字
- 比如,
console.log(1 >true);//1和1的比较
console.1og(1 >false);//1和0的比较
console.1og(1 >“aa”);//1和NaN的比较,NaN无法比较大小,这里会打印false
- 比如,
- 字符串与字符串比较
- 比较他们的unicode编码
- js使用的编码: unicode编码(统一码,万国码)
大写字母: A-Z,65-90
小写字母:a-Z,97-122
简体中文的范围:\u4e00 - \u9fa5
“字符”. charcodeAt() 可以查看字符的unicode编码 - 两个字符串的比较是单个单个字符比较编码大小,直至出结果
- 除了两个字符串比较,其他情况都转成number类型比较
3.("== !=")的隐式转化
- 如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true。就是他们指向的地址一样时才相等。
- 如果一个操作数是null,另一个操作数是undefined或者null,则返回true。
- 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:
- 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
- 如果操作数之一是Boolean,则将布尔操作数转换为1或0。
- 如果是true,则转换为1。
- 如果是 false,则转换为0。
- 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()和toString()方法将对象转换为原始值。
- 如果操作数具有相同的类型,则将它们进行如下比较:
- String:true仅当两个操作数具有相同顺序的相同字符时才返回。
- Number:true仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false。
- Boolean:true仅当操作数为两个true或两个false时才返回true。
7.逻辑运算符
- && 逻辑与(且) &&符号两边的表达式的结果同时为真才为真
- 进阶用法:
//可以用来做开关:
var flag = confirm("是否给予定位权限"); // true 或false
//只有条件为真,才会执行后面的代码
var i= flag && "正在获取你的定位" ;
console.log(i);
- || 逻辑或 或者 ||符号两边的表达式的结果只要有一边为真就为真
- 进阶用法:
//可以用来做默认值
var city = prompt("请输入你要查询的城市天气”);
var i = city||"北京";
console.log(i+"当前的天气为晴天");
- ! 逻辑非 取反 取反操作 将true变为false 将false变为true
- 进阶用法:
//非运算符可以把其他数据类型转Boolean 类型
console .1og(!"a");// false
8.三元运算符
- 语法:条件语句 ? 语句1 : 语句2; 当左边表达式成立时返回语句1否则返回语句2
- age >= 18 ? ‘成年’:‘未成年’; //当左边表达式成立时返回语句1否则返回语句2
- 三目运算符的条件语句在这里,只会返回true或false两种结果,是一个布尔值,这里隐式转换成一个布尔值
9.位运算符( & | ~ ^)
- 把数字化成二进制数再进行运算,把数字化成二进制,两个数的位数化成一样长,位数不够在前面补0
- & :全为1才是1,一个0就是0
- | :一个为1就是1 全部为0才是0
- ~ :取反-1
- ^ :相同为0, 不同为1
- 三次异或可以交换两个变量的值
<script>
// 二进制 0 1
// 位运算符 & | ~ ^
// 1024 512 256 128 64 32 16 8 4 2 1
// 6: 1 1 0
// 8: 1 0 0 0
// 17: 1 0 0 0 1
// 7: i 0 1 1 1;
// 13: j 1 1 0 1;
// 7&13 0 1 0 1;
// 7|13 1 1 1 1
// i = i ^ j = 10 1 0 1 0;
// j = i ^ j = 7 0 1 1 1;
// i = i ^ j = 13 1 1 0 1;
var i = 7;
var j = 13;
// & 且: 全部为真才是真, 一个为假就是假
console.log( i & j ); // 5
// | 或: 一个为真就是真 全部为假才是假
console.log(i | j); // 15
// ~ 非: 值取相反数再-1
console.log(~i); // -8
console.log(~j); // -14
console.log(~-3); // 2
// ^ 异或:相同为0, 不同为1
i = i ^ j;
j = i ^ j;
i = i ^ j;
console.log(i); // 13
console.log(j); // 7
</script>
10.运算符优先级
- 介绍:在下面运算符优先级表中,排在越上面的运算符优先级越高。排在越下面的运算符优先级越低。圆括号可以用来改变正常情况下的优先级:
. [] () 提取属性函数调用
delete new typeof ++ -- ! 一元运算符
* / % 乘法、除法、取余
+ - 加法/拼接 、 减法
<= >= > < 不等式运算符
=== !== 等式运算符
&& 逻辑与
|| 逻辑或
? : 三元运算符