2024年最全初中级前端 JavaScript 自测清单 - 1,面试前端

最后

全网独播-价值千万金融项目前端架构实战

从两道网易面试题-分析JavaScript底层机制

RESTful架构在Nodejs下的最佳实践

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

一线互联网企业如何初始化项目-做一个自己的vue-cli

思维无价,看我用Nodejs实现MVC

代码优雅的秘诀-用观察者模式深度解耦模块

前端高级实战,如何封装属于自己的JS库

VUE组件库级组件封装-高复用弹窗组件

在 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 转换为 0undefied 转换为 NaN

null > 0;  // false 1

null >= 0; // true  2

null == 0; // false 3

null < 1;  // true  4

需要注意:null == 0; // false 这里是因为:undefinednull 在相等性检查 == 中**「不会进行任何的类型转换」**,它们有自己独立的比较规则,所以除了它们之间互等外,不会等于任何其他的值。

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、空字符串 ""nullundefinedNaN 都会被转换成 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. 注意点


  1. 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

  1. **如果没有 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

  1. **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

当函数内也有与外部变量名称相同的变量,会忽略外部变量:

let name = ‘leo’;

let fun = function(){

let name = ‘pingan8787’;

let text = 'Hello, ’ + name;

console.log(text);

}

fun(); // Hello, pingan8787

4. 函数参数


从ECMAScript 6开始,有两个新的类型的参数:默认参数,剩余参数。

4.1 默认参数

若函数没有传入参数,则参数默认值为undefined,通常设置参数默认值是这样做的:

// ES6 之前,没有设置默认值

function f(a, b){

b = b ? b : 1;

return a * b;

}

f(2,3);  // 6

f(2);    // 2

// ES6,设置默认值

function f(a, b = 1){

return a * b;

}

f(2,3);  // 6

f(2);    // 2

4.2 剩余参数

可以将参数中不确定数量的参数表示成数组,如下:

function f (a, …b){

console.log(a, b);

}

f(1,2,3,4); // a => 1 b => [2, 3, 4]

既然讲到参数,那就不能少了 arguments 对象。

4.3 arguments 对象

函数的实际参数会被保存在一个**「类似数组的arguments对象」**中。在函数内,我们可以使用 arguments 对象获取函数的所有参数:

let fun = function(){

console.log(arguments);

console.log(arguments.length);

}

fun(‘leo’);

// Arguments [“leo”, callee: ƒ, Symbol(Symbol.iterator): ƒ]

// 1

以一个实际示例介绍,实现将任意数量参数连接成一个字符串,并输出的函数:

let argumentConcat = function(separator){

let result = ‘’, i;

for(i = 1; i < arguments.length; i ++){

result += arguments[i] + separator;

}

return result;

}

argumentConcat(‘,’, ‘leo’, ‘pingan’); //“leo,pingan,”

5. 函数返回值


在函数任意位置,指定 return 指令来停止函数的执行,并返回函数指定的返回值。

let sum = function(a, b){

return a + b;

};

let res = sum(1, 2);

console.log(res); // 3

默认空值的 return 或没有 return 的函数返回值为 undefined

十五、函数表达式

========

函数表达式是一种函数定义方式,在前面章节中已经介绍到了,这个部分将着重介绍 「函数表达式」「函数声明」 的区别:

1. 语法差异


// 函数表达式

let fun = function(){};

// 函数声明

function fun(){}

2. 创建时机差异


函数表达式会在代码执行到达时被创建,并且仅从那一刻可用。而函数声明被定义之前,它就可以被调用。

// 函数表达式

fun();  // Uncaught ReferenceError: fun is not defined

let fun = function(){console.log(‘leo’)};

// 函数声明

fun();  // “leo”

function fun(){console.log(‘leo’)};

3. 使用建议


建议优先考虑函数声明语法,它能够为组织代码提供更多灵活性,因为我们可以在声明函数前调用该函数。

十六、箭头函数

=======

「本章节简单介绍箭头函数基础知识,后面章节会完整介绍。」****「函数箭头表达式」是ES6新增的函数表达式的语法,也叫「胖箭头函数」,变化:更简洁的函数和this

1. 代码更简洁


// 有1个参数

let f = v => v;

// 等同于

let f = function (v){return v};

// 有多个参数

let f = (v, i) => {return v + i};

// 等同于

let f = function (v, i){return v + i};

// 没参数

let f = () => 1;

// 等同于

let f = function (){return 1};

let arr = [1,2,3,4];

最后

全网独播-价值千万金融项目前端架构实战

从两道网易面试题-分析JavaScript底层机制

RESTful架构在Nodejs下的最佳实践

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

一线互联网企业如何初始化项目-做一个自己的vue-cli

思维无价,看我用Nodejs实现MVC

代码优雅的秘诀-用观察者模式深度解耦模块

前端高级实战,如何封装属于自己的JS库

VUE组件库级组件封装-高复用弹窗组件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值