1. 变量(variable)

它不是具体的值,只是一个用来存储具体值的容器或者代名词,因为其存储的值可变,所以称为变量。

1.1 创建变量的方法

基于 ES 语法规范,在 JS 中创建变量有以下 6种 方式:

  • var (ES3)

  • function (ES3)创建函数(函数名也是变量,只不过存储的值是函数类型的而已)

  • let (ES6)

  • const (ES6)创建的是常量

  • import (ES6)基于 ES6 的模块规范导出需要的信息

  • class (ES6)基于 ES6 创建类

  1. /*
  2. * 语法:
  3. * var [变量名] = 值;
  4. * let [变量名] = 值;
  5. * const [变量名] = 值;
  6. * function [函数名]() {
  7. * }
  8. * ...
  9. */
  10. var n = 13; // n: 13
  11. n = 15; // n: 15
  12. let m = 100; // m: 100
  13. m = 101; // m: 101
  14. const o = 10; // o: 10
  15. o = 13; // Uncaught TypeError: Assignment to constant variable.

1.2 命名规范

创建变量,命名的时候要遵循一些规范。

  • 严格区分大小写

  • 遵循驼峰命名法:按照数字、字母、下划线或者 $ 来命名(数字不能作为开头),命名的时候基于英文单词拼接成一个完整的名字(小驼峰第一个单词小写,其余每一个有意义单词的首字母都大写)

  • 不能使用关键字和保留字:在 JS 中有特殊含义的叫做关键字,未来可能会成为关键字的叫做保留字

  1. var n = 12;
  2. var N = 13; //=> 两个 n 不是同一个变量
  3. // 命名方法
  4. studentInfo
  5. student_info
  6. _studentInfo (下划线在前的,一般都是公共变量)
  7. $studentInfo (一般存储的是 JQ 元素)
  8. // 语义化强一些
  9. add / create / insert
  10. del(delete) / update / rm(remove)
  11. info / detail
  12. log
  13. ...

2. 数据类型

数据值是一门编程语言进行生产的材料,JS 中包含的数值有以下这些类型:

  • 基本数据类型

    • 数字 number

    • 字符串 string

    • 布尔 boolean

    • null

    • undefined

  • 引用数据类型

    • 对象 object

      • Object 类型

      • Array 类型

      • RegExp 类型

      • Date 类型

      • Function 类型 (函数也是特殊的对象)

      • 基本包装类型

  • ES6 中新增加的一个特殊的类型:Symbol,唯一的值

总共 7 种数据类型:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)、Symbol

  1. // [基本数据类型]
  2. var n = 13; //=> 0 -13 13.2 数字类型中有一个特殊的值 NaN(not a number代表不是一个有效的数字,但是属于number类型)
  3. var s = ''; //=> "" '13' "{}" JS 中所有用单引号或者双引号包裹起来的就是字符串,里面的内容是当前字符串中的字符(一个字符串有零到多个字符组成)
  4. var b = true; //=> 布尔类型只有两个值,true真 false假
  5. // [引用数据类型]
  6. var o = {name: 'aa', age: 24}; //=> 普通对象,有大括号包裹起来,里面包含多组属性名和属性值(包含多组键值对) {}空对象
  7. var arr = [12, 23, 34]; //=> 中括号包裹起来,包含零到多项内容,这种是数组对象 []空数组
  8. var reg = /-?(\d|([1-9]\d+))(\.\d+)?/g; //=> 有元字符组成一个完整的正则 //不是空正则是单行注释
  9. function fn() {
  10. }
  11. // [Symbol] 创建出来的是一个唯一的值
  12. var a = Symbol('aa');
  13. var b = Symbol('aa');
  14. 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_INFINITYNumber.POSITIVE_INFINITY 保存着 Infinity-Infinity


NaN

NaN:not a number,但是它是数字类型

  • 用于表示一个本来要返回数值的操作数未返回数值的情况

  • 任何数值除以 0 会返回 NaN

  • 任何涉及 NaN 的操作都会返回 NaN

  • NaN 和任何值都不相等,包括 NaN 本身

  • isNaN() 函数,判断参数是否不是数值


isNaN 转换机制
isNaN:检测当前值是否不是有效数字,返回 true 代表不是有效数字,false 代表是有效数字

  1. // 语法:isNAN([value])
  2. var num = 12;
  3. isNaN(num) => false
  4. isNaN('13') => false
  5. isNaN('aa') => true
  6. isNaN(true) => false
  7. isNaN(false) => false
  8. isNaN(null) => false
  9. isNaN(undefined) => true
  10. isNaN({age: 9}) => true
  11. isNaN([12, 23]) => true
  12. isNaN([12]) => false
  13. isNaN(/^$/) => true
  14. isNaN(function() {}) => true

重要:isNaN`` 检测机制

  1. 先验证当前要检测的值是否是数字类型,如果已经是数字类型,是有效数字返回 false,否则返回 true(数字类型中只有 NaN 不是有效数字)

  2. 如果不是,浏览器会默认把值转换为数字类型

把非数字类型的值转换为数字

  • 其他基本类型转换为数字:直接使用 Number 方法转换
  1. // [字符串转数字]
  2. Number('13') => 13
  3. Number('12px') => NaN 如果当前字符串中出现任意一个非有效数字,结果为 NaN
  4. Number('13.5') => 识别小数
  5. Number('') => 0
  6. // [布尔转数字]
  7. Number(true) => 1
  8. Number(false) => 0
  9. // [其他]
  10. Number(null) => 0
  11. Number(undefined) => NaN
  • 把引用数据类型值转换为数字:先把引用值调用 toString 转换为字符串,然后再把字符串调取 Number 转换为数字
  1. // [对象]
  2. ({}).toString() => '[object Object]' => NaN
  3. // [数组]
  4. [12,23].toString() => '12, 23' => NaN
  5. [12].toString() => '12' => 12
  6. [].toString() => '' => 0
  7. // [正则]
  8. /^$/.toString() => '/^$/' => NaN

NaN 的比较

  1. NaN == NaN; //=> false NaN 和谁都不相等,包括自己

所以,不能使用 NaN 进行 == 以及 === 的判断,而使用 isNaN 也只能判断变量是否能转换为有效数字。

如果想检测 num 是否为一个有效数字(包含字符串形式 '13.5' 等 ),需要使用正则或者结合 typeofisNaN

  1. // 第一种方法
  2. var reg = /^(\-|\+)?(\d+\.?\d*|Infinity)$/;
  3. reg.test(num);
  4. // 第二种方法
  5. if (typeof num == 'number' && !isNaN(num)) {
  6. ...
  7. }

如果只是想判断字符串是否是有效数字,如用户从 input 输入的值等,可以直接使用 isNaN

  1. if (isNaN(str)) {
  2. //不是有效数字
  3. }

3.2 boolean

只有两个值:true / false

如何把其它数据类型转换为布尔类型?

  • Boolean

  • !

  • !!

  1. Boolean(1) => true
  2. Boolean(0) => false
  3. Boolean(-1) => true
  4. Boolean(NaN) => false
  5. !'aa' => 先把其它类型转换为布尔类型,然后取反
  6. !!null => 取两次反,相当于没取反,只是转换为布尔类型,与 Boolean 方法一样

规律:在 JS 中只有 0 / NaN / 空字符串 / null / undefined 这五个值转换为布尔类型的 false,其余都转换为 true

3. 3 null && undefined

都代表空或者没有

  • null:空对象指针

  • undefined:未定义

null 一般都是意料之中的,是人为手动的先赋值为 null,后面程序中我们会再次给他赋值

  1. var num = null; //=>后面会再进行赋值

只要意在保存对象的变量还没有真正保存对象,就应该明确的让变量保存为 null 值,且 null 在内存中是不占位置的,多用于初始化值

undefined 一般都不是人为手动控制的,大部分都是浏览器自主为空

  1. 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() 方法返回字符串的一个副本

    • nullundefined 没有这个方法

    • 可选参数,输出数值的基数。可以输出以十进制、二进制、八进制、十六进制等的字符串值,不包含前缀 00x

  • String() 转型函数

    • 将任何类型的值转换为字符串

    • 值有 toString() 方法,则调用该方法并返回相应的结果

    • 值为 null,返回 "null"

    • 值为 undefined,返回 "undefined"

3.5 object

普通对象

  • 由大括号包裹起来

  • 由零到多组键值对组成

属性是用来描述当前对象特征的,属性名是当前具备这个特征,属性值是对这个特征的描述。

专业术语:属性名为键 [key],属性值为值 [value],一组属性名和属性值为一组键值对。

  1. var obj = {
  2. name: 'aa', //=>属性名也可以直接写成字符串 'name': 'aa'
  3. age: 15
  4. }
  5. // 对象的操作:对键值对的增删改查
  6. [获取]
  7. 语法:对象.属性 / 对象['属性']
  8. obj.name
  9. obj['name'] 一般来说,对象的属性名都是字符串格式的
  10. 使用方括号语法就可以通过变量来访问对象属性
  11. 获取属性值的时候,如果当前对象有这个属性名,则可以正常获取到值(哪怕是 null),但是如果没有这个属性名,则获取的结果是 undefined
  12. obj.friends //=> undefined
  13. [增/改]
  14. JS 对象中属性名是不允许重复的,是唯一的
  15. obj.name = 'bb'; //=> 原有对象中存在 name 属性,此处属于修改属性值
  16. obj.sex = "man"; //=> 原有对象不存在 sex 属性,此处属于新增一个属性
  17. obj['age'] = 28;
  18. [删]
  19. 彻底删除,对象中不存在这个属性
  20. delete obj.age;
  21. 假删除,并没有移出这个属性,只是让当前属性的值为空
  22. obj.sex = null;

思考题:

  1. var obj = {
  2. name: 'aa',
  3. age: 9
  4. };
  5. var name = 'age';
  6. obj.name //=> 'aa'
  7. obj['name'] //=> 'aa'
  8. obj[name] //=> 9
  9. ----
  10. 'name' name 的区别?
  11. => 'name' 是一个字符串,代表本身
  12. => name 是一个变量,代表的是存储的值

一个对象的属性名不仅仅是字符串格式的,还有可能是数字格式的(数组)。

  1. var obj = {
  2. name: 'aa'
  3. 0: 12
  4. };
  5. obj[0] //=> 12
  6. obj['0'] //=> 12
  7. obj.0 //=> Uncaught SyntaxError: Unexpected number
  8. SyntaxError 语法错误

当我们存储的属性名不是字符串也不是数字的时候,浏览器会把这个值转换为字符串(String),然后再进行存储

  1. obj[{}] = 300;
  2. //=> 先把 ({}).toString()后的结果作为对象的属性名存储起来 obj['[object Object]'] //=> 300
  3. obj[{}] //=> 获取的时候也是先装换为字符串 '[object Object]',然后获取之前存储的 300

数组对象

  1. var arr = [12, 23]; //=> 12 和 23 都是属性值
  2. arr[0] //=> 12
  3. arr['age'] = 23;
  4. arr //=>[12, 23, age: 23]

通过控制台观察结果,数组对象的属性名是数字,我们把数字属性名称为当前对象的索引