前言
记录JacaScript关于数据类型,作用域的重点易忘笔记
一、概述与定义
- 数据类型分为原始类型和对象类型
- 属性的集合称之为对象
null和undefined也是原始类型,没有方法。值唯一并且不可修改- ES6新增Symbol类型
- 常量声明const,变量let(老版本var),声明是无类型的,不影响赋什么类型的值,Java按照类型声明
- JavaScript会自动做类型转换,在需要字符串的地方会自动把数据转换成字符串,需要数值的地方自动把数据转换成数值
二、数值
- 取值范围:约正9000兆至负9000兆
- 数值字面值可使用分隔符
let i = 1_000_000;
1.整数字面量
- 整数字面量可以用10进制,16进制,2,8进制的任意数表示
let i = 0xff;
console.log(i);//255
2. 浮点数字面量
- 为什么不用浮点数进行计算
解释:计算机的浮点格式只能表示有限个实数,而实数是无限的,所以我们操作的不是一个精切的实数,而是通过舍入后无限接近于当前实数的数。所以
0.5-0.2不一定等于0.4-0.1
console.log((0.3 - 0.2) === (0.2 - 0.1));//false
3.JavaScript中的算数
- 包括基本的
+ - * / %,以及Math类提供的各种方法来进行数学计算 - 在算术运算时发生的两种溢出
上溢出:算数结果超出取值范围(或者除以0时)。不会发生错误,而是显示无穷值,即:
+/-Infinity
下溢出:JavaScript中最接近0的数为Number.MIN_VALUE,当结果比这个值还接近0时,返回+/-0
NaN,与1,2,3也是一个Number类型,但是表示的含义为 Not a Number。任何无法转换成数值的数据做算数操作结果都是NaN。它与任何值都不相等,包括自己。需要Number.isNaN(x)判断NaN和Infinity为全局常量,只会在做数学运算时产生这两个值(老是弄不清楚在什么时候产生)- 在JavaScript中,-0于0相等
三、字符串
- 空串长度为0
- 字符串可以用
'' , "" , 反引号(``)包裹 - 字符串行尾添加反斜杠可以把字符串分行
1.字符串模板字面量
- 使用模板字面量需要反引号,反引号内可以是任何表达式,而最终的字符串就是表达式所求的值
let name = 'li';
function fun() { return 'zs' }
let n = `${name}`// n = 'li'
let n = `${fun()}`// n = z
四、布尔值
- 6种假性值可以转换成布尔值false,
undefined,null, 0, -0, NaN, "" - 布尔值只有一个
toString()方法,用来将值转换成字符串
五、null与undefined
null值是Null类型的唯一成员,null表示的含义为'对象为空'- 变量未初始化,数组的元素和对象的属性不存在时去访问是
undefined。函数的形参没有传递实参时是undefined,函数未指定返回值默认返回undefined
六、符号
- 符号类型的值一般用于当作属性名
- 符号不能像其他基础类型一样
let i = 1使用字面量语法获取值,获取符号类型的值需要调用符号的构造函数Symbol([x]),所以使用这种方式获取的符号值都是唯一不重复的,因为内存地址不同。 - 使用
Symbol.for(x)获取'x'对应的符号
七、类型转换
- JavaScript中尽量不要隐式转换,有时候会出现问题,
NaN和""都是false,但是它们不相等 - 使用
Boolean(),Number(),String(),进行显示转换 - 某些操作符会进行隐式类型转换,
+转数值,!转布尔再取反,可以利用这种特性来进行数据类型转换。 parseInt/Float()是全局函数,字符串转数值用,比如字符串"120px"可以转成数值120- 原始值中的
+操作符,有字符串参与做字符串拼接。没有字符串则全转换成数值相加
八、对象到原始值的转换
toString()方法默认返回[object,Object],JavaScript的内置对象,比如Array,Funcation,Number重写了toString()所以不会返回默认值valueOf()方法,大体把它看作是,把对象转换成原始值(如果这个值存在)的方法。但是大多数对象无法转换成原始值,这种情况默认返回对象本身
九、变量的声明与赋值
- ES6之前使用
var关键字声明,ES6之后使用let(变量)和const(常量) - 声明不赋值默认值为
undefined,const声明必须赋值 let和const声明的变量,常量具有块级作用域(块级作用域解释在下面),语法可以看作与Java相同let和const在同一个作用域中不能重复声明同名变量,但是var可以
十、var声明的变量的特殊性(接九)
- 使用var关键字声明的变量全局变量会成为全局对象window的属性。
- var声明的变量没有块级作用域,即
{}作用域,只有函数作用域和全局作用域
(1)换句话说:只要不是函数体内
var声明的变量都是全局变量
(2)例子:例如if(){},for(){},while(){},都是块级作用域,而funcation fun(){}是函数作用域也就是局部作用域
(3)区分函数作用域与块级作用域
- var声明的变量不能使用delete删除
- 注意:不使用关键字任何声明的变量也是全局变量(避免使用,但是可以使用delete删除)
- 使用
var关键字声明的变量会导致声明提前
function test() {
function t2() {
console.log(a);//undefined,因为a提前声明了,但是没赋值
//这里的 var a = 10; 因为var声明提前的特性,var会在当前函数的最顶层声明(可以看作第一行声明),但是赋值会在当前行赋值
var a = 10;
}
t2()
console.log(a);//报错,在外部函数中找不到变量a
}
test()
- 尽量使用
let和const,因为var的语法十分不严谨,容易出现各种意外错误。举个例子
十一、解构赋值
- 什么意思:只使用一个声明关键字,不使用逗号分隔,同时给多个变量赋不同的值。左侧是数组,右侧是数组或者可迭代的对象
let [x, y] = [1, 2];
let { x, y } = { x: 1, y: 2 }
-
当一个函数返回一个数组时,这个数组的元素当作值赋给其他变量。可以使用解构赋值接收
-
当解构赋值左右侧的变量数量不一定相同,左侧多出来的赋
undefined,右侧则忽略,并且右侧给左侧赋值是按照顺序的,就是按照逗号的顺序来赋值 -
对象的解构赋值
//结构赋值迭代对象
let obj = { a: 1, b: 2 }
for (let [key, value] of Object.entries(obj)) {
console.log(key, value)// a 1, b 2
}
//使用对象解构赋值,左侧也要写{},并且里面的变量名和右侧属性的属性名必须相同
let { a: a1, b: b1 } = { a: 1, b: 2 }
console.log(a)
console.log(b)
- 解构赋值还可以使用
...把右侧剩余的值全部保存在同一个变量中(不介绍) - 解构赋值还可以在左右侧嵌套数组进行赋值。但是会让代码变得复杂
我的问题
- 字符串不可修改,也没有提供修改值的方法,那重新赋值属于什么?
- 类型转换时的偏数值算法和偏字符串的算法没掌握。
总结
- String类型
语法与Java一致,单双引号都可以
- Number类型分三类
(1)+/-Infinity,表示无穷大或者无穷小 (2)NaN,表示一个Number类型的字面量 (3)正常的数值
- Boolean
- Null
- Undefined
- Object