前言
Javascript属于是一种弱类型动态语言且在执行代码前是需要先编译的,且变量的查找会先从内到外的作用域中查找,不能从外到内查找。
什么叫弱类型动态语言呢?
当强类型动态语言声明一个变量时 var a:number=1,需要加上类型名(number),此时当你重新定义a='hello'时,此行代码无法运行,'hello'是字符串类型,而你定义的确实number类型,而弱类型动态语言声明一个变量时只需 var a=1,不需要加类型,并且当你修改a值时(a='hello'),可以成功修改的。
var a =1
a='hello'
console.log(a);
作用域
一、全局作用域
在 JavaScript 中,位于函数之外的变量被称为全局变量,它们拥有全局作用域。这意味着全局变量可以在代码的任何地方被访问,包括函数内部和外部。
var a = 1;//全局变量
var b = 2;//全局变量
function foo() {
console.log(a, b);
}
foo();
二、局部作用域
局部作用域是指在函数内部声明的变量,它们只能在函数内部访问,称为局部变量。
function foo() {
var a = 2;//局部变量
console.log(a);
}
foo();
三、块级作用域
块级变量声明周期 : 从大括号开始 -> 到大括号结束。
var a = 1;//全局变量
let b = 2;//块级变量(块级作用域 :只在大括号内部起作用)
console.log(a,b);//1,2
};
console.log(a);//1
// console.log(b);// b is not defined
到这儿,各位小伙伴可能就不能理解了,为什么a和b都是在if语句中定义,但a是全局变量而b却是块级变量呢,这就引出了我们今天的另外一个知识点:var有声明提升的作用,将a=1提升到作用域的顶端,成为全局变量,而函数的声明则会整体提升,但let却没有声明提升这个功能,这在后续的讲解中将为大家介绍到let、const与var声明的区别!
什么是声明提升呢?
例如下面这段代码,当我们用正常思维逻辑来解释时,这段代码是不能让人理解的,正是声明提升以及执行前先编译这两个特点的存在,使得这段代码是可以运行的,但是得出来的结果是undefined,这并不意味着是错误,而是因为在执行console.log语句前,a并没有赋到值。
console.log(a);
var a=1;
var a
console.log(a);
a =1
let及const与var声明的区别
(一)let及const不能声明提升
还是拿上一段var定义的代码来说,将var替换成let以及const,分别调试看结果。
console.log(a);
let a =1
console.log(a);
const a =1
(二)let及const的特点
let除了不能声明提升外,还不能同时定义两个相同的量,系统会出现报错,但用let声明一个变量,其可以修改值,下列代码中,将a的值修改为了hello。
let a=1
a='hello'
console.log(a);
const同样不能声明提升且不能同时定义两个相同的量,但是const也不可以修改变量值,下列代码在运行中会出现报错。
const a=1
a='hello'
console.log(a);
欺骗词法作用域
(一)eval()将原本不属于这行的代码放置这行
观察下列代码:
var b = 2; // 被覆盖
function foo(str, a) {
eval(str); // 欺骗
console.log(a, b);//输出: 1, 3
}
foo("var b = 3;", 1);
(二)with()当修改对象中不存在的属性时,该属性会泄露到全局成为全局变量
观察下列代码:
function foo(obj){
with(obj){
a=2
}
}
var o1={
a:3
}
foo(o1)
console.log(o1);
function foo(obj){
with(obj){
a=2
}
}
var o1={
a:3
}
var o2={
b:4
}
foo(o2)
console.log(a);