JavaScript(ES6-10)语法详解 —— ES6基础知识【作用域】

基础环境构建

初始化项目

  • 通过脚手架工具将babel/Webpack等的配置直接生成好
npx es10-cli create es2019
# 其中es10-cli是提供的脚手架
# create表示创建项目的命令
# es2019 - projectName是要创建项目的目录名称
  • 启动项目:进入es2019项目中,执行npm run start
    执行代码
  • 访问http://localhost:8080即可看到效果
    运行效果图

VSCode应用插件

插件 作用
Beautify 代码格式化
ESLint eslint检查

作用域

  • 先决条件在static文件夹中创建lession1.js文件,并在layout.ejs中引入。(没有直接定义在js文件夹中的原因是为了不通过webpack进行编译)

全局作用域

// lession1.js
// 作用域学习代码,直接创建js文件是为了查看不通过webpack打包的效果
console.log("JACK")
// 全局作用域: 在全局的任意地方都可以拿到变量的值
// 在函数外部定义的变量基本都是全局变量
var name = 'JACK' // 可以在console中使用window.name获取,或直接输出name获取 —— 此方式定义的是全局变量
age = 23 // 不通过var声明也具有全局作用域,但是严格来说此方式定义的内容不能称为全局变量 —— 此方式定义的是全局对象的属性
// 全局变量不可以被删除,但是全局属性可以被删除
// 验证方式 - 在浏览器的console中执行`delete name`无法删除该全局变量 / 在浏览器的console中执行`delete age`是可以成功删除的

// 在函数内部没有使用var定义的变量不具有函数内部作用域,而具有全局作用域
function test () {
    sex = 'man' // 在浏览器中直接访问sex可以获得man
}
test()
  • 总结:
    • 没有使用var定义的变量是作为window的属性存在,不属于全局变量,而是全局对象的属性。但是与使用var定义的变量都具有全局作用域
    • 在函数内部没有使用var声明的变量也视为全局对象的属性,具有全局作用域 (JS中存在变量作用域提升的概念)
    • 全局变量不可以被删除,但是全局属性可以被删除

函数作用域

  • 在函数内部定义的变量具有局部作用域(即函数作用域)
  • 实例代码
// 函数作用域
function test () {
  var a = 3
  return a + 4
}
console.log(test()) // 可以输出结果7
console.log(a) // 无法输出a,因为a是局部作用域
  • 总结:在ES6之前只存在全局作用域和局部作用域的概念,故即使在函数中定义if/else,并在if/else中定义属性值,该属性值依旧在外层的函数中共享。

块状作用域

  • 只要有花括号包裹就相当于一个块状区域,具有块状作用域
  • 实例代码
// 块状作用域
function test2 () {
  var a = 3
  if (a === 3) {
    var b = 4
    let c = 5
    console.log('abc')
  } else {
    console.log('cba')
  }
  // 在es6之前只有全局作用域和局部作用域,故使用var定义的变量其实就是局部作用域中的数据值,故可以访问
  console.log(b) // 可以输出b的值
  // 使用let或const定义块级作用域变量
  console.log(c) // 无法输出c的值
  return a + 4
}
console.log(test2())
  • 总结:使用let/const定义的变量具有块级作用域,使用var定义的变量只存在全局/局部作用域的概念

动态作用域

  • 通常我们使用的this对象就是具有动态作用域的,其作用域范围不固定
  • 实例代码
// 动态作用域
a = 3
function test () {
  console.log(this.a)
}
console.log(test()) // 输出3, this指向与window
test.bind({ a: 100 })() // 输出100, bind表示让函数动态绑定到一个对象上去,此时this的指向就是这个对象
// this是动态指向的

let 与 const

// let与const
{
  let a = 1;
  console.log(a); // 输出1
}
console.log(a) // 无法输出结果,因为let具有块状作用域

// 使用var定义的变量可以通过window来访问,使用let定义的变量无法通过window来访问
var b = 3;
let c = 4;
console.log(b, c); // 输出 3 4
console.log(window.b, window.c); // 输出 3 undefined

// var定义的变量可以重复定义,相当于覆盖之前定义的变量值 / let定义的变量不可以重复定义
var b = 4
let c = 5
console.log(b) // 输出4
console.log(c) // 无法输出结果, let定义的变量无法进行重复定义

// let定义的变量不会进行变量提升

// let的特性,const都具备,且const只能定义常量
const a = 2
a = 3 // 报错,因为const的常量不能被修改
console.log(a)

// const不能在定义时不赋值,但是let和var都可以
const b
b = 3 // 报错
console.log(b)
  • 总结
    • 使用var定义的变量可以通过window来访问,使用let定义的变量无法通过window来访问
    • var定义的变量可以重复定义,相当于覆盖之前定义的变量值 / let定义的变量不可以重复定义
    • let定义的变量不会进行变量提升
    • let的特性,const都具备,且const只能定义常量
    • const不能在定义时不赋值,但是let和var都可以

常考面试题

// 课后练习
// 面试题1: 请说出console输出的结果
console.log(a);
let a = 1; // 报错 Cannot access 'a' before initialization
var a = 1; // 报错 a is not defined
a = 1; // 输出 undefined

// 面试题2: 请说出console输出的结果
let array = [1, 2, 3];
for (let i = 0; i < array.length; i++) {
  setTimeout(() => {
    console.log(array[i]);
  }, 1000);
}
// 输出结果 1 2 3

猜你喜欢

转载自blog.csdn.net/qq_34829447/article/details/107599825