JavaScript基础知识
# “script” 标签
可以插入到HTML的任何地方
# 外部链接
不能同时有src和里面的代码
<script src="index.js">
alert(1) // 这将不会工作
</script>
2
3
# 代码结构
当存在分行符(line break)时,在大多数情况下可以省略分号。
alert('hello')
alert('world')
2
在这,JavaScript 将分行符理解成“隐式”的分号。这也被称为 自动分号插入
但是也有例外的情况 :
alert("There will be an error")
[1, 2].forEach(alert)
2
现在,如果我们运行代码,只有第一个 alert 语句的内容被显示了出来,随后我们收到了一 个错误! 但是,如果我们在第一个 alert 语句末尾加上一个分号,就工作正常了:
alert("All fine now");
[1, 2].forEach(alert)
2
出现无分号变量(variant)的错误,是因为 JavaScript 并不会在方括号 [...] 前添加一个隐 式的分号。
# 现代模式,"use strict"
这个指令看上去像一个字符串 "use strict" 或者 'use strict' 。当它处于脚本文件的顶 部时,则整个脚本文件都将以“现代”模式进行工作。
- 确保use strict出现在脚本的最顶端
- 没有办法取消use strict
# 变量
# 7种数据类型
- number --- 可以是浮点数,可以是整数
- string --- 字符串类型
- boolean --- 逻辑值 true false
- null
- undefined
- object 和 symbol
# 变量命名
JavaScript 的变量命名有两个限制:
- 变量名称必须仅包含字母,数字,符号 $ 和 _ 。
- 首字符必须非数字。
# 大写形式的常数
使用大写字母和下划线来命名这些常量。
# 数据类型
# number 类型
number 类型代表整数和浮点数。
数字可以有很多操作,比如,乘法 * 、除法 / 、加法 + 、减法 - 等等。
除了常规的数字,还包括所谓的“特殊数值(“special numeric values”)”也属于这种类型: Infinity 、 -Infinity 和 NaN 。
# string 类型
# boolean 类型(逻辑类型)
# “null” 值
# “undefined” 值
# object 类型和 symbol 类型
# 字符串转换
数字型转换:
值 | 变成... |
---|---|
undefined | NaN |
null | 0 |
true/ false | 1/0 |
string | 去掉首尾空格后的纯数字字符串中含有的数字。如果剩余字符串为空,则转换结果为 。否则,将会从剩余字 符串中“读取”数字。当类型转换出现 error 时返回 |
上述的大多数规则都容易理解和记忆。人们通常会犯错误的值得注意的例子有以下几个:
- 对进行数字型转换时,输出结果为 NaN ,而非 0 。
- 对 "0" 和只有空格的字符串(比如: " " )进行布尔型转换时,输出结果为 true 。
"" + 1 + 0 // "10" 加号首先会解析为字符串连接的加号而不是数学的加号
"" - 1 + 0 // -1 减号会将字符串转为数字
true + false // 1 这里的加号解析成数学的加号 true为1 false为0
6 / "3" //2
"2" * "3" //6
4 + 5 + 'px' // 9px 4+5首先解析为数学的加号,后面再是字符串的拼接加号
"$" + 4 + 5 // "$45"
"4" - 2 // 2
"4px" - 2 // NaN
7/0 // Infinity
" -9 " + 5 // "-95"
" -9 " - 5 // -14
null + 1 // -1
undefined + 1 // NaN
" \t \n" - 2 //-2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 运算符
# 位运算符
- 按位与( )
- 按位或( )
- 按位异或( )
- 按位非( )
- 左移( )
- 右移( )
- 无符号右移 ( >>> )
# 相等
有时候,以下两种情况会同时发生:
- 若直接比较两个值,其结果是相等的。
- 若把两个值转为布尔值,它们可能得出完全相反的结果,即一个是 true ,一个是 false 。
let a = 0;
alert( Boolean(a) ); // false
let b = "0";
alert( Boolean(b) ); // true
alert(a == b); // true!
2
3
4
5
# 严格相等
严格相等操作符 === 在进行比较时不会做任何的类型转换。
# 总结
- 比较运算符始终返回布尔值。
- 字符串的比较,会按照“词典”顺序逐字符地比较大小。 的变量,请按需要分别检查它
- 当对不同类型的值进行比较时,它们会先被转化为数字(不包括严格相等检测)再进行比较。
- 在非严格相等 下, null 和 undefined 相等且各自不等于任何其他的值。
- 在使用 > 或 进行比较时,需要注意变量可能为 null/undefined 的情况。比较好的方法 是单独检查变量是否等于 null/undefined 。
5>4 // true
"apple" > "pineapple" // false
"2" > "12" // true
undefined == null // true
undefined === null // false
null == "\n0\n" // false
null === +"\n0\n" // false
2
3
4
5
6
7
# 逻辑运算符
# 或运算寻找第一个真值
result = value1 || value2 || value3
或运算做了一下的事情:
- 从左到右依次计算操作数。
- 将每一个操作数转化为布尔值。如果结果是 true ,就停止计算,返回这个操作数的初始值。
- 如果所有的操作数都被计算过(也就是,转换结果都是 false ),返回最后一个操作数。
alert( null || 0 || 1 ); // 1(第一个真值)
alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返回最后一个值)
2
# 与操作寻找第一个假值
result = value1 && value2 && value3
与运算 && 做了如下的事情:
- 从左到右依次计算操作数。
- 将每一个操作数转化为布尔值。如果结果是 false ,就停止计算,返回这个操作数的初始值。
- 如果所有的操作数都被计算过(也就是,转换结果都是 true ),返回最后一个操作数。
// 如果第一个操作符是真值, // 与操作返回第二个操作数: alert( 1 && 0 ); // 0 alert( 1 && 5 ); // 5
// 如果第一个操作符是假值,
// 与操作直接返回它。第二个操作数被忽略 alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
2
3
4
与运算要比或运算有限级高 所以a&&b||c&&d 相当于(a&&b)||(d&&d)
# 循环
- while —— 每次迭代之前都要检查条件。
- do..while —— 每次迭代后都要检查条件。
- for (;😉 —— 每次迭代之前都要检查条件,可以使用其他设置。
通常使用 while(true) 来构造“无限”循环。这样的循环就像任何其他循环一样,可以通过 break 指令来终止。 如果我们不想在当前迭代中做任何事,并且想要转移至下一次迭代,那么 continue 指令就会执 行它。 break/continue 支持循环前的标签。标签是 break/continue 跳出嵌套循环来转到外部循 环的唯一方法。
//标签跳出最外层循环
outer:for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++){
// let input = prompt(`Value at coords (${i},${j})`, '');
console.log(i,j)
if(j == 1) break outer;
}
}
console.log('done')
2
3
4
5
6
7
8
9
思考题
for (let i = 0; i < 5; i++) console.log( i ); // 0 1 2 3 4
for (let i = 0; i < 5; ++i) console.log( i ); // 0 1 2 3 4
//p76
2
3
注意: switch case里的是严格相等,既 ===, 所以'3'跟3是不等的
# 函数
- 作为参数传递给函数,值被复制到其局部变量
- 函数可以访问外部变量。但它只能从内到外起作用。函数外部的代码看不到它的局部变量。
- 函数可以返回值。如果没有,则其结果是 undefined 。 为了使代码简洁易懂,建议在函数中主要使用局部变量和参数,而不是外部变量。 与不获取参数但作为副作用修改外部变量的函数相比,理解获取参数、与它们一起工作并返回结果 的函数总是更容易理解。 函数命名:
- 名称应该清楚地描述函数的功能。当我们在代码中看到一个函数调用时,一个好的名称立即让 我们了解它所做的和返回的事情。
- 一个函数是一个行为,所以函数名通常是动词。
- 有许多优秀的函数前缀,如 create... 、 show... 、 get... 、 check... 等等。使用它们来提示函 数的作用。 函数是脚本的主要构建块。现在我们已经介绍了基本知识,这样我们就可以开始创建和使用它们 了。但这只是道路的开始。我们将多次回到它们身上,更深入地研究它们的先进特征。
总结
- 函数是值。他们可以在代码的任何地方分配,复制或声明。
- 如果函数在主代码流中声明为单独的语句,那就称为“函数声明”。
- 如果该函数是作为表达式的一部分创建的,则称其为“函数表达式”。
- 函数声明在代码块执行之前处理。它们在代码块中随处调用。
- 函数表达式在执行流程到时创建。 在大多数情况下,当我们需要声明一个函数时,函数声明是可取的,因为它在声明本身之前是可见 的。这给了我们更多的代码组织的灵活性,并且通常更具可读性。 所以我们应该只在函数声明不适合任务时才使用函数表达式。在本章中我们已经看到了几个例子, 并且将来会看到更多的例子。 箭头函数非常适合单行调用,以下是其两个特点。
- 没有大括号: (...args) => expression —— 右侧是一个表达式:该函数对其进行运行 并返回结果。
- 有大括号: —— 括号允许我们在函数中写入多个语句,但是我们 需要一个显式的 来返回一些东西。