JavaScript 变量
概述
把一个具体的值存入到变量中。那么此时这个变量就代表着我们这个具体的值。我们如果想要重新的使用这个值,不再需要重新的计算或者其他操作,直接使用变量就可以得到之前存储的这个值。
简单的说,变量就是一个保存数据的容器,调用变量就是调用保存在这个容器中的值。
变量之所以叫做变量,是因为变量随时可以根据我们的需要去改变其中存储的值
注:变量本身没有数据类型,只能根据存储的值来判断数据类型。
创建一个变量
声明关键字,如:var、let
var
声明一个变量,可选初始化一个值。
let
声明一个块作用域的局部变量,可选初始化一个值。
声明变量的三种方式:
使用关键词 var
var a = 42; // 可以用来声明局部变量和全局变量。
直接赋值(不推荐)
b = 42;// JS 的小 bug,这样写会产生一个全局变量
这种方式在严格模式下会出错,也没人会用这种方式声明变量,不建议使用这种方式。
使用关键词 let
let c = 12; // 用来声明块作用域的局部变量。
声明变量的底层原理
我们所写的程序运行在内存中,当我们使用关键字声明一个变量的时候,计算机会从内存中划分一个空间,为我们存放不同类型的内容做准备
变量的命名规则
1. 由数字、字母、下划线( _ )、$ 组成。
不能由数字开头
不能包含星号 ( * )
不能包含加号
不能包含减号或者连词线
字母可以是大写,也可以是小写。
2. 语义化,看其名知其意,前缀就可以表示出变量的类型
3. 不允许使用关键字和保留字。
4. 如果变量名由多个单词组成,要使用驼峰式命名法
大驼峰:从第一个单词的首字母开始大写。
小驼峰:从第二个单词的首字母开始大写。
注:JS 对大小写敏感,a 和 A 是不同的。
var a = 1; var A = 2; console.log(a); // 1 console.log(A); // 2
变量也叫做标识符。
变量的存储
重新存储数据
当我们重新的向变量中存储数据的时候,不需要再加 var
var a = 10; a = 20;
上面我们将变量 a 内存储的数据由10变成了20,在重新存储的过程中,我们并没有使用 var,那么上面的代码就相当于我们将20的值存储到之前创建的变量 a 中
重新声明变量
如果在重新存储数据的过程中,没有在变量名前面加 var,那么相当于是更改变量 a 中存储的值,而如果前面加了 var,则相当于重新的创建了一个变量 a,并且存储了这个数据。
var a = 10; // 第一次声明变量 a var a = 20; // 再一次通过 var 声明变量 a,并且使用了 var
虽然最后的结果和上面的打印结果相同,但是变量 a 本质上已经发生了变化 (存储的地址变了)
如果采用以下方式,那么重新创建的变量将会无效:
var x = 1; var x;
变量提升
JS 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果就是所有的变量的声明语句,都会被提升到代码的头部。
console.log(a); var a = 1;
上面代码首先使用 console.log 方法,在控制台 (console) 显示变量 a 的值。这时变量 a 还没有声明和赋值,所以这是一种错误的做法,但是实际上不会报错。因为存在变量提升,真正运行的是下面的代码
var a; console.log(a); a = 1;
最后的结果是显示 undefined,表示变量 a 已声明,但还未赋值
关键字的介绍
关键字
关键字用于执行特定操作等。按照规则,关键字也是语言保留的,不能用做变量。
常见的关键字
break、do、instanceof、typeof、case、else、new、var、catch、finally、return、void、continue、 for、switch、while、debugger、function、this、with、default、if、throw、delete、in、try
保留字
未来可能做为关键字的存在
常见的保留字
abstract、enum、int、short、boolean、export、interface、static、byte、extends、long、super、 char、final、native、synchronized、class、float、package、throws、const、goto、private、 transient、implements、protected、volatile、double、import、public
基本上这些关键字和保留字都是一些语义强烈的词语。
Java Script 数据类型
数据类型
什么是数据类型?
变量用来临时存储数据(如果想要永久的存储数据,需要通过数据库)。而在任何一门编程语言当中,数据都是分为不同类型的。就如同人类也分为男人和女人一样。
基本数据类型
基本数据类型也叫做 值类型、原始类型;有六种
String 字符型
1. 单引号字符串的内部,可以使用双引号。双引号字符串的内部,可以使用单引号
2. 如果要在单引号字符串的内部,使用单引号,就必须在内部的单引号前面加上反斜杠,用来转义。双引号字符串内部使用双引号,也是如此。
'Did she say \'Hello\'?'
3. 如果长字符串必须分成多行,可以在每一行的尾部使用反斜杠
var longString = 'Long \ long \ long \ string'; // Long long long String
反斜杠后面必须是换行符
4. 字符串默认只能写在一行内,分成多行将会报错
5. 连接运算符(+)可以连接多个单行字符串,将长字符串拆成多行书写,输出的时候也是单行
6. 转义字符: 反斜杠(\)在字符串内有特殊含义,用来表示一些特殊字符,所以又称为转义符,以下有几种常见的转义符:
\0 : null (\u0000) \b :后退键 (\u008) \f :换页符 (\u000C) \n :换行符 (\u000A) \r :回车键 (\u000D) \t :制表符 (\u0009) \v :垂直制表符 (\u000B) \' :单引号 (\u0027) \" : 双引号 (\u0022) \\ :反斜杠 (\u005C)
注:只要被引号包裹起来的就是字符('',"") -> "hello"
Number 数字型
JS 的64位浮点数之中,有一个二进制位是符号位。这意味着,任何一个数都有一个对应的负值,就连0也不例外,几乎所有场合,正零和负零都会被当作正常的0,但是当0和-0被充当分母的时候,返回的值是不相等的,除以正零得到+Infinity,除以负零得到-Infinity
NaN
NaN 是 JS 的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合
NaN不是独立的数据类型,而是一个特殊数值,它的数据类型依然属于Number(NaN本身是数字类型)
不是一个数字的数值型数据 -> 代表意外或非法转换的数字
NaN不等于任何数值,包括它自己,即有NaN参与的计算都不会相等
检查一个参数是否是非数字值
isNaN(x)函数用于检查其参数是否是非数字值
如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false
true 不是一个数字 false 是一个数字
当值是0时,返回的值仍为 true
Number 中的全局方法
parseInt()、parseFloat()、isNaN、isFinite
parseInt
parseInt() /* 将字符串转为整数 parseInt('123') // 123 如果字符串头部有空格,空格会被自动去除 parseInt(' 81') // 81 如果parseInt的参数不是字符串,则会先转为字符串再转换 parseInt(1.23) // 1 // 等同于 parseInt('1.23') // 1 字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分 如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN */
parseInt的返回值只有两种可能,要么是一个十进制整数,要么是NaN
parseFloat
parseFloat() /* parseFloat方法用于将一个字符串转为浮点数 parseFloat('3.14') // 3.14 如果字符串符合科学计数法,则会进行相应的转换 parseFloat('314e-2') // 3.14 parseFloat('0.0314E+2') // 3.14 如果字符串包含不能转为浮点数的字符,则不再进行往后转换,返回已经转好的部分 parseFloat('3.14more non-digit characters') // 3.14 parseFloat方法会自动过滤字符串前导的空格 parseFloat('\t\v\r12.34\n ') // 12.34 如果参数不是字符串,或者字符串的第一个字符不能转化为浮点数,则返回NaN parseFloat([]) // NaN parseFloat('FF2') // NaN parseFloat会将空字符串转为NaN parseFloat('') // NaN */
inFinite
isFinite() /* 返回一个布尔值,表示某个值是否为正常的数值 isFinite(Infinity) // false isFinite(NaN) // false 除了Infinity、-Infinity、NaN和undefined这几个值会返回false,isFinite对于其他的数值都会返回true */
注:JS 中的数字类型,只有 Number
Boolean 布尔型
true、false
返回 boolean 的运算符
逻辑运算符、比较运算符
undefined 未定义
没有被赋值的变量的类型就是 undefined
null 空值
null 只有一个值,就是它本身
null 类型为 Object、但是不能叫它空对象(这是 JS 中的一个 bug)
Symbol 一种实例 (ES6新增)
一种实例是唯一且不可改变的数据类型
引用类型
引用类型也称之为对象类型、复杂数据类型
对象 Object、数组 Array、函数 Function
Object
一般是 {},标签的数据类型都是 Object
Array
一组“成员”,一般是 []
Function
标志是,function
数据类型转换
自动类型转换
转换的规则
预期什么类型的值,就调用该类型的转换函数。比如,某个位置预期为字符串,就调用String函数进行转换。如果该位置即可以是字符串,也可能是数值,那么默认转为数值
利用算术运算符
console.log(+str); console.log(str - 0); console.log(str * 1); console.log(str / 1);
注:如果字符串无法全都转为数字,则会变为 NaN
利用算术运算符的 +,进行字符串的拼接
由于自动转换具有不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用Boolean、Number和String函数进行显式转换
强制类型转换
Number
规则:
严格转换,能识别小数点,不能出现非数字,出现就会NaN
空字符串会转为 0
自动过滤一个字符串前导和后缀的空格
布尔值:true 转成 1,false 转成 0
undefined:转成 NaN
Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组
Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组,如:
转换对象:Number({a: 1}) // NaN Number([1, 2, 3]) // NaN Number([5]) // 5
Number 示例:
转换基本数据类型:// 数值:转换后还是原来的值 Number(324) // 324 // 字符串:如果可以被解析为数值,则转换为相应的数值 Number('324') // 324 // 字符串:如果不可以被解析为数值,返回 NaN Number('324abc') // NaN // 空字符串转为0 Number('') // 0 // 布尔值:true 转成 1,false 转成 0 Number(true) // 1 Number(false) // 0 // undefined:转成 NaN Number(undefined) // NaN // null:转成0 Number(null) // 0
其他方法:
parseInt()、parseFolat()、isNaN
isNaN
isNaN 方法可以用来判断一个值是否为NaN isNaN(NaN) // true isNaN(123) // false isNaN(x) 如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false true 不是一个数字 isNaN("hello world"); -> true false 是一个数字 isNaN(123); -> false isNaN只对数值有效,如果传入其他值,会被先转成数值 isNaN('Hello') // true // 相当于 isNaN(Number('Hello')) // true isNaN为true的值,有可能不是NaN,而是一个字符串 比如,传入字符串的时候,字符串会被先转成NaN,所以最后返回true 由于 NaN 的意思是 not a numer ,所以isNaN判断时,本身是双重否定,true 也就代表着是 NaN,即不是一个数字 当值是0时,返回的值仍为 true
String
转换基本数据类型: 数值:转为相应的字符串。 字符串:转换后还是原来的值。 布尔值:true转为字符串"true",false转为字符串"false"。 undefined:转为字符串"undefined"。 null:转为字符串"null"
转换对象: String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式
其他方法:
toString()
方式:直接转换,相当于给数值添加两个引号
var num1 = 123; var str1 = num1.toString(); console.log(str1); // 123 -> 字符串 var num2 = NaN; var str2 = num2.toString(); console.log(str2); // NaN -> 字符串
可以接受参数:
toString(8); toString(16); toString(32); ...
参数时进制,结果也是以进制表示的数字
toFixed()
主要作用是保留小数位,顺带着转变数据类型
var num = 123.456; var str = num.toFixed(2); console.log(str); // 123.46 -> 字符串
保留 n 位小数的时候会自动四舍五入。
Boolean
可以将任何类型的值转为 布尔值
规则:除了以下五个值的转换结果为 false,其他的值全部为 true
undefined null 0(包含-0和+0) NaN "" ''(空字符串
true 和 false 这两个布尔值不会发生变化
所有对象(包括空对象)的转换结果都是true,甚至连 false 对应的布尔对象new Boolean(false)也是true
注意:" " 并不是空字符串,看不见的缩进和空格也是字符
JavaScript 运算符
算术运算符
+ 加法运算 - 减法运算 * 乘法运算 / 除法运算 % 取余运算(求模运算) ** 指数运算符
加法运算符有字符串拼接的作用
规则:只要 + 两边出现一个字符,那么就会将两边的值连在一起,成为字符串;只有 + 两边都是数字的时候才是加法运算
下面是一些常见的 + 连接:
1 1 + null // 1 2 1 + true // 2 3 1 + false // 1 4 1 + NaN // NaN 5 1 + "hello" // 1hello 6 1 + undefined // NaN 7 1 + [3,4,5,6] // 13,4,5,6 8 + 如果跟 空字符串("")一起,那么会成为0 9 1+ {} -> 1 + {name:"admin"} // 1[object Object]->只拿到了标志,没拿到值
赋值运算符
赋值运算符,是基于右值,给左值赋值。如:
var a = 10; var b = 11; console.log(a); // 10 console.log(b); // 11
把一个值赋给一个变量,为了把一个值赋给多个变量,可以以链式使用赋值运算符
一些常用的赋值运算符:
加赋值 x += y 加法运算,相当于 x = x + y 减赋值 x -= y 减法运算,相当于 x = x - y 乘赋值 x *= y 乘法运算,相当于 x = x * y 除赋值 x /= y 除法运算,相当于 x = x / y 模赋值 x %= y 取余,相当于 x = x % y
赋值运算符的隐式数据类型转换规则,参考算术运算符 (数据类型时会有 类型转换的问题)。
自增和自减
++
++ 等价于 += 1
前自增
先运算,后赋值
var a = 1; ++a; // a = 2 console.log(a): // 2
前自增是先加1,再使用操作数的值
后自增
先使用最初值,后运算
var b = 2; b++; // b = 2; console.log(b); // 3
后自增是先使用操作数的值,再加1
--
自减的原理和自增相同,只是自减是减法。前自减和后自减参考自增。
小练习
var a = 12; var sum = a++ + ++a + ++a * 2 + a-- + a--; console.log(sum + "" + a); /* 算 sum 的值 a++ a 是 12 ++a ++13, 之后 a 是14 ++a * 2,15 * 2 a-- 15 -1 a -- 14 - 1 最后得出 a 是 13 sum = 12 + 14 + 15 * 2 + 15 + 14 == 85 输出结果为 8513 */
比较运算符
等于 == 如果两边操作数相等时返回 true 不等于 != 如果两边操作数不相等时返回 true 全等 === 两边操作数相等且类型相同时返回 true 不全等 !== 两边操作数不相等或类型不同时返回 true 大于 > 左边的操作数大于右边的操作数返回 true 大于等于 >= 左边的操作数大于或等于右边的操作数返回 true 小于 < 左边的操作数小于右边的操作数返回 true 小于等于 <= 左边的操作数小于或等于右边的操作数返回 true
注:
1. 一个字符和一个数值比较,会把字符转换成数值,之后再比较
2. 当比较运算符的两边都是字符时,比较规则为字符的逐位比较
只比较字符中首位数字,后面的不再进行比较
逻辑运算符
逻辑运算符常用于布尔(逻辑)值之间; 当操作数都是布尔值时,返回值也是布尔值。 不过实际上 && 和 || 返回的是一个特定的操作数的值,所以当它用于非布尔值的时候,返回值就可能是非布尔值。
且 &&
如果第一个运算子的布尔值为 true,则返回第二个运算子的值(注意是值,不是布尔值);如果第一个运算子的布尔值为 false,则直接返回第一个运算子的值,且不再对第二个运算子求值。
&& 的两边,只要有其中一个是 false ,就返回 false;只有当两边都是 true 时,才返回 true
或 ||
如果第一个运算子的布尔值为 true,则返回第一个运算子的值,且不再对第二个运算子求值;如果第一个运算子的布尔值为 false,则返回第二个运算子的值
|| 的两边,只要有其中一个是 true,就返回 true
非 !
取一个值的反值。主要用于将一个布尔值变为相反值。即 true 变为 false,false 变为 true
不管什么类型的值,经过取反运算后都会变成布尔值
如果使用取反运算符的值不是一个布尔值,那么取反运算符就会将其变为一个布尔值,然后再取反
下面的六个值使用取反运算符取反后都为 true,其他都为 false
undefined null false 0 NaN 空字符串('')
如果对一个值连续做两次的取反运算,等于将其转换为对应的布尔值。这是一种较为常见的类型转换的方法,即 快速获取一个值得布尔类型表示 !!值
逻辑与运算符可以多个连用,这时返回第一个布尔值为 false 的表达式的值。如果所有表达式的布尔值都为 true,则返回最后一个表达式的值
条件运算符
条件运算符也叫做 三元运算符、三目运算符
条件 ? 值1 : 值2
如果条件为真,则结果取值1。否则为值2。你能够在任何允许使用标准运算符的地方使用条件运算符
逗号运算符
逗号操作符( , )
对两个操作数进行求值并返回最终操作数的值。它常常用在 for 循环中,在每次循环时对多个变量进行更新
运算符优先级
用于确定一个表达式的计算顺序。在你不能确定优先级时,可以通过使用括号显式声明运算符的优先级。