代码结构
js 将换行符理解成“隐式”的分号。这也被称为 自动分号插入
alert('Hello')
alert('World')
例外:
//如果一行以加号 "+" 结尾,这是一个“不完整的表达式”,js认为不需要分号。
alert(3 +
1
+ 2);
//结果输出 6
alert("All fine now");
[1, 2].forEach(alert)
//输出All fine now ,然后报错
//在[] 前面js也认为是 不完整表达式
(function() {
'use strict';
let a = 'dd'
})()
严格模式
use strict,必须在最顶部才有全局效果 控制台 需要 使用自执行函数
(function() {
'use strict';
a = '111' ///会报错
// ...你的代码...
})()
变量命名
变量名称必须仅包含字母,数字,符号 $ 和 _。 首字符必须非数字。 允许非英文字母,但不推荐,如 let 李 = 'x'
数据类型
7 种原始类型和 1 种引用类型
Number
常规的数字 和 特殊数值 Infinity、-Infinity 和 NaN Infinity 是 在数学里是无穷大 ,可以有正负
1 / 0// Infinity
Infinity// 可以直接访问
NaN 代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果
"not a number" / 2// NaN,这样的除法是错误的
"not a number" / 2 + 5// NaN
BigInt
尾部的 "n" 表示这是一个 BigInt 类型
const bigInt = 1234567890123456789012345678901234567890n;
String字符串
双引号:"Hello".
单引号:'Hello'.
反引号:Hello
.
js 没有char
//可以使用 ${} 做运算
let a = '张三'
`the result is ${a} ${1 + 2}`// the result is 3
Boolean 布尔类型
“null” 值
特殊的 null 值不属于上述任何一种类型,它构成了一个独立的类型,只包含 null 值: let age = null; 相比较于其他编程语言,JavaScript 中的 null 不是一个“对不存在的 object 的引用”或者 “null 指针”。 JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值。 上面的代码表示 age 是未知的。
undefined
特殊值 undefined 和 null 一样自成类型。 undefined 的含义是 未被赋值。 如果一个变量已被声明,但未被赋值,那么它的值就是 undefined:
let age;
alert(age); // 弹出 "undefined"
let age = 100;
// 将值修改为 undefined
age = undefined;
alert(age); // "undefined"
symbol 用于唯一的标识符。
object 复杂数据类型
typeof
typeof 运算符返回参数的类型 作为运算符:typeof x。 函数形式: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) // js的bug,null 绝对不是一个 object。null 有自己的类型,它是一个特殊值。
typeof alert // "function" (3)
typeof alert 的结果是 "function", 因为 alert 在 JavaScript 语言中是一个函数。我们会在下一章学习函数, JavaScript 语言中没有一个特别的 “function” 类型。 函数隶属于 object 类型。但是 typeof 会对函数区分对待,并返回 "function"。 这也是来自于 JavaScript 语言早期的问题。从技术上讲,这种行为是不正确的,但在实际编程中却非常方便。
类型转换
- 定义:运算符和函数会自动将赋予它们的值转换为正确的类型
- 运算符如:+ / ,会显示调用Number(内容), "1" + "2" => Number("1") + Number("2")
- 函数如:alert ,会显示调用String(内容) , alert(1) => alert("1")
基本数据类型转换
- 字符串类型
String(value)
- 数字类型
- Number(value)
- undefined => NaN
- null => 0
- true / false => 1 / 0
- string => “按原样读取”字符串,两端的空白会被忽略。空字符串变成 0。转换出错则输出 NaN。
- 布尔类型
- 0, null, undefined, NaN, "" => false
- 其他值 , " "(包括空格的字符串) => true
let a
if (a) { //false
}
if("") { //false
}
if(" ") { //true
}
基础运算符,数学
一元运算符
x = -x;
alert( x ); // -1,一元负号运算符生效
二元运算符”
let x = 1, y = 3;
alert( y - x ); // 2,二元运算符减号做减运算
数学运算:
加法 +, 减法 -, 乘法 *, 除法 /,
取余 %
a % b 的结果是 a 整除 b 的 余数
alert( 5 % 2 ); // 1,5 除以 2 的余数
alert( 8 % 3 ); // 2,8 除以 3 的余数
求幂 **
其实就是平方,也支持平方根
//平方
alert( 2 ** 2 ); // 4 (2 * 2,自乘 2 次)
alert( 2 ** 3 ); // 8 (2 * 2 * 2,自乘 3 次)
alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2,自乘 4 次)
//平方根
alert( 4 ** (1/2) ); // 2(1/2 次方与平方根相同)
alert( 8 ** (1/3) ); // 2(1/3 次方与立方根相同)
二元运算符 + 连接字符串
原则:有字符串,优先转String(value), 其他走Number(value)
alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
alert(2 + 2 + '1' ); // "41",不是 "221"
alert( true + true ); // 2
二元运算符 - * /
-
- / 都是Number(value) 处理
一元运算符 +
数字转化
// 对数字无效
let x = 1;
alert( +x ); // 1
let y = -2;
alert( +y ); // -2
// 转化非数字
alert( +true ); // 1
alert( +"" ); // 0
优先级
优先级 | 名称 | 符号 | 17 | 一元加号 | + | 17 | 一元负号 | - | 16 | 求幂 | ** | 15 | 乘号 | * | 15 | 除号 | / | 13 | 加号 | + | 13 | 减号 | - | 3 | 赋值符 | = | 1 | 逗号 | , |
---|
链式赋值
let a, b, c;
a = b = c = 2 + 2;
alert( a ); // 4
alert( b ); // 4
alert( c ); // 4
原地修改
let n = 2;
n = n + 5;
//等价于 运算符 +=
let n = 2;
n += 5;
自增 / 自减
前置形式返回一个新的值,但后置返回原来的值(做加法/减法之前的值)。
let counter = 0;
alert( ++counter ); // 1
let counter = 0;
alert( counter++ ); // 0
let counter = 1;
alert( 2 * counter++ ); // 2,因为 counter++ 返回的是“旧值”
注意:5++ 是错误
位运算符
- 位运算符把运算元当做 32 位整数,并在它们的二进制表现形式上操作。
- 按位与 ( & )
- 按位或 ( | )
- 按位异或 ( ^ )
- 按位非 ( ~ )
- 左移 ( << )
- 右移 ( >> )
- 无符号右移 ( >>> )
值的比较
所有比较运算符均返回布尔值:
字符串比较
首位比较,如果相同继续比较,比较根据 Unicode 编码顺序
'Z' > 'A'// true
'Glow' > 'Glee'// true
'Bee' > 'Be'// true
不同类型间的比较
JS 会首先将其转化为数字(number)再判定大小
'2' > 1// true,字符串 '2' 会被转化为数字 2
'01' == 1// true,字符串 '01' 会被转化为数字 1
'a' == 1//永远都是false 因为 'a' => Number('a') = NaN , NaN 跟任何数字判断都为 false
'a' > 1//false
'0' == false//true
'' == false//true
严格相等
'' === false // false
null 和 undefined 进行比较
undefined 和 null 在相等性检查 == 中不会进行任何的类型转换,
"> < >= <= " 这些是正常转化 Number, Number(null) => 0 Number(undefined) => NaN
null === undefined // false
null == undefined // false //js特殊处理了, 只在非严格相等下成立
null < undefined //false 会正常转化成 数字,Number(null) => 0 Number(undefined) => NaN
null > 0 // (1) false
null == 0 // (2) false
null >= 0 // (3) true
"0" == +"\n0\n" //true 这里 +先执行 Number(“\n0\n”) => 0 ,然后 "0" == 0 比较,Number("0") == 0
##总结
-
除了严格相等 === 外,其他但凡是有 undefined/null 参与的比较,我们都需要格外小心。
-
除非你非常清楚自己在做什么,否则永远不要使用 >= > < <= 去比较一个可能为 null/undefined 的变量。对于取值可能是 null/undefined 的变量,请按需要分别检查它的取值情况。
-
比较运算符始终返回布尔值。
-
字符串的比较,会按照“词典”顺序逐字符地比较大小。
-
当对不同类型的值进行比较时,它们会先被转化为数字(不包括严格相等检查)再进行比较。
-
在非严格相等 == 下,null 和 undefined 相等且各自不等于任何其他的值。
-
在使用 > 或 < 进行比较时,需要注意变量可能为 null/undefined 的情况。比较好的方法是单独检查变量是否等于 null/undefined。
条件分支
? 三元运算法,优先级比较低
let age = 1
let a = (age > 18) ? true : false; //
//括号可以省略
let a = age > 18 ? true : false;
多个 ‘?’
let age = prompt('age?', 18);
let message = (age < 3) ? 'Hi, baby!' :
(age < 18) ? 'Hello!' :
(age < 100) ? 'Greetings!' :
'What an unusual age!';
alert( message );
//等价于
if (age < 3) {
message = 'Hi, baby!';
} else if (age < 18) {
message = 'Hello!';
} else if (age < 100) {
message = 'Greetings!';
} else {
message = 'What an unusual age!';
}
逻辑运算符
判断时候 会自动做Boolean(value) 转化
||(或)
1.或运算寻找第一个真值
- result = value1 || value2 || value3;
- 从左到右依次计算操作数。
- 处理每一个操作数时,都将其转化为布尔值。如果结果是 true,就停止计算,返回这个操作数的初始值。
- 如果所有的操作数都被计算过(也就是,转换结果都是 false),则返回最后一个操作数。
//中间true 直接返回中间值
let firstName = '' ,lastName = 'bbb' ,lastName = '' ;
firstName || lastName || lastName || "aaa"); // bbb
//中间前面都是false ,直接返回最后一个
let firstName = '' ,lastName = '' ,lastName = '' ;
firstName || lastName || lastName || "aaa"); // aaa
1.短路求值(Short-circuit evaluation)
操作数可以是:变量赋值或函数调用
true || alert("not printed");
false || alert("printed");
- 在第一行中,或运算符 || 在遇到 true 时立即停止运算,所以 alert 没有运行。
- 有时,人们利用这个特性,只在左侧的条件为假时才执行命令。
&&(与)
与运算寻找第一个假值
1 && 2 && 3 // 输出 3
同时存在 && 和 ||
可以使用 ( 1 && 2 ) 把 "与"内容包裹 如:
0 || 2 && 0 || 3 && 4
//等价于
0 || (2 && 0) || (3 && 4) // => 0 || 0 || 4 结果为 4
!(非)
Boolean(value) 返回相反值 ,优先级在所有逻辑运算符里面最高,在&& 和 || 之前执行。 两个非运算 !! 有时候用来将某个值转化为布尔类型:
alert( !!"non-empty string" ); // true
alert( !!null ); // false
空值合并运算符 '??' (新符号)
第一个参数不是 null/undefined,则 ?? 返回第一个参数。否则,返回第二个参数。
let a,b;
a ?? b
//等价于
(a !== null && a !== undefined) ? a : b;
//连续判断
let firstName = null;
let lastName = null;
let nickName = "Supercoder";
// 显示第一个已定义的值:
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder
?? 与 || 比较
let height = 0;
alert(height || 100); // 100 // Boolean(0) = false
alert(height ?? 100); // 0 // 不是undefined 也不是null
优先级
?? 在 = 和 ? 之前计算,但在大多数其他运算符(例如,+ 和 *)之后计算。
出于安全原因,JS 禁止将 ?? 运算符与 && 和 || 运算符一起使用,除非使用括号明确指定了优先级。
let x = 1 && 2 ?? 3; // Syntax error
let x = 1 && (2 ?? 3); // 正常
循环:while 和 for
while
while (i != 0) 可简写为 while (i):
let i = 3;
while (i) { // 当 i 变成 0 时,条件为假,循环终止
alert( i );
i--;
}
//单行循环体不需要大括号
while (i) alert(i--);
“do…while” 循环
let i = 0;
do {
alert( i );
i++;
} while (i < 3);
for
//内联变量声明
for (let i = 0; i < 3; i++) {
alert(i); // 0, 1, 2
}
alert(i); // 错误,没有这个变量。
//可以通过外部定义
let i = 0;
for (i = 0; i < 3; i++) { // 使用现有的变量
alert(i); // 0, 1, 2
}
alert(i); //3,可见,因为是在循环之外声明的
//省略语句段
//省略begin
let i = 0; // 我们已经声明了 i 并对它进行了赋值
for (; i < 3; i++) { // 不再需要 "begin" 语句段
alert( i ); // 0, 1, 2
}
//省略step
let i = 0;
for (; i < 3;) {
alert( i++ );
}
//等价于
while (i < 3)
//省略所有
for (;;) {
// 无限循环
}
break/continue
break 终止循环 , continue 继续下一个循环 禁止 break/continue 在 ‘?’ 的右边
(i > 5) ? alert(i) : continue; // continue 不允许在这个位置
标签 xxx:
xxx: 定义 ,break outer必须要循环内部
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++) {...}
题目:重复输入,直到正确为大于100的值为止
let input
do {
input = prompt("请输入大于100数字")
}while(input <= 100 && input)
题目 :输出素数(prime)
let n = 10
outer: for(let i = 2;i <= n;i++){
let j = 2;
while(j<i ){
if(i%j === 0) { //当前不是素数
// console.log("当前不是素数",i)
continue outer;
}
j++
}
console.log("素数",i)
}
switch
- 如果相等,switch 语句就执行相应 case 下的代码块,直到遇到最靠近的 break 语句.
- 如果没有符合的 case,则执行 default 代码块(如果 default 存在)。
//case的内容是 严格匹配 ===
let a = 2
switch(a) {
case '2': alert("ddd")
}
//无效 2 === '2' => false
任何表达式都可以成为 switch/case 的参数
let a = "1";
let b = 0;
switch (+a) {
case b + 1:
alert("this runs, because +a is 1, exactly equals b+1");
break;
default:
alert("this doesn't run");
}
case 分组
let a = 3;
switch (a) {
case 4:
alert('Right!');
break;
case 3: // (*) 下面这两个 case 被分在一组
case 5:
alert('Wrong!');
alert("Why don't you take a math class?");
break;
default:
alert('The result is strange. Really.');
}
函数
局部变量
function showMessage() {
let message = "Hello, I'm JavaScript!"; // 局部变量
alert( message );
}
showMessage(); // Hello, I'm JavaScript!
alert( message ); // <-- 错误!变量是函数的局部变量
外部变量
let userName = 'John';
function showMessage() {
let message = 'Hello, ' + userName;
alert(message);
}
showMessage(); // Hello, John
局部变量 和 外部变量 同时存在,优先使用内部
参数
函数可以修改参数,但在函数外部看不到更改,函数修改的是复制的变量值副本:
function showMessage(from, text) {
from = '*' + from + '*'; // 让 "from" 看起来更优雅
alert( from + ': ' + text );
}
let from = "Ann";
showMessage(from, "Hello"); // *Ann*: Hello
// "from" 值相同,函数修改了一个局部的副本。
alert( from ); // Ann //值没有变化
默认值
没有设置参数,默认值则是 undefined。
//可以指定默认
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}
showMessage("Ann"); // Ann: no text given
后备的默认参数
//1 自己判断
function showMessage(text) {
if (text === undefined) {
text = 'empty message';
}
alert(text);
}
showMessage(); // empty message
//2.|| 运算符
function showMessage(text) {
text = text || 'empty';
...
}
//3.空值合并运算符 ??
function showCount(count) {
alert(count ?? "unknown");
}
showCount(0); // 0
showCount(null); // unknown
showCount(); // unknown
return
不要在 return 与返回值之间添加新行
空值的 return 或没有 return 的函数返回值为 undefined
函数命名
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!