typeof [1,2,3,4] // "object"
typeof Math // "object" (1) Math 是一个提供数学运算的内建 object。
typeof null // "object" (2) JavaScript 语言的一个错误,null 不是一个 object。null 有自己的类型,它是一个特殊值。
typeof alert // "function" (3) alert 在 JavaScript 语言中是一个函数。
六、类型转换
======
JavaScript 变量可以转换为新变量或其他数据类型:
-
通过使用 JavaScript 函数
-
通过 JavaScript 自身自动转换
1. 字符串转换
通过全局方法 String() 将 「其他类型数据(任何类型的数字,字母,布尔值,对象)」 转换为 String 类型:
String(123); // "123"
// Number方法toString()/toExponential()/toFixed()/toPrecision() 也有同样效果。
String(false); // "false"
// Boolean方法 toString() 也有同样效果。
String(new Date()); // "Sun Jun 07 2020 21:44:20 GMT+0800 (中国标准时间)"
// Date方法 toString() 也有同样效果。
String(leo);
2. 数值转换
通过以下几种方式能将其他类型数据转换为 Number 类型:
- 一元运算符
+
const age = +"22"; // 22
Number方法
const age = Number("22"); // 22
Number.parseFloat("22"); // 22
Number.parseInt("22"); // 22
- 其他方式转 Number 类型
// 布尔值
Number(false) // 返回 0
Number(true) // 返回 1
// 日期
const date = new Date();
Number(date); // 返回 1591537858154
date.getTime(); // 返回 1591537858154,效果一致。
// 自动转换
5 + null // 返回 5 null 转换为 0
"5" + null // 返回"5null" null 转换为 "null"
"5" + 1 // 返回 "51" 1 转换为 "1"
"5" - 1 // 返回 4 "5" 转换为 5
3. 布尔值转换
转换规则如下:
-
直观上为“空”的值(如
0、空字符串、null、undefined和NaN)将变为false。 -
其他值变成
true。
Boolean(1); // true
Boolean(0); // false
Boolean("hello"); // true
Boolean(""); // false
Boolean("0"); // true
Boolean(" "); // 空白, 也是 true (任何非空字符串是 true)
4. 小结
image2.png
七、运算符
=====
1、运算符概念
常见运算符如加法 + 、减法 - 、乘法 * 和除法 / ,举一个例子,来介绍一些概念:
let sum = 1 + 2;
let age = +18;
其中:
-
加法运算
1 + 2中,1和2为 2 个运算元,左运算元1和右运算元2,即**「运算元就是运算符作用的对象。」** -
1 + 2运算式中包含 2 个运算元,因此也称该运算式中的加号+为 「二元运算符。」 -
在
+18中的加号+对应只有一个运算元,则它是 「一元运算符」 。
2、+ 号运算符
let msg = "hello " + "leo"; // "hello leo"
let total = 10 + 20; // 30
let text1 = "1" + "2"; // "12"
let text2 = "1" + 2; // "12"
let text3 = 1 + "2"; // "12"
let text4 = 1 + 2 + "3"; // "33"
let num = +text1; // 12 转换为 Number 类型
3、运算符优先级
运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。下面的表将所有运算符按照优先级的不同从高(20)到低(1)排列。
| 优先级 | 运算类型 | 关联性 | 运算符 |
| --- | --- | --- | --- |
| 20 | 圆括号 | n/a(不相关) | ( … ) |
| 19 | 成员访问 | 从左到右 | … . … |
|
| 需计算的成员访问 | 从左到右 | … [ … ] |
|
| new (带参数列表) | n/a | new … ( … ) |
|
| 函数调用 | 从左到右 | … ( … ) |
|
| 可选链(Optional chaining) | 从左到右 | ?. |
| 18 | new (无参数列表) | 从右到左 | new … |
| 17 | 后置递增(运算符在后) | n/a |
|
| … ++ |
|
|
|
|
| 后置递减(运算符在后) |
| … -- |
| 16 | 逻辑非 | 从右到左 | ! … |
|
| 按位非 |
| ~ … |
|
| 一元加法 |
| + … |
|
| 一元减法 |
| - … |
|
| 前置递增 |
| ++ … |
|
| 前置递减 |
| -- … |
|
| typeof |
| typeof … |
|
| void |
| void … |
|
| delete |
| delete … |
|
| await |
| await … |
| 15 | 幂 | 从右到左 | … ** … |
| 14 | 乘法 | 从左到右 |
|
| … * … |
|
|
|
|
| 除法 |
| … / … |
|
| 取模 |
| … % … |
| 13 | 加法 | 从左到右 |
|
| … + … |
|
|
|
|
| 减法 |
| … - … |
| 12 | 按位左移 | 从左到右 | … << … |
|
| 按位右移 |
| … >> … |
|
| 无符号右移 |
| … >>> … |
| 11 | 小于 | 从左到右 | … < … |
|
| 小于等于 |
| … <= … |
|
| 大于 |
| … > … |
|
| 大于等于 |
| … >= … |
|
| in |
| … in … |
|
| instanceof |
| … instanceof … |
| 10 | 等号 | 从左到右 |
|
| … == … |
|
|
|
|
| 非等号 |
| … != … |
|
| 全等号 |
| … === … |
|
| 非全等号 |
| … !== … |
| 9 | 按位与 | 从左到右 | … & … |
| 8 | 按位异或 | 从左到右 | … ^ … |
| 7 | 按位或 | 从左到右 | … | … |
| 6 | 逻辑与 | 从左到右 | … && … |
| 5 | 逻辑或 | 从左到右 | … || … |
| 4 | 条件运算符 | 从右到左 | … ? … : … |
| 3 | 赋值 | 从右到左 | … = … |
|
|
|
| … += … |
|
|
|
| … -= … |
|
|
|
| … *= … |
|
|
|
| … /= … |
|
|
|
| … %= … |
|
|
|
| … <<= … |
|
|
|
| … >>= … |
|
|
|
| … >>>= … |
|
|
|
| … &= … |
|
|
|
| … ^= … |
|
|
|
| … |= … |
| 2 | yield | 从右到左 | yield … |
|
| yield* |
| yield* … |
| 1 | 展开运算符 | n/a | ... … |
| 0 | 逗号 | 从左到右 | … , … |
3 > 2 && 2 > 1
// return true
3 > 2 > 1
// 返回 false,因为 3 > 2 是 true,并且 true > 1 is false
// 加括号可以更清楚:(3 > 2) > 1
八、值的比较
======
1. 常见比较
在 JS 中的值的比较与数学很类型:
-
大于/小于/大于等于/小于等于:
a>b/a<b/a>=b/a<=b; -
判断相等:
// 使用 ==,非严格等于,不关心值类型
// == 运算符会对比较的操作数做隐式类型转换,再比较
'1' == 1; // true
// 使用 ===,严格相等,关心值类型
// 将数字值 -0 和 +0 视为相等,并认为 Number.NaN 不等于 NaN。
'1' === 1; // false
(图片来自:《MDN JavaScript 中的相等性判断》)
- 判断不相等:和判断相等一样,也有两种:
!=/!==。
2. 相等性判断(Object.is())
另外 ES6 新增 Object.is 方法判断两个值是否相同,语法如下:
Object.is(value1, value2);
以下任意项成立则两个值相同:
-
两个值都是
undefined -
两个值都是
null -
两个值都是
true或者都是false -
两个值是由相同个数的字符按照相同的顺序组成的字符串
-
两个值指向同一个对象
-
两个值都是数字并且
-
- 都是正零
+0
- 都是正零
-
都是负零
-0 -
都是
NaN -
都是除零和
NaN外的其它同一个数字 使用示例:
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
兼容性 Polyfill 处理:
if (!Object.is) {
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
}
3. null 与 undefined 比较
对于相等性判断比较简单:
null == undefined; // true
null === undefined; // false
对于其他比较,它们会先转换位数字:null 转换为 0 , undefied 转换为 NaN 。
null > 0; // false 1
null >= 0; // true 2
null == 0; // false 3
null < 1; // true 4
需要注意:null == 0; // false 这里是因为:undefined 和 null 在相等性检查 == 中**「不会进行任何的类型转换」**,它们有自己独立的比较规则,所以除了它们之间互等外,不会等于任何其他的值。
undefined > 0; // false 1
undefined > 1; // false 2
undefined == 0; // false 3
第 1、2 行都返回 false 是因为 undefined 在比较中被转换为了 NaN,而 NaN 是一个特殊的数值型值,它与任何值进行比较都会返回 false。第 3 行返回 false 是因为这是一个相等性检查,而 undefined 只与 null 相等,不会与其他值相等。
九、alert / prompt / confirm
==========================
1. alert
显示一个警告对话框,上面显示有指定的文本内容以及一个“确定”按钮。「注意:弹出模态框,并暂停脚本,直到用户点击“确定”按钮。」
// 语法
window.alert(message);
alert(message);
// 示例
alert('hello leo!');
message是要显示在对话框中的文本字符串,如果传入其他类型的值,会转换成字符串。
2. prompt
显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字。**「注意:弹出模态框,并暂停脚本,直到用户点击“确定”按钮。」**当点击确定返回文本,点击取消或按下 Esc 键返回 null。语法如下:
let result = window.prompt(text, value);
-
result用来存储用户输入文字的字符串,或者是 null。 -
text用来提示用户输入文字的字符串,如果没有任何提示内容,该参数可以省略不写。 -
value文本输入框中的默认值,该参数也可以省略不写。不过在 Internet Explorer 7 和 8 中,省略该参数会导致输入框中显示默认值"undefined"。
3. confirm
Window.confirm() 方法显示一个具有一个可选消息和两个按钮(确定和取消)的模态对话框。**「注意:弹出模态框,并暂停脚本,直到用户点击“确定”按钮。」**语法如下:
let result = window.confirm(message);
-
message 是要在对话框中显示的可选字符串。
-
result 是一个布尔值,表示是选择确定还是取消 (true表示OK)。
十、条件运算符:if 和 '?'
================
1. if 语句
当 if 语句当条件表达式,会将表达式转换为布尔值,当为 truthy 时执行里面代码。转换规则如:
-
数字
0、空字符串""、null、undefined和NaN都会被转换成false。因为他们被称为 “falsy” 值。 -
其他值被转换为
true,所以它们被称为 “truthy”。
2. 三元运算符
**「条件(三元)运算符」**是 JavaScript 仅有的使用三个操作数的运算符。一个条件后面会跟一个问号(?),如果条件为 truthy ,则问号后面的表达式A将会执行;表达式A后面跟着一个冒号(:),如果条件为 falsy ,则冒号后面的表达式B将会执行。本运算符经常作为 [if]( ) 语句的简捷形式来使用。语法:
condition ? exprIfTrue : exprIfFalse
-
condition 计算结果用作条件的表达式。
-
exprIfTrue 如果表达式 condition 的计算结果是 truthy(它和 true 相等或者可以转换成 true ),那么表达式 exprIfTrue 将会被求值。
-
exprIfFalse 如果表达式 condition 的计算结果是 falsy(它可以转换成 false ),那么表达式 exprIfFalse 将会被执行。示例:
let getUser = function(name){
return name === 'leo' ? 'hello leo!' : 'unknow user';
}
// 可以简写如下:
let getUser = name => name === 'leo' ? 'hello leo!' : 'unknow user';
getUser('leo'); // "hello leo!"
getUser('pingan'); // "unknow user"
十一、逻辑运算符
========
详细可以阅读《MDN 逻辑运算符》 。
1. 运算符介绍
逻辑运算符如下表所示 (其中_expr_可能是任何一种类型, 不一定是布尔值):
| 运算符 | 语法 | 说明 |
| --- | --- | --- |
| 逻辑与,AND(&&) | _expr1_ && _expr2_ | 若 expr**1** 可转换为 true,则返回 expr**2**;否则,返回 expr**1**。 |
| 逻辑或,OR(||) | _expr1_ || _expr2_ | 若 expr**1** 可转换为 true,则返回 expr**1**;否则,返回 expr**2**。 |
| 逻辑非,NOT(!) | !_expr_ | 若 expr 可转换为 true,则返回 false;否则,返回 true。 |
如果一个值可以被转换为 true,那么这个值就是所谓的 truthy,如果可以被转换为 false,那么这个值就是所谓的 falsy。会被转换为 false 的表达式有:
-
null; -
NaN; -
0; -
空字符串(
""or''or ````); -
undefined。尽管&&和||运算符能够使用非布尔值的操作数, 但它们依然可以被看作是布尔操作符,因为它们的返回值总是能够被转换为布尔值。如果要显式地将它们的返回值(或者表达式)转换为布尔值,请使用双重非运算符(即!!)或者Boolean构造函数。JavaScript 里有三个逻辑运算符:||(或),&&(与),!(非)。
2. 运算符示例
- 逻辑与(&&) 所有条件都为 true 才返回 true,否则为 false。
a1 = true && true // t && t 返回 true
a2 = true && false // t && f 返回 false
a3 = false && true // f && t 返回 false
a4 = false && (3 == 4) // f && f 返回 false
a5 = "Cat" && "Dog" // t && t 返回 "Dog"
a6 = false && "Cat" // f && t 返回 false
a7 = "Cat" && false // t && f 返回 false
a8 = '' && false // f && f 返回 ""
a9 = false && '' // f && f 返回 false
- 逻辑或( || ) 所有条件有一个为 true 则返回 true,否则为 false。
o1 = true || true // t || t 返回 true
o2 = false || true // f || t 返回 true
o3 = true || false // t || f 返回 true
o4 = false || (3 == 4) // f || f 返回 false
o5 = "Cat" || "Dog" // t || t 返回 "Cat"
o6 = false || "Cat" // f || t 返回 "Cat"
o7 = "Cat" || false // t || f 返回 "Cat"
o8 = '' || false // f || f 返回 false
o9 = false || '' // f || f 返回 ""
- 逻辑非( ! )
n1 = !true // !t 返回 false
n2 = !false // !f 返回 true
n3 = !'' // !f 返回 true
n4 = !'Cat' // !t 返回 false
- 双重非运( !! )
n1 = !!true // !!truthy 返回 true
n2 = !!{} // !!truthy 返回 true: 任何 对象都是 truthy 的…
n3 = !!(new Boolean(false)) // …甚至 .valueOf() 返回 false 的布尔值对象也是!
n4 = !!false // !!falsy 返回 false
n5 = !!"" // !!falsy 返回 false
n6 = !!Boolean(false) // !!falsy 返回 false
3. 布尔值转换规则
- 将 && 转换为 ||
condi1 && confi2
// 转换为
!(!condi1 || !condi2)
- 将 || 转换为 &&
condi1 || condi2
// 转换为
!(!condi1 && !condi2)
4. 短路取值
由于逻辑表达式的运算顺序是从左到右,也可以用以下规则进行"短路"计算:
-
(some falsy expression) && (_expr)_短路计算的结果为假。 -
(some truthy expression) || _(expr)_短路计算的结果为真。短路意味着上述表达式中的expr部分**「不会被执行」**,因此expr的任何副作用都不会生效(举个例子,如果expr是一次函数调用,这次调用就不会发生)。造成这种现象的原因是,整个表达式的值在第一个操作数被计算后已经确定了。看一个例子:
function A(){ console.log('called A'); return false; }
function B(){ console.log('called B'); return true; }
console.log( A() && B() );
// logs "called A" due to the function call,
// then logs false (which is the resulting value of the operator)
console.log( B() || A() );
// logs "called B" due to the function call,
// then logs true (which is the resulting value of the operator)
5. 注意
与运算 && 的优先级比或运算 || 要高。所以代码 a && b || c && d 完全跟 && 表达式加了括号一样:(a && b) || (c && d)。
十二、循环:while 和 for
=================
1. while 循环
详细可以阅读《MDN while》 。**「while 语句」**可以在某个条件表达式为真的前提下,循环执行指定的一段代码,直到那个表达式不为真时结束循环。如:
var n = 0;
var x = 0;
while (n < 3) {
n++;
x += n;
}
当循环体为单行时,可以不写大括号:
let i = 3;
while(i) console.log(i --);
2. do...while 循环
详细可以阅读《MDN do...while》 。do...while 语句创建一个执行指定语句的循环,直到condition值为 false。在执行statement 后检测condition,所以指定的statement至少执行一次。如:
var result = '';
var i = 0;
do {
i += 1;
result += i + ' ';
} while (i < 5);
3. for 循环
详细可以阅读《MDN for》 。for 语句用于创建一个循环,它包含了三个可选的表达式,这三个表达式被包围在圆括号之中,使用分号分隔,后跟一个用于在循环中执行的语句(通常是一个块语句)。语法如:
for (begin; condition; step) {
// ……循环体……
}
示例:
for (let i = 0; i < 3; i++) {
console.log(i);
}
描述:
| begin | i = 0 | 进入循环时执行一次。 |
| --- | --- | --- |
| condition | i < 3 | 在每次循环迭代之前检查,如果为 false,停止循环。 |
| body(循环体) | alert(i) | 条件为真时,重复运行。 |
| step | i++ | 在每次循环体迭代后执行。 |
4. 可选的 for 表达式
for 语句头部圆括号中的所有三个表达式都是可选的。
- 不指定表达式中初始化块
var i = 0;
for (; i < 3; i++) {
console.log(i);
}
- 不指定表达式中条件块,这就必须要求在循环体中结束循环,否则会出现死循环
for (var i = 0;; i++) {
console.log(i);
if (i > 3) break;
}
- 不指定所有表达式,也需要在循环体中指定结束循环的条件
var i = 0;
for (;;) {
if (i > 3) break;
console.log(i);
i++;
}
5. break 语句
详细可以阅读《MDN break》 。break 语句中止当前循环,switch语句或label 语句,并把程序控制流转到紧接着被中止语句后面的语句。在 while 语句中:
function testBreak(x) {
var i = 0;
while (i < 6) {
if (i == 3) {
break;
}
i += 1;
}
return i * x;
}
另外,也可以为代码块做标记,并在 break 中指定要跳过的代码块语句的 label:
outer_block:{
inner_block:{
console.log ('1');
break outer_block; // breaks out of both inner_block and outer_block
console.log (':-('); // skipped
}
console.log ('2'); // skipped
}
需要注意的是:break 语句需要内嵌在它所应用的标签或代码块中,否则报错:
block_1:{
console.log ('1');
break block_2; // SyntaxError: label not found
}
block_2:{
console.log ('2');
}
6. continue 语句
continue 声明终止当前循环或标记循环的当前迭代中的语句执行,并在下一次迭代时继续执行循环。与 break 语句的区别在于, continue 并不会终止循环的迭代,而是:
-
在
while循环中,控制流跳转回条件判断; -
在
for循环中,控制流跳转到更新语句。注意:continue 也必须在对应循环内部,否则报错。
i = 0;
n = 0;
while (i < 5) {
i++;
if (i === 3) {
continue;
}
n += i;
}
带 label:
var i = 0,
j = 8;
checkiandj: while (i < 4) {
console.log("i: " + i);
i += 1;
checkj: while (j > 4) {
console.log("j: "+ j);
j -= 1;
if ((j % 2) == 0)
continue checkj;
console.log(j + " is odd.");
}
console.log("i = " + i);
console.log("j = " + j);
}
7. 注意
「禁止 「break/continue」 在 ‘?’ 的右边:」
(i > 5) ? console.log(i) : continue; // continue 不允许在这个位置
这样会提示语法错误。请注意非表达式的语法结构不能与三元运算符 ? 一起使用。特别是 break/continue 这样的指令是不允许这样使用的。
8. 总结
三种循环:
-
while—— 每次迭代之前都要检查条件。 -
do..while—— 每次迭代后都要检查条件。 -
for (;;)—— 每次迭代之前都要检查条件,可以使用其他设置。通常使用while(true)来构造“无限”循环。这样的循环和其他循环一样,都可以通过break指令来终止。如果我们不想在当前迭代中做任何事,并且想要转移至下一次迭代,那么可以使用continue指令。break/continue支持循环前的标签。标签是break/continue跳出嵌套循环以转到外部的唯一方法。
十三、"switch" 语句
==============
switch 语句用来将表达式的值与 case 语句匹配,并执行与情况对应的语句。switch 语句可以替代多个 if 判断,为多个分支选择的情况提供一个更具描述性的方式。
1. 语法
switch 语句至少包含一个 case 代码块和一个可选的 default 代码块:
switch(expression) {
case 'value1':
// do something ...
[break]
default:
// ...
[break]
}
当 expression 表达式的值与 value1 匹配时,则执行其中代码块。如果没有 case 子句匹配,则会选择 default 子句执行,若连 default 子句都没有,则直接执行到 switch 结束。
2. 使用 case 分组
所谓 case 分组,就是与多个 case 分支共享同一段代码,如下面例子中 case 1 和 case 2:
let a = 2;
switch (a) {
case 1: // (*) 下面这两个 case 被分在一组
case 2:
console.log('case is 1 or 2!');
break;
case 3:
console.log('case is 3!');
break;
default:
console.log('The result is default.');
}
// 'case is 1 or 2!'
3. 注意点
- 「
expression表达式的值与case值的比较是严格相等:」
function f(n){
let a ;
switch(n){
case 1:
a = 'number';
break;
case '1':
a = 'string';
break;
default:
a = 'default';
break;
}
console.log(a)
}
f(1); // number
f('1'); // string
- **如果没有
break,程序将不经过任何检查就会继续执行下一个 ****case**:
let a = 2 + 2;
switch (a) {
case 3:
console.log( 'Too small' );
case 4:
console.log( 'Exactly!' );
case 5:
console.log( 'Too big' );
default:
console.log( "I don't know such values" );
}
// Exactly!
// Too big
// I don't know such values
**default****放在 ****case**「之上不影响匹配:」
function f(n){
switch (n) {
case 2:
console.log(2);
break;
default:
console.log('default')
break;
case 1:
console.log('1');
break;
}
}
f(1); // 1
f(2); // 2
f(3); // default
- 「
switch语句中存在let/const重复声明问题:」
// 以下定义会报错
function f(n){
switch(n){
case 1:
let msg = 'hello';
console.log(1);
break;
case 2:
let msg = 'leo';
break;
default:
console.log('default');
break;
}
}
// Error: Uncaught SyntaxError: Identifier 'msg' has already been declared
这是由于两个 let 处于同一个块级作用域,所以它们被认为是同一变量名的重复声明。解决方式,只需要将 case 语句包装在括号内即可解决:
function f(n){
switch(n){
case 1:{ // added brackets
let msg = 'hello';
console.log(msg);
break;
}
case 2: {
let msg = 'leo';
console.log(msg);
break;
}
default:
console.log('default');
break;
}
}
十四、函数
=====
函数可以让一段代码被多次调用,避免重复代码。如之前学习到的一些内置函数:alert(msg) / prompt(msg, default) / confirm(quesyion) 等。
1. 函数定义
定义函数有两种方式:「函数声明」和「函数表达式」。
1.1 函数声明
如定义一个简单 getUser 函数:
function getUser(name){
return 'hello ' + name;
}
getUser('leo"); // 函数调用
通过函数声明来定义函数时,需要由以下几部分组成:
-
函数名称 -
getUser; -
函数参数列表 -
name; -
函数的 JS 执行语句 -
return 'hello ' + name。
1.2 函数表达式
类似声明变量,还是以 getUser 为例:
let getUser = function(name){
return 'hello ' + name;
}
另外,函数表达式也可以提供函数名,并用于函数内部指代函数本身:
let fun = function f(n){
return n < 3 ? 1 : n * f(n - 1);
}
fun(3); // 3
fun(5); // 60
2. 函数调用
当定义一个函数后,它并不会自动执行,而是需要使用函数名称进行调用,如上面例子:
fun(3); // 3
**「只要注意:」**使用 「函数表达式」 定义函数时,调用函数的方法必须写在定义之后,否则报错:
console.log(fun()); // Uncaught ReferenceError: fun is not defined
let fun = function(){return 1};
而使用 「函数声明」 则不会出现该问题:
console.log(fun()); // 1
function fun(){return 1};
原因就是:函数提升仅适用于函数声明,而不适用于函数表达式。
3. 函数中的变量
在函数中,可以使用局部变量和外部变量。
3.1 局部变量
函数中声明的变量只能在该函数内可见。
let fun = function(){
let name = 'leo';
}
fun();
console.log(name); // Uncaught ReferenceError: name is not defined
3.2 全局变量
函数内可以使用外部变量,并且可以修改外部变量的值。
let name = 'leo';
let fun = function(){
let text = 'Hello, ' + name;
console.log(text);
}
fun(); // Hello, leo
总结
-
对于框架原理只能说个大概,真的深入某一部分具体的代码和实现方式就只能写出一个框架,许多细节注意不到。
-
算法方面还是很薄弱,好在面试官都很和蔼可亲,擅长发现人的美哈哈哈...(最好多刷一刷,不然影响你的工资和成功率????)
-
在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。
-
要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!
第一次跳槽十分忐忑不安,和没毕业的时候开始找工作是一样的感受,真的要相信自己,有条不紊的进行。如果有我能帮忙的地方欢迎随时找我,比如简历修改、内推、最起码,可以把烦心事说一说,人嘛都会有苦恼的~
祝大家都有美好的未来,拿下满意的 offer。 开源分享:docs.qq.com/doc/DSmRnRG…