1 基础
约 2010 个字 102 行代码 预计阅读时间 8 分钟
Intro
JavaScript & ECMAScript
一般情况下我们认为两者等价
ECMAScript是一个标准,需要各个浏览器厂商进行实现JavaScript>ECMAScript,其完整实现囊括了ECMAScript,DOMandBOM.
- JavaScript 的特点
- 解释型语言
- 类似于 C & Java 的语法结构
- 动态语言
- 基于原型的面向对象
- JavaScript 的编写位置
- HTML 文件的
<script>标签中 - 外部文件中,并通过
<script>标签引入- 可以被不同文件引用,利用浏览器的缓存机制加快加载过程
- 用于引入外部文件的
<script>标签内书写的内容会被忽略(禁止吃里扒外)
- HTML 文件的
- 基本规则
- 严格区分大小写
- 每一条语句以
;结尾,不手写浏览器会自动添加(也可能加错) - 忽略多个空格和换行
1 字面量 & 变量
-
字面量
一些不可改变的值(如
1/1000),可以直接使用(但一般不直接用) -
变量
可以用于保存字面量,其值可以任意改变;
简单的变量声明:
var a,此时我们尚未赋值,a = undefined
标识符命名规则
在 JS 中,所有支持自主命名的都称为“标识符”(如 变量名 / 函数名 / 属性名),需要满足以下规则:
- 可以包含:字母、数字、下划线、$
- 不能以数字开头
- 不能是 ES 中的 关键字 / 保留字
- 建议使用小驼峰命名法
JS 底层使用 Unicode 编码保存标识符,理论上支持 utf-8
中的所有内容(比如中文)
使用
XXXX表示Unicode字符的十进制编号:
JS 中使用
\uXXXX输出HTML 中使用
&#XXXX输出
1.1 基本数据类型
JS 中共包含六种数据类型:
- 基本数据类型:
String,Number,Boolean,Null,Undefined- 引用数据类型:
Object我们可以使用
typeof varName简单检查变量的类型。
String
- 需要使用引号包裹(单双都行,但不要混用)
- 引号不能嵌套(可以大肠包小肠,但是自产自销时需要用
\进行转义) - 特殊符号也需要使用
\进行转义
Number
整数计算精度有保障,但是浮点数就 emmm ...
- JS 中的所有数值都属于 Number 型(整数 & 浮点数)
-
最值与无穷
- 最大值
Number.MAX_VALUE= \(1.7976931348623157*10^{308}\),超过这个值将返回Infinity - 最小值是最大值的相反数,超过则返回
-Infinity Number.MIN_VALUE= \(0.5*10^{323}\) 表示支持的最小正值
Infinity是一个类型为 Number 的字面量,我们可以通过var a = Infinity进行赋值 - 最大值
-
NaN表示 Not a Number,是一个 Number 型的字面量
Boolean
true or false
Null
只有 null 值,表示 空对象,使用 typeof 返回 Object
Undefined
只有 undefined 值,表示 未定义(声明但没赋值)
1.2 强制类型转换
转 String
关于 toString 方法
toString方法不会改变原变量的类型,而是返回一个 String 型的执行结果Null&Undefined类型没有toString方法,调用时会报错
- 调用被转换数据类型的
toString方法 - 调用
String函数- 对于 Number / Boolean 类型,直接调用
toString方法 - 对于 Null / Undefined 类型,直接转为字符串
- 对于 Number / Boolean 类型,直接调用
转 Number
-
使用
Number函数Type Result 存在非数字内容 NaN空串 / 纯空格 0 true1 false0 null0 undefinedNaN -
使用
parseInt / parseFloat函数(String 类型专用)-
提取从头开始匹配的最长连续字串
parseInt("123px456") => 123parseFloat("123.456.789") => 123.456
-
对「非 String 类型」调用会先转换为 String,再进行对应转换。
parseInt(true) => parseInt("true") => NaN- 甚至可以悄悄取整
parseInt(198.23) => parseInt("198.23") => 198
-
进制转换
-
非十进制的表示
进制 前缀 示例 16 0x0x12f8 00702 0b0b1010console.log()均以十进制输出结果- 不是所有浏览器都支持以
0bxxx表示二进制数
-
指定进制解析
- 场景:
parseInt("070")视浏览器可能被解析为 \(56_o\) 或 \(70_d\) - 解决:传入第二个参数指定进制
parseInt("070", 8) === 56
- 场景:
转 Boolean
使用 Boolean 函数,转换规则如下:
| Input | Result |
|---|---|
| 一般数字 | true |
| 0 | false |
NaN |
false |
| 一般字符串 / 纯空格 | true |
| 空串 | false |
null |
false |
undefined |
false |
Object |
true |
1.3 包装类
用于将「基本数据类型」转换为「对象」
-
JS 中存在三个包装类
String(),Number(),Boolean()var num = new Number(3); // typeof num 返回 Object(而非 Number) // 注意:实际开发时不会使用(比较结果不符合预期) var n1 = 3; var n2 = 3; n1 == n2; // => true var n3 = Number(3); var n4 = Number(3); n3 == n4; // => false 对象地址不同 // 以及 Boolean 对象作为条件 var b = new Boolean(false); if(b) console.log("ok"); // 会输出 ok(Object 转 Boolean 为 true) -
我们可以为包装类对象添加属性
-
当我们试图调用「基本数据类型」的 属性/方法 时,浏览器会临时使用包装类将其转换为对象
1.4 String 对象方法
包装类的存在使得我们可以直接使用 String 对象的方法
-
String 在底层是以「字符数组」的形式保存的
- 可以通过
str.length获取字符串长度 - 可以通过
str[idx]获取指定位置上的 char
- 可以通过
-
下面是一些方法
方法 描述 charAt(idx)返回 str[idx]charCodeAt(idx)返回 str[idx]的 Unicode 编码fromCharCode(charCode)从字符编码创建一个字符串 concat(str1, str2, ...)拼接多个字符串 indexOf("str", start)返回从 start开始首次出现该子串的起始下标,不存在时返回 -1lastIndexOf("str")返回最后一次出现该子串的起始下标,不存在时返回 -1 slice(start, end)返回 str[start, end)子串,不影响原串(允许传入负数)subString(start, end)和 slice 类似(不允许传入负数,且 p2<p1 时自动交换) subStr(start, len)不太建议使用 split("指定分隔符")将 String 拆分为 Array (不指定/指定空串会逐个拆开) toLowerCase()/toUpperCase()大小写转换
2 基本运算
2.1 运算符
-
类型运算符
typeof将值的类型以 String 形式返回
-
算数运算符(二元)
-
+(左结合)-
String + 任意类型,将“任意类型值”转换为 String,随后进行
concat我们可以使用
var + ''将任意数据类型转为 String(隐式类型转换,由浏览器自动调用toString函数) -
Number + 任意非String类型,会对非 Number 的值进行转换后运算
- 任何值与
NaN运算均返回NaN-*/会把两侧的数据均转换为 Number
可以使用
var -0 / *1 / /1将任意数据类型专为 Number -
-
%朴素的取模
-
-
一元运算符
+-正负号,会将非 Number 转为 Number++--自增自减++a先递增再返回结果a++先返回结果再递增
-
逻辑运算符: 非 Boolean 类型会先进行转换
-
!非可以使用
!!var快速将变量转为 Boolean -
&&与- 第一个条件失败后,不会执行第二个条件
True && Ture,返回后面的 True 结果- 存在 False 时,返回首个 False 结果
||或- 第一个条件成功后,不会执行第二个条件
Ture || ?,返回首个 Ture 结果False || ?,返回第二个结果
-
-
赋值运算符
=+=-=*=/=%= -
关系运算符
>>=<<=- 会将非 Number 转换为 Number,返回 Boolean
- 符号两侧均为 String 时,直接逐位比较 Unicode 编码
- 任何值与
NaN比较均返回false
-
相等运算符
-
==会自动将两侧转为相同类型进行比较(大部分情况下转 Number)-
undefined == null -> true -
NaN == Anything -> false(包括NaN == NaN,需要用isNaN函数判断)
-
-
===全等(不会做类型转换,类型不同直接false) !=不等,!==不全等
-
-
条件运算符(三元)
condition?case1:case2当 condition 的结果非 Boolean 类型时会进行转换
2.2 优先级
序号越大优先级越低,平级时左结合
.[]new()++--!~+/- 符号typeofvoiddelete%*/+/- 加减法<<>>>>><<=>>===!====!==&^|&&||?:=+=-=/=*=%=<<=>>=>>>=&=^=|=
3 语句
获取用户输入
您可以使用 prompt("提示语句") 弹出弹窗以获得用户输入:
-
IF 多分支模版
-
Switch 模版
-
While 模版
-
For 模版
- 执行顺序:初始化 -> 判断条件 -> 循环体 -> 更新
- 初始化/条件/更新都可以 省略 or 写在外面(要留
;)
-
break & continue
- break 可用于退出最近的一层 switch / 循环语句(不能用于 IF)
- continue 可以用于逃过当次循环的余下部分(作用于最近的循环)
使用 Label 标识循环语句
我们可以通过 labelName:循环语句 的形式进行标识
4 作用域 Scope
变量作用的范围
-
JS 共有两种作用域
-
全局作用域
- 页面打开时创建,关闭时销毁
- 不被函数包裹的代码均在全局作用域中
-
具有代表浏览器窗口的全局对象
window,可以直接使用在全局作用域中创建的变量都会作为「window 的属性」保存,可以在任意位置访问
在全局作用域中创建的函数都会作为「window 的方法」保存
-
变量的声明提前
使用
var声明的变量将在「所有代码执行前」被定义(但没有赋值!) -
函数的声明提前
以「声明」形式创建的函数会在所有代码执行前被创造(可以在声明前调用)
-
函数作用域
- 调用函数时创建,执行完毕后销毁(每调用一次就会创建一个独立的作用域)
- 可以访问全局变量,但是全局作用域不能访问函数作用域中变量(
var定义) -
局部变量与全局变量同名时,优先使用局部变量(可以用
window.name强行指定)本地不存在时,逐层向上一级查找(直至全局作用域,还是没有报
ReferenceError) -
也存在「声明提前」
var a = 123; function f() { console.log(a); // 输出 undefined -> 局部声明提前 var a = 234; a = 345; // 就是全局变量(没有提升),上面输出 123(全局值) b = 567; // 没有使用 var 关键字 => 定义了变量 b subF(); // 函数声明提前,正常调用 function subF() {console.log("subF")}; } console.log(a); // 若没有 var => c 就是全局变量,输出 345 console.log(b); // 正常输出 567(在函数中定义了全局变量) // 参数列表相当于 var params; var e = 111; function f2(e) { // 等同于 var e console.log(e); // => undefined e = 222; // => 修改的是局部变量 }
-
5 垃圾回收 GC
- 「垃圾」
- 当一个对象没有任何变量或属性对其进行引用时,我们将永远无法对其进行操作
- 「垃圾」会占用大量内存空间,导致程序运行速度变慢
-
JS 的「垃圾回收机制」
JS 会「自动」将垃圾从内存中销毁(不允许进行手动操作)
但是我们不手动将不再使用的变量指向
null,JS 将无法进行识别