1. 变量(variable)
它不是具体的值,只是一个用来存储具体值的容器或者代名词,因为其存储的值可变,所以称为变量。
1.1 创建变量的方法
基于 ES 语法规范,在 JS 中创建变量有以下 6种 方式:
var
(ES3)function
(ES3)创建函数(函数名也是变量,只不过存储的值是函数类型的而已)let
(ES6)const
(ES6)创建的是常量import
(ES6)基于 ES6 的模块规范导出需要的信息class
(ES6)基于 ES6 创建类
/*
* 语法:
* var [变量名] = 值;
* let [变量名] = 值;
* const [变量名] = 值;
* function [函数名]() {
* }
* ...
*/
var n = 13; // n: 13
n = 15; // n: 15
let m = 100; // m: 100
m = 101; // m: 101
const o = 10; // o: 10
o = 13; // Uncaught TypeError: Assignment to constant variable.
1.2 命名规范
创建变量,命名的时候要遵循一些规范。
严格区分大小写
遵循驼峰命名法:按照数字、字母、下划线或者 $ 来命名(数字不能作为开头),命名的时候基于英文单词拼接成一个完整的名字(小驼峰第一个单词小写,其余每一个有意义单词的首字母都大写)
不能使用关键字和保留字:在 JS 中有特殊含义的叫做关键字,未来可能会成为关键字的叫做保留字
var n = 12;
var N = 13; //=> 两个 n 不是同一个变量
// 命名方法
studentInfo
student_info
_studentInfo (下划线在前的,一般都是公共变量)
$studentInfo (一般存储的是 JQ 元素)
// 语义化强一些
add / create / insert
del(delete) / update / rm(remove)
info / detail
log
...
2. 数据类型
数据值是一门编程语言进行生产的材料,JS 中包含的数值有以下这些类型:
基本数据类型
数字 number
字符串 string
布尔 boolean
null
undefined
引用数据类型
对象 object
Object 类型
Array 类型
RegExp 类型
Date 类型
Function 类型 (函数也是特殊的对象)
基本包装类型
…
ES6 中新增加的一个特殊的类型:Symbol,唯一的值
总共 7 种数据类型:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)、Symbol
// [基本数据类型]
var n = 13; //=> 0 -13 13.2 数字类型中有一个特殊的值 NaN(not a number代表不是一个有效的数字,但是属于number类型)
var s = ''; //=> "" '13' "{}" JS 中所有用单引号或者双引号包裹起来的就是字符串,里面的内容是当前字符串中的字符(一个字符串有零到多个字符组成)
var b = true; //=> 布尔类型只有两个值,true真 false假
// [引用数据类型]
var o = {name: 'aa', age: 24}; //=> 普通对象,有大括号包裹起来,里面包含多组属性名和属性值(包含多组键值对) {}空对象
var arr = [12, 23, 34]; //=> 中括号包裹起来,包含零到多项内容,这种是数组对象 []空数组
var reg = /-?(\d|([1-9]\d+))(\.\d+)?/g; //=> 有元字符组成一个完整的正则 //不是空正则是单行注释
function fn() {
}
// [Symbol] 创建出来的是一个唯一的值
var a = Symbol('aa');
var b = Symbol('aa');
a == b //=> false
拓展:JS 代码如何被运行以及运行后如何输出结果?
[如何被运行]
把代码运行在浏览器中(浏览器内核来渲染解析)
基于 NODE 来运行(NODE也是基于 V8 引擎渲染和解析 JS 的工具)
[如何输出结果]
alert
:在浏览器中通过弹框的方法输出(浏览器提示框)window.alert 省略 window,先计算结果再运行 toString
转化为字符串输出,最后都是输出字符串confirm
:和 alert
用法一致,只不过提示框中有确定和取消两个按钮,所以是确认提示框,会返回一个布尔值,来处理点击prompt
:在 confirm
的基础上增加输入框,返回输入的值,取消则返回 null``console.log
:在浏览器控制台输出日志,快捷键 [value].log
Elements:当前页面中的元素和样式在这里都可以看到,还可以调节和修改样式结构等
Console:控制台,可以在 JS 代码中通过 .log 输出到这里,也可以直接在这里编写 JS 代码
Sources:当前网站的源文件都在这里
network:通讯请求等信息
Application:localStorage、cookies、sessionStorage等等
…
console.dir``:比 log 输出的更详细一些(尤其是输出对象数据值的时候)
console.table``:把一个 JSON 数据按照表格的方式输出
…
3. 数据类型的详细剖析
3.1 number
整数
十进制
八进制
第一位必须是
0
,且数字序列是 0-7如果超出范围,则忽略前导 0,按十进制数解析
十六进制
前两位必须是
0x
,后面跟任意十六进制数字 0-9,A-F字母 A-F,可以大写,也可以小写
浮点数
必须包含小数点,且小数点后至少一位数字
如果小数点后没有跟任何数字,或者跟一个 0,会被自动转化为整数
科学计数法
等于 e 前面的数值乘以 10 的指数次幂
e 可以大写,也可以小写
默认情况下,自动将小数点后面带有 6 个零以上的浮点数值转化为科学计数法
精度
最高精度是 17 为小数,但计算时精度远远不如整数
计算时出现小小的舍入误差,
0.1+0.2 = 0.30000000000000004
是基于 IEEE754 数值的浮点计算的通病
导致无法测试特定的浮点数值,永远不要测试某个特定的浮点数值
数值范围
最小数值保存在
Number.MIN_VALUE
中,值为5e-324
最大数值保存在
Number.MAX_VALUE
中,值为1.7976931348623157e+308
超过数值范围的值,会被自动转换成
Infinity
值,且无法进行下次运算负数转换为
-Infinity
(负无穷),正值转换为Infinity
(正无穷)判断是否有穷,
isFinite()
函数,有穷则true
,无穷则false
在执行极小或者极大数值计算时,必须检查监控这些值
Number.NEGATIVE_INFINITY
和Number.POSITIVE_INFINITY
保存着Infinity
和-Infinity
NaN
NaN:not a number,但是它是数字类型
用于表示一个本来要返回数值的操作数未返回数值的情况
任何数值除以
0
会返回NaN
任何涉及
NaN
的操作都会返回NaN
NaN
和任何值都不相等,包括NaN
本身isNaN()
函数,判断参数是否不是数值
isNaN 转换机制isNaN
:检测当前值是否不是有效数字,返回 true
代表不是有效数字,false
代表是有效数字
// 语法:isNAN([value])
var num = 12;
isNaN(num) => false
isNaN('13') => false
isNaN('aa') => true
isNaN(true) => false
isNaN(false) => false
isNaN(null) => false
isNaN(undefined) => true
isNaN({age: 9}) => true
isNaN([12, 23]) => true
isNaN([12]) => false
isNaN(/^$/) => true
isNaN(function() {}) => true
重要:isNaN`` 检测机制
先验证当前要检测的值是否是数字类型,如果已经是数字类型,是有效数字返回
false
,否则返回true
(数字类型中只有NaN
不是有效数字)如果不是,浏览器会默认把值转换为数字类型
把非数字类型的值转换为数字
- 其他基本类型转换为数字:直接使用
Number
方法转换
// [字符串转数字]
Number('13') => 13
Number('12px') => NaN 如果当前字符串中出现任意一个非有效数字,结果为 NaN
Number('13.5') => 识别小数
Number('') => 0
// [布尔转数字]
Number(true) => 1
Number(false) => 0
// [其他]
Number(null) => 0
Number(undefined) => NaN
- 把引用数据类型值转换为数字:先把引用值调用
toString
转换为字符串,然后再把字符串调取Number
转换为数字
// [对象]
({}).toString() => '[object Object]' => NaN
// [数组]
[12,23].toString() => '12, 23' => NaN
[12].toString() => '12' => 12
[].toString() => '' => 0
// [正则]
/^$/.toString() => '/^$/' => NaN
NaN 的比较
NaN == NaN; //=> false NaN 和谁都不相等,包括自己
所以,不能使用 NaN
进行 ==
以及 ===
的判断,而使用 isNaN
也只能判断变量是否能转换为有效数字。
如果想检测 num 是否为一个有效数字(包含字符串形式 '13.5'
等 ),需要使用正则或者结合 typeof
和 isNaN
:
// 第一种方法
var reg = /^(\-|\+)?(\d+\.?\d*|Infinity)$/;
reg.test(num);
// 第二种方法
if (typeof num == 'number' && !isNaN(num)) {
...
}
如果只是想判断字符串是否是有效数字,如用户从 input
输入的值等,可以直接使用 isNaN
if (isNaN(str)) {
//不是有效数字
}
3.2 boolean
只有两个值:true / false
如何把其它数据类型转换为布尔类型?
Boolean
!
!!
Boolean(1) => true
Boolean(0) => false
Boolean(-1) => true
Boolean(NaN) => false
!'aa' => 先把其它类型转换为布尔类型,然后取反
!!null => 取两次反,相当于没取反,只是转换为布尔类型,与 Boolean 方法一样
规律:在 JS 中只有 0 / NaN / 空字符串 / null / undefined 这五个值转换为布尔类型的 false,其余都转换为 true
3. 3 null && undefined
都代表空或者没有
null:空对象指针
undefined:未定义
null
一般都是意料之中的,是人为手动的先赋值为 null
,后面程序中我们会再次给他赋值
var num = null; //=>后面会再进行赋值
只要意在保存对象的变量还没有真正保存对象,就应该明确的让变量保存为
null
值,且null
在内存中是不占位置的,多用于初始化值
undefined
一般都不是人为手动控制的,大部分都是浏览器自主为空
var num; //=> 此时浏览器自动给其分配为 undefined
注意: undefined
值派生自 null
值,null == undefined,结果为 true
3.4 string
由零个或多个 16 为 Unicode 字符组成的字符序列
特殊的字符字面量(转义序列)
字面量 | 含义 |
---|---|
\n | 换行 |
\t | 制表 |
\b | 退格 |
\r | 回车 |
\f | 进纸 |
\ | 斜杠 |
‘ | 单引号 |
“ | 双引号 |
\xnn | 以十六进制代码 nn 表示的一个字符 |
\unnn | 以十六进制代码 nnnn 表示的一个字符,如 \u03a3 表示Σ |
可以出现在任何位置,被当做一个字符来解析
字符串特点
字符串是不可变的,字符串一旦创建,它们的值就不能改变
要改变保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量
字符串转换
toString()
方法,返回相应值的字符串表现数值、布尔值、对象和字符串值都有一个
toString()
方法字符串的
toString()
方法返回字符串的一个副本null
和undefined
没有这个方法可选参数,输出数值的基数。可以输出以十进制、二进制、八进制、十六进制等的字符串值,不包含前缀
0
、0x
等
String()
转型函数将任何类型的值转换为字符串
值有
toString()
方法,则调用该方法并返回相应的结果值为
null
,返回"null"
值为
undefined
,返回"undefined"
3.5 object
普通对象
由大括号包裹起来
由零到多组键值对组成
属性是用来描述当前对象特征的,属性名是当前具备这个特征,属性值是对这个特征的描述。
专业术语:属性名为键 [key],属性值为值 [value],一组属性名和属性值为一组键值对。
var obj = {
name: 'aa', //=>属性名也可以直接写成字符串 'name': 'aa'
age: 15
}
// 对象的操作:对键值对的增删改查
[获取]
语法:对象.属性 / 对象['属性']
obj.name
obj['name'] 一般来说,对象的属性名都是字符串格式的
使用方括号语法就可以通过变量来访问对象属性
获取属性值的时候,如果当前对象有这个属性名,则可以正常获取到值(哪怕是 null),但是如果没有这个属性名,则获取的结果是 undefined
obj.friends //=> undefined
[增/改]
JS 对象中属性名是不允许重复的,是唯一的
obj.name = 'bb'; //=> 原有对象中存在 name 属性,此处属于修改属性值
obj.sex = "man"; //=> 原有对象不存在 sex 属性,此处属于新增一个属性
obj['age'] = 28;
[删]
彻底删除,对象中不存在这个属性
delete obj.age;
假删除,并没有移出这个属性,只是让当前属性的值为空
obj.sex = null;
思考题:
var obj = {
name: 'aa',
age: 9
};
var name = 'age';
obj.name //=> 'aa'
obj['name'] //=> 'aa'
obj[name] //=> 9
----
'name' 和 name 的区别?
=> 'name' 是一个字符串,代表本身
=> name 是一个变量,代表的是存储的值
一个对象的属性名不仅仅是字符串格式的,还有可能是数字格式的(数组)。
var obj = {
name: 'aa'
0: 12
};
obj[0] //=> 12
obj['0'] //=> 12
obj.0 //=> Uncaught SyntaxError: Unexpected number
SyntaxError 语法错误
当我们存储的属性名不是字符串也不是数字的时候,浏览器会把这个值转换为字符串(String),然后再进行存储
obj[{}] = 300;
//=> 先把 ({}).toString()后的结果作为对象的属性名存储起来 obj['[object Object]'] //=> 300
obj[{}] //=> 获取的时候也是先装换为字符串 '[object Object]',然后获取之前存储的 300
数组对象
var arr = [12, 23]; //=> 12 和 23 都是属性值
arr[0] //=> 12
arr['age'] = 23;
arr //=>[12, 23, age: 23]
通过控制台观察结果,数组对象的属性名是数字,我们把数字属性名称为当前对象的索引