JS基础
JS基础
作者:IT王小二
JS是什么
JS 是一种轻量级的脚本语言。所谓“脚本语言” (script language),指的是它不具备开发操作系统的能力,而是只用来编写控制其他大型应用程序(比如浏览器)的“脚本”。
JS 也是一种嵌入式 (embedded) 语言。它本身提供的核心语法不算很多,只能用来做一些数学和逻辑运算。JS 本身不提供任何与 I/O (输入/输出)相关的 API,都要靠宿主环境(host)提供,所以 JS 只合适嵌入更大型的应用程序环境,去调用宿主环境提供的底层 API。
简单来说,JS 在前端就是用来操作浏览器的工具。
引入方式
JS 代码可以直接嵌在网页的任何地方,如果想要在网页显示前就载入并运行 JS,通常我们把代码放到 <head>
中。
<html>
<head>
<script>
alert("Hello, world");
</script>
</head>
<body>
...
</body>
</html>
由 <script>...</script>
包含的代码就是 JavaScript 代码,它将直接被浏览器执行。
第二种方法是把 JS 代码放到一个单独的 js
文件,然后在 HTML 中通过 <script src="..."></script>
引入这个文件:
<html>
<head>
<script src="/static/js/abc.js"></script>
</head>
<body>
...
</body>
</html>
这样, /static/js/abc.js
就会被浏览器执行,通常我们使用外部引用。
注释
<script>
// 这是一个行注释
alert("Hello, world");
alert("你好,世界"); // 这是一个行尾注释
/* 这是一个区块注释
这是一个区块注释
这是一个区块注释 */
</script>
变量和常量
变量的概念基本上和初中代数的方程变量是一致的,只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型;常量指不可变的量,特性就是不可变。
JS 中定义变量主要有三个关键字,var
let
const
,简单用法如下。
// JS 设计之初使用的关键字,但是存在历史遗留问题(可重复定义导致变量覆盖问题;提前解析变量导致变量提升问题),以后都不建议使用,替代品是 let
var a = 1;
// 使用 let 定义的变量,不可重复定义,不会提前解析
let b = 2;
// 使用 const 定义的常量,不可变
const c = 3;
strict 模式
JS 在设计之初甚至并不强制要求用 var
声明变量,这个设计错误带来了严重的后果,如果一个变量没有通过 var
声明就被使用,那么该变量就自动被声明为全局变量。
i = 10; // i 现在是全局变量
所以为了避免这种问题,可以启用 strict
模式,在 JS 代码的第一行加上以下代码。
"use strict";
变量类型
JS 是弱类型语言,对于数据类型的规范比较松散,有以下几种类型。
数据类型 | 说明:(四基两空一对象) |
---|---|
Number | 数值,JS 数值类型不再细分整型、浮点型等。 |
String | 字符串,信息传播的载体,字符串必须包含在单引号、双引号或反引号之中。 |
Boolean | 布尔值,逻辑运算的载体,仅有两个值,true 和 false。 |
Symbol | 符号类型,ES6 引入的一种新的原始数据类型,表示独一无二的值,不常用。 |
null | 空值,表示不存在,当为对象的属性赋值为 null,表示删除该属性,使用 typeof 运算符检测 null 值,返回 Object。 |
undefined | 未定义,当声明变量而没有赋值时会显示该值,可以为变量赋值为 undefined。 |
Object | 对象,是一种无序的数据集合,内容是键值对的形式,键名(key)是字符串,可以包含任意字符(空格),字符串引号可省略。 |
以下先简单介绍除 Symbol 和 Object 之外的几种类型,此外我们可以使用 typeof 变量
来查看变量的类型。
<script>
let num = 1;
let str = "1";
let bool = true;
console.log(typeof num); // number
console.log(typeof str); // string
console.log(typeof bool); // boolean
</script>
数值类型(Number)
即我们数学中学习到的数字,可以是整数、小数、正数、负数。
let num1 = 18;
let num2 = 18.88;
let num3 = -18;
字符串类型(String)
被引号包裹的一段文字信息,单引号、双引号、反引号。
// 定义字符串
let str1 = '我是一段文字';
let str2 = "我是一段文字";
let str3 = `我是一段文字`;
// 字符串中显示双引号
let str4 = '我是一段"文字"';
// 模板字符串,可以引用变量
let name = "itwxe"
let age = 18
let intro = `我是${name},今年${age}岁`
布尔值(Boolean)
表示肯定或否定时在计算机中对应的是布尔类型数据,它有两个固定的值 true
和 false
,表示肯定的数据用 true
,表示否定的数据用 false
。
let isMan = true;
let isWoman = false;
空值(null)和未定义(undefined)
null
表示一个“空”的值,它和 0 以及空字符串 ''
不同,0 是一个数值,''
表示长度为 0 的字符串,而 null
表示“空”。
在其他语言中,也有类似 JS 的 null
的表示,例如 Java 也用 null
,Swift 用 nil
,Python 用 None
表示。但是,在 JS 中,还有一个和 null
类似的 undefined
,它表示 “未定义”。
JS 的设计者希望用 null
表示一个空的值,而 undefined
表示值未定义。事实证明,这并没有什么卵用,区分两者的意义不大。大多数情况下,我们都应该用 null
。undefined
仅仅在判断函数参数是否传递的情况下有用。
console.log(null); // null
let name;
console.log(name); // undefined
运算符
算数运算符
数学运算符,主要包括加、减、乘、除、取余(求模)。
运算符 | 作用 |
---|---|
+ | 求和 |
- | 求差 |
* | 求积 |
/ | 求商 |
% | 取模(取余数),常用于作为某个数字是否被整除 |
console.log(1 + 2); // 3
console.log(1 - 2); // -1
console.log(1 * 2); // 2
console.log(1 / 2); // 0.5
console.log(0 % 2); // 0
console.log(1 % 2); // 特别注意这里和 Java 不一样,结果是 1
console.log(2 % 2); // 0
console.log(3 % 2); // 1
console.log(1 + 2 * 3); // 组合起来也遵循数学的规则 7
console.log("itwxe" + 2); // itwxe2
console.log("itwxe" - 2); // 计算失败返回 NaN
console.log("itwxe" * 2); // 计算失败返回 NaN
console.log("itwxe" / 2); // 计算失败返回 NaN
赋值运算符
赋值运算符:对变量进行赋值的运算符号,已经写了很多 =
号了,以下是一些简写方式。
运算符 | 作用 |
---|---|
+= | 加法赋值,eg:i = i + 1 可以简写为 i += 1 |
-= | 减法赋值,eg:i = i - 1 可以简写为 i -= 1 |
*= | 乘法赋值,eg:i = i * 1 可以简写为 i *= 1 |
/= | 除法赋值,eg:i = i / 1 可以简写为 i /= 1 |
%= | 取余赋值,eg:i = i % 1 可以简写为 i %= 1 |
let num = 100;
num += 100; // 100
num -= 50; // 150
num *= 2; // 300
num /= 3; // 100
num %= 50; // 0
自增/自减运算符
以变量 num
为例说明。
符号 | 说明 |
---|---|
num++ | 使用变量自身的值运算,之后再 +1 |
++num | 使用变量自身的值 +1 之后的值运算 |
num-- | 使用变量自身的值运算,之后 -1 |
--num | 使用变量自身的值 -1 之后的值运算 |
虽然上面说明很简单,但是得结合下面例子,细品~
let num = 100;
console.log(num++); // 100
console.log(num); // 101
console.log(num--); // 101
console.log(num); // 100
console.log(++num); // 101
console.log(num); // 101
console.log(--num); // 100
console.log(num); // 100
比较运算符
使用场景:比较两个数据大小、是否相等,根据比较结果返回一个布尔值(true / false)
运算符 | 作用 |
---|---|
> | 左边是否大于右边 |
< | 左边是否小于右边 |
>= | 左边是否大于或等于右边 |
<= | 左边是否小于或等于右边 |
=== | 左右两边是否类型和值都相等(重点) |
== | 左右两边值是否相等 |
!= | 左右值是否不相等 |
!== | 左右两边是否不全等 |
// 根据比较结果返回 布尔值 true / false
console.log(3 > 6) // false
console.log(3 < 6) // true
console.log(3 >= 6) // false
console.log(3 <= 3) // true
// 提倡使用三等,即比较值和类型
console.log(3 == 3) // true
console.log(3 == '3') // true
console.log(3 === 3) // true
console.log(3 === '3') // false
console.log(3 != 3) // false
console.log(3 !== 3) // false
console.log(3 !== '3') // true
逻辑运算符
符号 | 名称 | 说明 |
---|---|---|
&& | 逻辑与,俗称并且 | 所有条件为 true 则为 true;有一个条件为 false 则为 false |
|| | 逻辑或,俗称或者 | 有一个条件为 true 则为 true,并且碰到条件为 true 时后面的条件就不会判断了 |
! | 逻辑非,俗称取反 | 给条件取反,true 变为 false ;false 变为 true |
console.log(3 < 5 && 2 < 1); // false
console.log(3 < 5 || 2 < 1); // true
console.log(!(3 < 5 || 2 < 1)); // false
运算符优先级
优先级 | 顺序 |
---|---|
1 | () |
2 | ++ -- ! |
3 | 先 * / % 后 + - |
4 | > >= < <= |
5 | == != === !== |
6 | 先 && 后 ` |
7 | = |
显示模式
转换为数字型
有时候需要进行计算的数据不是数字类型,则需要转换后计算。
函数 | 说明 |
---|---|
Number(数据) | 转换成功返回一个数字类型;转换失败则返回 NaN (例如数据里面包含非数字) |
parseInt(数据) | 只保留整数,如果数字开头的字符串,只保留整数数字 比如 12px 返回 12;转换失败则返回 NaN (例如数据以非数字开头) |
parseFloat(数据) | 可以保留小数,如果数字开头的字符串,可以保留小数 比如 12.5px 返回 12.5;转换失败则返回 NaN (例如数据以非数字开头) |
console.log(Number("10.01")); // 10.01
console.log(Number("10.01xyz")); // NaN
console.log(parseInt("10.01")); // 10
console.log(parseInt("10.01xyz")); // 10
console.log(parseInt("xyz10.01")); // NaN
console.log(parseFloat("10.01")); // 10
console.log(parseFloat("10.01xyz")); // 10.01
console.log(parseFloat("xyz10.01")); // NaN
转换为字符串
函数 | 说明 |
---|---|
String(数据) | 转为字符串 |
数据.toString(进制,不填默认10进制) | 转为字符串,可以进行进制转换 |
let num = 10;
let numConvertStr1 = String(num);
let numConvertStr2 = num.toString();
console.log(numConvertStr1); // "10"
console.log(numConvertStr2); // "10"
console.log(typeof numConvertStr1); // string
console.log(typeof numConvertStr2); // string
let numConvertStr3 = num.toString(8); // 转换为8进制,结果:"12"
console.log(numConvertStr3); // "12"
console.log(typeof numConvertStr3); // string
布尔型转换
使用 Boolean(数据)
可以转换为布尔类型,其他数据类型中的 0 "" null undefined NaN
为 false,其他的都为 true。
console.log(Boolean(0)); // false
console.log(Boolean(1)); // true
console.log(Boolean("")); // false
console.log(Boolean("itwxe")); // true
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
// 算术运算符 - * / 比较运算符 > ==
console.log(9 - "3"); // 6
console.log("300" * "2"); // 600
console.log(3 > "6"); // false
console.log(3 == "3"); // true
// 加正号使用的时候,也会把字符串转换为 数字型
console.log("123"); // "123"
console.log(+"123"); // 123
console.log(typeof +"123"); // number
// 隐式转换为字符串型的运算符,加号拼接字符串,两侧只要有一个是字符串,结果就是字符串
console.log("28" + 18); // "2818"
console.log(typeof ("28" + 18)); // string
// 隐式转换为布尔型的运算符 !逻辑非
console.log(!true); // false
console.log(!0); // true
console.log(!""); // true
console.log(!null); // true
console.log(!undefined); // true
console.log(!NaN); // true
console.log(!false); // true
console.log(!"itwxe"); // false
条件判断
if 分支判断
条件判断语句定义:
// 单分支
if (条件表达式){
// 满足条件要执行的语句
}
// 双分支
if (条件表达式){
// 满足条件要执行的语句
} else {
// 不满足条件要执行的语句
}
// 多分支,else if 可以多个
if (条件表达式1){
// 满足条件表达式1要执行的语句
} else if (条件表达式2) {
// 满足条件表达式2要执行的语句
} else {
// 不满足条件要执行的语句
}
没啥好解释的,上例子。
let score = 70;
// 控制台打印结果为及格
if (score >= 90) {
console.log("优秀");
} else if (score >= 75) {
console.log("良好");
} else if (score >= 60) {
console.log("及格");
} else {
console.log("不及格");
}
三元表达式
一些简单的双分支,可以使用三元表达式(三元运算符),写起来比 if else 双分支更简洁。
// 语法
// 条件 ? 条件为真时的结果 : 条件为假时的结果;
console.log(5 > 3 ? "真的" : "假的"); // 真的
switch 语句
switch 语句在 if 多分支等值匹配比较多的时候书写起来更加简洁。
switch (表达式) {
case 值1:
代码1
break;
case 值2:
代码2
break;
default:
代码n
}
例如电脑配件的价格示例,示例控制台打印结果为 2000。
let computerParts = "CPU";
switch (computerParts) {
case "主板":
console.log(1000);
break;
case "CPU":
console.log(2000);
break;
case "内存条":
console.log(800);
break;
default:
console.log("没有匹配到");
}
循环
所谓循环,就是满足判断条件则一遍一遍循环的执行一段代码块。
while 循环
语法:
while (判断条件) {
// 满足条件执行的循环体
}
循环打印10次,示例:
let i = 1;
while (i <= 10) {
console.log(`当前循环第${i}次`);
i++;
}
for 循环
语法:
for (初始值; 循环条件; 变量计数) {
// 满足条件执行的循环体
}
循环打印10次,示例:
for (let i = 0; i < 10; i++) {
console.log(`当前循环第${i + 1}次`);
}
死循环和终止循环
死循环是当判断条件始终不满足的时候就会无限循环,而通常死循环是不可取的,所以需要终止循环。
死循环可以使用 while (true)
和 for(;;;)
来实现,当然也有其他方式;而终止循环需要使用到 break
关键字。
let num = 100;
while (true) {
if (num < 50) {
console.log("程序终止")
break;
} else {
num -= 50;
console.log("程序没有终止,num - 50,num = " + num)
}
}
// 程序总共执行了三次循环,执行结果为
程序没有终止,num - 50,num = 50
程序没有终止,num - 50,num = 0
程序终止
break
用于终止循环,而 continue
用于跳过某次循环。
let num = 3;
for (let i = 1; i < 6; i++) {
if (num === i) {
console.log("跳过第" + i + "次循环");
continue;
}
console.log("这是第" + i + "次循环");
}
// 控制台打印结果,可以看到 i=3 的时候没有打印 这是第3次循环
这是第1次循环
这是第2次循环
跳过第3次循环
这是第4次循环
这是第5次循环
循环的嵌套
条件判断可以嵌套,循环也可以嵌套,外层循环循环一次,里层循环循环全部。
<script>
"use strict";
// document.write 是往页面写入信息
document.write("<h2>三角形</h2>")
for (let i = 0; i < 6; i++) {
for (let j = 0; j <= i; j++) {
document.write("☆");
}
document.write("<br>");
}
document.write("<hr>")
document.write("<h2>九九乘法表</h2>")
for (let i = 1; i <= 9; i++) {
let rowStr = "";
for (let j = 1; j <= i; j++) {
rowStr += `${j} * ${i} = ${i * j} `;
}
document.write(rowStr + "<br>");
}
</script>