script 标签
- <scrtipt> 标签可以插入到HTML中的任何位置
- 在很老的代码中需使用type属性,但是现在的代码中不需要
<script type="text/javascript"><!-- ... //--></script>
外部脚本
通过src 属性将脚本添加到HTML中
<script src="/path/to/script.js"></script>
如果设置了src属性,script标签中的内容将会被忽略
<script _src_="file.js"> alert(1); // 此内容会被忽略,因为设定了 src </script>
为了让上面的例子工作,我们可以将它分成两个 <script>
标签。
<script src="file.js"></script> <script> alert(1); </script>
代码结构
语句
当存在换行符的时候可以省略分号,也被称为自动分号插入,建议不要省略分号
alert('Hello'); alert('World');
alert('Hello')
alert('World')
现代模式,“use strict”
为了保证旧的功能能够使用,大部分的修改是默认不生效的。你需要一个特殊的指令 —— "use strict"
来明确地激活这些特性。
"use strict";
// 代码以现代模式工作
...
确保“use strict”出现脚本顶部
没有办法取消 use strict
- class 和 module 都会自动启用 usr strict,无需再添加指令
变量
使用 let 定义和声明变量
let message = 'Hello!';
alert(message); // Hello!
let user = 'John', age = 25, message = 'Hello';
老的代码中使用 var
未采用user strict时变量定义
// 注意:这个例子中没有 "use strict"
num = 5;
// 如果变量 "num" 不存在,就会被创建
alert(num); // 5
"use strict";
num = 5; // 错误:num 未定义_
常量
const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // 错误,不能对常量重新赋值
数据类型
动态类型
虽然编程语言中有不同的数据类型,但是你定义的变量并不会在定义后,被限制为某一数据类型
// 没有错误
let message = "hello";
message = 123456;
Number 类型
- Infinity 无穷大,有两种方式来得到它
// 除0
alert( 1 / 0 ); // Infinity
alert( Infinity ); // Infinity
- NaN 代表一个计算错误
BigInt类型
±
(
2
53
−
1
)
±(2^{53}-1)
±(253−1) 范围就足够了,但有时候我们需要整个范围非常大的整数,例如用于密码学或微秒精度的时间戳。
可以通过将 n
附加到整数字段的末尾来创建 BigInt
值。
// 尾部的 "n" 表示这是一个 BigInt 类型
const bigInt = 1234567890123456789012345678901234567890n;
String类型
let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;
-
反引号是 功能扩展 引号。它们允许我们通过将变量和表达式包装在 ${…} 中,来将它们嵌入到字符串中。
-
需要注意的是,这仅仅在反引号内有效,其他引号不允许这种嵌入。
Boolean 类型
null
undefined
typeof 运算符
对 typeof x
的调用会以字符串的形式返回数据类型:
typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol" _
typeof Math // "object" (1)_ _
typeof null // "object" (2)_ _
typeof alert // "function" (3)_
type(x)
与 type x
相同。
简单点说:typeof
是一个操作符,不是一个函数。这里的括号不是 typeof
的一部分。它是数学运算分组的括号。
交互
alert
它会显示一条信息,并等待用户按下 “OK”。
alert("Hello");
prompt
prompt 函数接收两个参数
result = prompt(title, [default]);
- title 显示给用户的文本
- default 是输入框的初始文本,可省
- 输入框,点确定,将输入的内容返回给result
- 点取消,返回null
![[Pasted image 20230430011020.png]]
![[Pasted image 20230430011031.png]]
confirm
result = confirm(question);
confirm
函数显示一个带有 question
以及确定和取消两个按钮的模态窗口。
点击确定返回 true
,点击取消返回 false
。
类型转换
字符串转换
String(value)
数字类型转换
- 在算术函数和表达式中,会自动进行 number 类型转换。
alert( "6" / "2" ); // 3, string 类型的值被自动转换成 number 类型后进行计算
- 使用Number(value)
let str = "123";
alert(typeof str); // string
let num = Number(str); // 变成 number 类型 123
alert(typeof num); // number
Bool
转换发生在进行逻辑操作时,也可以通过 Boolean(value)
进行显式转换
alert( Boolean(1) ); // true
alert( Boolean(0) ); // false
alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
alert( Boolean("0") ); // true
alert( Boolean(" ") ); // 空格,也是 true(任何非空字符串都是 true)
包含 0 的字符串 "0"
是 true
数学运算
求幂**
alert( 2 ** 2 ); // 2² = 4
alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
alert( 4 ** (1/2) ); // 2(1/2 次方与平方根相同)
alert( 8 ** (1/3) ); // 2(1/3 次方与立方根相同)
加号 +
被应用于字符串,它将合并(连接)各个字符串:
let s = "my" + "string";
alert(s); // mystring
alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
alert(2 + 2 + '1' ); // "41",不是 "221"
alert('1' + 2 + 2); // "122",不是 "14"
二元 +
是唯一一个以这种方式支持字符串的运算符。其他算术运算符只对数字起作用,并且总是将其运算元转换为数字。
下面是减法和除法运算的示例:
alert( 6 - '2' ); // 4,将 '2' 转换为数字
alert( '6' / '2' ); // 3,将两个运算元都转换为数字
逗号运算符
逗号运算符能让我们处理多个语句,使用 ,
将它们分开。每个语句都运行了,但是只有最后的语句的结果会被返回。
let a = (1 + 2, 3 + 4);
alert( a ); // 7(3 + 4 的结果)
值的比较
和C很类似
不同类型的值比较
JavaScript 会首先将其转化为数字(number)再判定大小。
严格相等
如果 a
和 b
属于不同的数据类型,那么 a === b
不会做任何的类型转换而立刻返回 false
alert( 0 === false ); // false,因为被比较值的数据类型不同
逻辑运算
|| && !
控制合并运算符
a ?? b
的结果是:
- 如果
a
是已定义的,则结果为a
, - 如果
a
不是已定义的,则结果为b
。
等价于
result = (a !== null && a !== undefined) ? a : b;
循环
while for break continue 基本和c一致
标签
是在循环之前带有冒号的标识符:
```
labelName: for (…) { … }
`break <labelName>` 语句跳出标记循环:
```JavaScript
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`Value at coords (${i},${j})`, ''); // 如果是空字符串或被取消,则中断并跳出这两个循环。
if (!input) _break_ _outer_; // (*)
// 用得到的值做些事……
}
}
alert('Done!');
我们还可以将标签移至单独一行:
outer: for (let i = 0; i < 3; i++) { ... }
continue
指令也可以与标签一起使用。在这种情况下,执行跳转到标记循环的下一次迭代。
break
指令必须在代码块内。从技术上讲,任何被标记的代码块都有效.
switch
这里的相等是严格相等。被比较的值必须是相同的类型才能进行匹配。
函数
函数声明
function name(parameter1, parameter2, ... parameterN) {
...body...
}
向函数传参,使用的是赋值,而不是引用,函数内的修改函数外不可见
默认值
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}
showMessage("Ann"); // Ann: no text given
function showMessage(from, text = anotherFunction()) {
// anotherFunction() 仅在没有给定 text 时执行
// 其运行结果将成为 text 的值
}
返回值
空值的 return
和 return undefined
等效
函数表达式
在 JavaScript 中,函数不是“神奇的语言结构”,而是一种特殊的值。
它允许我们在任何表达式的中间创建一个新函数。
let sayHi = function() { alert( "Hello" ); };
函数是一个值
function sayHi() { alert( "Hello" ); }
alert( sayHi ); // 显示函数代码_
但是这样并不会运行函数,因为没有括号
回调函数
这两个函数没有名字,所以叫 匿名函数。这样的函数在 ask
外无法访问(因为没有对它们分配变量),不过这正是我们想要的。
function ask(question, yes, no)
{ if (confirm(question)) yes()
else no();
}
ask(
"Do you agree?",
function() { alert("You agreed."); },
function() { alert("You canceled the execution."); }
);
函数表达式是在代码执行到达时被创建,并且仅从那一刻起可用
在函数声明被定义之前,它就可以被调用。
sayHi("John"); // Hello, John
function sayHi(name) { alert( `Hello, ${name}` ); }
但是以下的写法就会有bug
sayHi("John"); // error!
let sayHi = function(name) {
// (*) no magic any more
alert( `Hello, ${name}` );
};
严格模式下,当一个函数声明在一个代码块内时,它在该代码块内的任何位置都是可见的。但在代码块外不可见。
箭头函数
let func = (arg1, arg2, ..., argN) => expression;
这里创建了一个函数 func
,它接受参数 arg1..argN
,然后使用参数对右侧的 expression
求值并返回其结果。
换句话说,它是下面这段代码的更短的版本:
let func = function(arg1, arg2, ..., argN) { return expression; };
let double = n => n * 2;
// 差不多等同于:let double = function(n) { return n * 2 }
alert( double(3) ); // 6
let sayHi = () => alert("Hello!");
sayHi();
let sum = (a, b) => { // 花括号表示开始一个多行函数
let result = a + b;
return result; // 如果我们使用了花括号,那么我们需要一个显式的 “return”
};
alert( sum(1, 2) ); // 3