课程介绍
本课程主要面向刚刚入门的前端同学,主要讲述了JS的整体发展及一些比较重要的知识。其中通过一些简单的代码讲述了变量提升、JS的数据是怎么存储的、基础数据类型和复杂数据类型的区别等一些基础知识,也讲解了JS的执行、闭包、垃圾回收等一些稍微进阶一些的知识。
课程重点
- JS的基本概念
- JS的数据类型
- 变量提升
- 作用域
- 闭包
- 垃圾回收
变量提升
变量提升是 JavaScript 中的一种特性,指在代码执行之前,所有函数和变量的声明会被 JavaScript 解释器提升到它们所在作用域的最顶部。这意味着即使声明在后面,也可以在之前使用这些函数或变量。
变量提升(Hoisting)被认为是,Javascript 中执行上下文(特别是创建和执行阶段)工作方式的一种认识。在 ECMAScript® 2015 Language Specification 之前的 JavaScript 文档中找不到变量提升(Hoisting)这个词。不过,需要注意的是,开始时,这个概念可能比较难理解,甚至恼人。
例如,从概念的字面意义上说,“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。
下面是一个基本的示例:
console.log(message); // 输出 undefined
var message = "Hello World!";
在上面的代码中,在变量 message 的声明之前,我们尝试输出它的值。由于变量提升的原因,JavaScript 解释器会将 var message 的声明移动到作用域的顶部。所以该代码等价于:
var message;
console.log(message); // 输出 undefined
message = "Hello World!";
在第1行中,message 变量被声明为 undefined,因此在尝试输出之后,它的值为 undefined。只有在第2行中,message 变量的值才被设置为 "Hello World!"。
需要注意的是,只有函数和变量的声明会被提升,而不是它们的初始化或赋值。例如:
console.log(bar); // 输出 undefined
var bar = 10;
console.log(foo()); // 输出 "Hello World!"
function foo() {
return "Hello World!";
}
在上面的代码中,变量 bar 被声明为 undefined 并输出了它的值,但是函数 foo() 在它的声明之前被调用并成功输出了 "Hello World!"。
作用域
作用域是指变量、函数和对象的可访问范围,也就是在代码中访问这些标识符的权限或范围。通常,作用域由代码中声明这些标识符的位置决定。在 JavaScript 中,标识符可以是变量、函数和对象等,并且有三种主要类型的作用域:全局作用域、局部作用域和块级作用域。
全局作用域是指变量、函数和对象在整个程序中都可访问的作用域。例如,定义在最外层的变量和函数都属于全局作用域,在程序的任何地方都可以被访问。
局部作用域是指在一个函数内部声明的变量和函数只能在该函数内部访问。这种作用域有助于避免命名冲突和提高代码的封装性和安全性。
块级作用域是一种相对较新的概念,在较早的 JavaScript 版本中并不存在。在块级作用域中,变量和函数只在它们所在的代码块内部可访问。块级作用域通常使用大括号 {} 来定义,例如 if 语句和 for 循环中的语句块。
全局作用域
全局作用域是指代码中未包含在任何函数中的变量或函数,它们被定义在最外层的作用域中。这意味着全局作用域的变量和函数可以被代码中的任何其他函数使用。例如:
var message = "Hello World!"; // 全局作用域
function showMessage() {
console.log(message); // 输出 "Hello World!"
}
showMessage();
在上面的代码中,message 变量被定义在全局作用域中,并且可以在任何函数中使用。showMessage() 函数可以访问 message 变量,并输出它的值。
局部作用域
局部作用域是指变量或函数被定义在函数内部。这意味着只能从函数内部访问这些变量或函数。例如:
function showMessage() {
var message = "Hello World!"; // 局部作用域
console.log(message); // 输出 "Hello World!"
}
showMessage();
console.log(message); // 报错,message is not defined
在上面的代码中,message 变量被定义为 showMessage() 函数的局部变量。因此,只能从 showMessage() 函数内部访问它。在函数的外部,尝试访问 message 变量将导致引用错误。
块级作用域
块级作用域是指使用大括号 {} 所包含的代码块中的变量或函数,这些变量或函数只能在该代码块内部访问。例如:
if (true) {
var message = "Hello World!"; // 块级作用域,但是 var 关键字会将变量提升到全局作用域
let greeting = "Welcome!"; // 块级作用域
}
console.log(message); // 输出 "Hello World!"
console.log(greeting); // 报错,greeting is not defined
在上面的代码中,message 变量被定义在 if 语句块中,虽然它使用了 var 关键字,但是由于 JavaScript 中没有块级作用域,所以 message 变量被提升到了全局作用域中,可以在代码块外部访问。而 greeting 变量则使用了 let 关键字,它会被限制在 if 语句块内部,并且在代码块外部无法访问,也就是说,它遵循了块级作用域的规则。
需要注意的是,在现代的 JavaScript 中,我们可以使用 let 和 const 来声明块级作用域的变量和常量。使用这两个关键字可以避免变量提升的问题,并且有效地将变量和函数限制在它们所在的代码块中,从而避免意外的错误和不必要的冲突。
文章仅为个人学习笔记,如有错误,欢迎指正。下期见🔥