const 定义的变量可以被修改吗?

var、let、const相关问题

  • 1,var
  • 2,let
  • 3,const
  • 4,块级作用域
  • 5,三者区别
  • 6,const 定义的变量可以修改吗?
  • 7,经典面试题

1,var

1, 声明提升
console.log(num) // undefined
var num = 100

2, 变量覆盖
var num1 = 100
var num1 = 200
conosle.log(num1) // 200

3, 没有块级作用域
function fn() {
  for (var i = 0; i <= 5; i++) {
    console.log(i)  // 0 1 2 3 4 5
  }
  console.log(i)  // 6
}
fn()

2,let

1, let 声明的变量具有块级作用域的特征
function fn() {
  let a = 10
}
console.log(a) // a is not defined

2, 在同一个块级作用域,不能重复声明变量
function fn() {
  let a = 10
  let a = 20
}
console.log(a) // Identifier 'a' has already been declared

3, let 声明的变量不存在变量提升,换种说法就是let声明存在暂时性死区(TDZ)
console.log(num) // Cannot access 'num' before initialization
let num = 10

3,const

1, const 声明的变量具有块级作用域的特征
function fn() {
  const a = 10
}
console.log(a) // a is not defined

2, 在同一个块级作用域,不能重复声明变量
function fn() {
  const a = 10
  const a = 20
}
console.log(a) //  Identifier 'a' has already been declared

3, const 声明的变量不存在变量提升,换种说法就是const声明存在暂时性死区(TDZ)
console.log(num) // Cannot access 'num' before initialization
const num = 10

4, const 声明一旦定义后,不能修改
const num = 100
num = 200
console.log(num) // Assignment to constant variable.

4,块级作用域

ES5中作用域有:全局作用域、函数作用域,没有块级作用域的概念。

ES6新增了块级作用域,由 {} 包括,if 语句for 语句里面的 {} 都属于块作用域

{
  var num = 100
  console.log(num) // 100
}
console.log(num) // 100 可见,通过var定义的变量可以跨块作用域访问到

function fn() {
  var num = 100
  console.log(num) // 100
}
console.log(num) // num is not defined 可见,通过var定义的变量不能跨函数作用域访问到

if (true) {
  var num = 100
}
console.log(num) // 100

for (var i = 0; i <= 5; i++) {
  var num = 100
}
console.log(i) // 6
console.log(num) // 100
if 语句和 for 语句中用 var 定义的变量可以在外面访问到,可见,if 语句和 for 语句属于块级作用域,不属于函数作用域

5,三者区别

  • var 定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问
  • let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问
  • const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,且不能修改
// 块级作用域
{
  var a = 100
  var b = 200
  var c = 300
  var a1
  let b1
  // const c1
  console.log(a) // 100
  console.log(b) // 200
  console.log(c) // 300
  console.log(a1) // undefined
  console.log(b1) // undefined
}
console.log(a) // 100
console.log(b) // 200
console.log(c) // 300

// 函数作用域
(function fn() {
  var a = 100
  let b = 200
  const c = 300
  console.log(a) // 100
  console.log(b) // 200
  console.log(c) // 300
})()
console.log(a) // a is not defined
console.log(b) // b is not defined
console.log(c) // c is not defined

6,const 定义的变量可以修改吗?

const 定义的基本类型不能改变,但是定义的对象是可以通过修改对象属性等方法改变的

const num = 100
num = 200
console.log(num) // Assignment to constant variable.

const person = {
  name: 'Tom',
  age: 18
}
person = {
  name: 'Jerry',
  age: 20
}
console.log(person) // Assignment to constant variable.

const person = {
  name: 'Tom',
  age: 18
}
person.name = 'Jerry'
console.log(person) // {name: 'Jerry', age: 18}

基本数据类型的变量保存在栈区中,基本数据类型的值直接在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响其他的变量。

引用数据类型的值是同时保存在栈内存和堆内存的对象,栈区保存了对象在堆区的地址。

const 声明的 person 给属性重新赋值是可以的,但是给 person 重新赋值是不可以的,那样会改变 person 在栈区的地址

7,经典面试题

for (var i = 0; i <= 5; i++) {
  setTimeout(function() {
    console.log(i)
  }, 1000)
}
console.log(i)

setTimeout 是异步执行的,1000ms后向任务队列里添加一个任务,只有主线程的全部执行完才会执行任务队列里的任务,所以当主线程 for 循环执行完之后 i 的值为 6, 这时候再去执行任务队列里执行任务, i 全部是 6。

每次 for 循环的时候 setTimeout 都会执行,但是里面的 function 则不会执行被放入任务队列,因此放了 6 次, for 循环的 6 次执行完之后不到 1000ms, 100ms后全部执行任务队列里的函数,所以输出 6 个 6。

for (let i = 0; i <= 5; i++) {
  setTimeout(function() {
    console.log(i)
  }, 1000)
}
console.log(i)

const 定义的变量可以被修改吗?_第1张图片

let定义的 i 事块级作用域,每个 i 只能存活到大括号结束,并不会把后面的 for 循环的 i 值赋给前面的 setTimeout 中的 i,而var 定义的 i是局部变量,这个 i 的生命周期不受for 循环的大括号限制。

你可能感兴趣的:(javaScript,javascript,前端,typescript)