认识前端--JS| 青训营笔记

67 阅读3分钟

认识前端--JS(一)

这是我参与「第四届青训营 」笔记创作活动的第5天

在青训营 JS 课程学习下再次回顾 JS 部分内容,本文主要分类做一些简单介绍帮助巩固知识,有不妥地方劳烦指正。

ECMA-262第6版规定的所有关键字

break       do          in          typeof 
case        else        instanceof  var 
catch       export      new         void 
class       extends     return      while 
const       finally     super       with 
continue    for         switch      yield 
debugger    function    this 
default     if          throw 
delete      import      try 

声明变量的关键字

  • var
  • let
  • const

var 兼容所有版本、letconst 兼容 es6 及其以后。

var声明

1.var 声明作用域(在函数内部定义变量,函数退出时被销毁即函数作用域)。

function test() { 
 var message = "hi"; // 局部变量
} 
test(); 
console.log(message); // 出错!//如果省略var操作符,可以创建一个全局变量(下面方式非常不推荐,在严格模式下,如果像这样给未声明的变量赋值,则会导致抛出 ReferenceError。)
function test() { 
 message = "hi"; // 全局变量
} 
test(); 
console.log(message); // "hi" 

如果需要定义多个变量,可以用一个var多个逗号完成。

var message = "hi", 
    found = false, 
    age = 29; 

2.var 声明提升(被声明变量会自动提升到函数作用域顶部)。

function foo() { 
 console.log(age); 
 var age = 26; 
} 
foo(); // undefined 注意不是26!!!它相当于下面形式
​
function foo() { 
 var age; 
 console.log(age); 
 age = 26; 
} 
foo(); // undefined 
​
//反复多次使用var声明同一个变量没有问题滴
function foo() { 
 var age = 16; 
 var age = 26; 
 var age = 36; 
 console.log(age); 
} 
foo(); // 36 

let声明

1.let 声明范围是块级作用域(块作用域是函数作用域的子集,因此适用于 var 的作用域限制同样也适用于 let)。

if (true) { 
 let age = 26; 
 console.log(age); // 26 
} 
console.log(age); // ReferenceError: age 没有定义

JavaScript 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,而这是因为同一个块中没有重复声明

var name = 'Nicholas'; 
console.log(name); // 'Nicholas' 
if (true) { 
 var name = 'Matt'; 
 console.log(name); // 'Matt' 
} 
let age = 30; 
console.log(age); // 30 
if (true) { 
 let age = 26; 
 console.log(age); // 26 
} 

对声明冗余报错不会因混用 let 和 var 而受影响。这两个关键字声明的并不是不同类型的变量, 它们只是指出变量在相关作用域如何存在

2.暂时性死区(也即不会变量提升)

当在获取和使用一个变量时,只有当出现声明和初始化变量的代码时,才可以获取和使用。

3.全局声明(即使在全局作用域声明也不会成为全局变量)

image-20220417145056630.png

4.条件声明(强烈建议不使用!)

5.let 的出现为 for 循环定义迭代变量渗透到循环体外(var i = 0; i < val;i++)提供了解决方式:

for (var i = 0; i < 5; ++i) { 
 // 循环逻辑 
} 
console.log(i); // 5 
//改成使用 let 之后,这个问题就消失了,因为迭代变量的作用域仅限于 for 循环块内部:
for (let i = 0; i < 5; ++i) { 
 // 循环逻辑
} 
console.log(i); // ReferenceError: i 没有定义

const声明

const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误

const 声明的限制只适用于它指向的变量的引用。换句话说,如果 const 变量引用的是一个对象, 那么修改这个对象内部的属性并不违反 const 的限制。

const person = {}; 
person.name = 'Matt'; // ok 

JavaScript 引擎会为 for 循环中的 let 声明分别创建独立的变量实例,虽然 const 变量跟 let 变量很相似,但是不能用 const 来声明迭代变量(因为迭代变量会自增):

image-20220328153307690.png

数据类型

  1. Undefined
  2. Null
  3. Boolean
  4. Number
  5. String
  6. Symbol
  7. Object

函数

1.箭头函数

箭头函数虽然语法简洁,但也有很多场合不适用。箭头函数不能使用 arguments、super 和 new.target,也不能用作构造函数。此外,箭头函数也没有 prototype 属性。

2.理解参数

arguments 参数

image-20220329225635342.png

image-20220329225717050.png

image-20220329225744103.png

箭头函数中的 arguments

如果函数是使用箭头语法定义的,那么传给函数的参数将不能使用 arguments 关键字访问,而只能通过定义的命名参数访问。

image-20220329230109592.png

image-20220329230053326.png

image-20220329231109870.png

3.没有重载

image-20220329231312456.png

function makeKing(name) { 
 name = (typeof name !== 'undefined') ? name : 'Henry'; 
 return `King ${name} VIII`; 
} 
console.log(makeKing()); // 'King Henry VIII' 
console.log(makeKing('Louis')); 

image-20220329231653502.png

默认参数值并不限于原始值或对象类型,也可以使用调用函数返回的值:

let romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI']; 
let ordinality = 0; 
function getNumerals() { 
 // 每次调用后递增
 return romanNumerals[ordinality++]; 
} 
function makeKing(name = 'Henry', numerals = getNumerals()) { 
 return `King ${name} ${numerals}`; 
} 
console.log(makeKing());  // 'King Henry I' 
console.log(makeKing('Louis', 'XVI')); // 'King Louis XVI' 
console.log(makeKing()); // 'King Henry II' 
console.log(makeKing()); // 'King Henry III' 

image-20220329233123985.png

4.函数声明提升

image-20220330112041732.png

参考书籍

JavaScript高级程序设计(第4版)