1.变量提升
代码执行之前需要进行一次解析,如果在变量使用var声明之前就使用它,不会报错,变量的值为undefined,即将变量使用var声明这一步提升到代码最前面执行,这就叫做变量提升。
console.log(web)//输出undefined
var web = "weizhuren"
虽然在条件语句中msg没有被var声明成为变量,但是在代码执行前已经对msg进行了解析,所以就算在执行方法时没有声明变量msg,依然可以在控制台输出msg,值为undefined。
function func() {
//想到于变量提升到这里声明 var msg
if(false){
var msg = "weizhuren"
}
console.log(msg)//输出 undefined
}
func()
使用let和const就不会出现变量提升的问题,因为在声明时会产生一个暂时性死区(tdc)。
不建议再使用var,建议使用let定义变量,const定义常量。
console.log(msg1)//ReferenceError
console.log(msg2)//ReferenceError
let msg1 = "weizhuren"
const msg2 = "erbihouke"
ps:如果不声明变量就使用是会报错的。
2.变量的作用域范围
变量的作用域范围。
let msg = "weizhueren"
function show() {
let msg = "魏主任"
function run() {
let msg = "run .. weizhuren"
console.log(msg)//输出 run .. weizhuren
}
run()
console.log(msg)//输出 魏主任
}
show()
console.log(msg)//输出 weizhueren
3.全局污染
如果不声明变量的话,就有可能产生全局污染。
// "use strict"
//严格模式,如果不进行声明,就会进行报错
function show() {
msg = "weizhuren"
}
show()
console.log(msg)//输出 weizhuren
4.块作用域
使用var声明的变量没有块作用域,但是使用let声明的变量存在块作用域。
使用var声明变量时。
var i = 99
for(var i = 0;i < 5;i++){
console.log(i)// 0 1 2 3 4
}
console.log(i)//输出 5
使用let声明变量时。
let i = 99
for(let i = 0;i < 5;i++){
console.log(i)//0 1 2 3 4
}
console.log(i)//99
5.const常量的声明
使用const声明过的常量的值在同一个作用域中不可以更改。
const MSG = "weizhuren"
MSG = "魏主任"//报错
但是在不同的作用域中可以修改,其本质是这不两个不同的常量。
const MSG = "weizhuren"
function show() {
const MSG = "魏主任"
console.log(MSG)//输出 魏主任
}
show()
const不允许修改基本数据类型的值,但是允许修改引用数据类型的值。
const MSG = {}
MSG.name = "weizhuren"
console.log(MSG.name)//输出 weizhuren
6.window全局对象污染与重复声明
使用var声明的变量会进入全局成为window的属性;但是使用let则不会出现这个问题。
使用var声明。
var msg = 'weizhuren'
console.log(window.msg)//输出 weizhuren
使用let声明。
let msg = 'weizhuren'
console.log(window.msg)//输出 undefined
使用var可以重复声明一个变量,但是使用let不可以。
使用var声明。
var msg = 'weizhuren'
console.log(msg)//输出 weizhuren
var msg = "魏主任"
console.log(msg)//输出 魏主任
使用let声明。
let msg = 'weizhuren'
console.log(msg)
let msg = "魏主任"//报错 msg已经被声明了
console.log(msg)
7.Object.freeze()冻结变量
使用Object.freeze()后,可以冻结变量,阻止变量的值被修改。
如果使用严格模式,则会报错。
"use strict"
const INFO = {
name:"weizhuren",
department:"erbihouke"
}
Object.freeze(INFO)
INFO.name="魏主任"//严格模式下这条语句会报错
console.log(INFO.name)//输出 weizhuren
8.传值与传址
值对象(基本数据类型)是传值的,对象和数组(引用数据类型)是传址的。
let a = 1;
let b = a;
b = 3
console.log(a,b)//1 3
let d = {}
let e = d
e.f = 1
console.log(d.f,e.f)//1 1
9.null和undefined
基本数据类型在声明且没有赋值时为undefined;引用数据类型在声明且没赋值时为null。
在函数中如果参数值为空则为undefined;如果函数没有返回值,则也为undefined。
function show(name) {
console.log(name)//undefined
}
console.log(show())//undefined
10.“use strict”严格模式
严格模式限制一些模棱两可的代码写法。比如变量不需要声明就可以使用,可以使用关键字作为变量的值等等,这些写法在严格模式下都是不允许的。
"use strict"//使用严格模式
msg = "weizhuren"
console.log(msg)//报错 msg is not defined
本文深入探讨JavaScript中的变量提升、作用域、全局污染、块作用域、const声明、window全局对象污染、Object.freeze()、传值与传址、null与undefined及严格模式等关键概念。
902

被折叠的 条评论
为什么被折叠?



