此篇再延续上篇,详细纪录一下三种宣告方式的不同。
在ES6之前只有var的宣告方式;在ES6之後,即新增了let & const两种方式:
var
- 宣告一个可随意更改内容的变数 - 函式作用域 (function-level scope)
⇒ 只有在「函式」里可以看得到,特性相当於全域变数
不会受限在区域(block scope)内,可能会污染全域变数。不管哪个作用域(Scope)都可以存取,可以重复宣告。(区域变数会覆盖全域变数)
范例如下:
var a = 5;
if (true) {
var a = 10; //区域变数覆盖全域变数!!
console.log(a); //结果为10
}
console.log(a); //结果为10
再看以下范例,若在一个 函式
内使用 var 宣告变数时,那这个变数就变成了一个区域变数,只有在函式内才看得到。
var a = 5
function MyFunction() {
if (true) {
var a = 10;
}
console.log(a); // 结果为10
}
MyFunction();
console.log(a); // 结果为5
let
- 宣告一个可随意更改内容的区域变数-区块作用域 (block-level scope)
⇒ 只有在「区块」里面才看得到,即只有在 {}花括号
里的才是它的作用域范围。
所宣告的变项只有在区域内(block scope)有效,不会产生全域变数,也就是 { } 包住的区域,一但离开 { } 范围,这个变数就不会被存取到,也无法在同一层 Block 重复宣告变数。
var b = 6;
if (true) {
let b = 20;
console.log(b); //出现20
}
console.log(b); //出现6 即为{}外的变数=6
无法在同一层 Block 重复宣告变数:
let a = 6;
let a = 20;
console.log(a);
//出现错误:Identifier 'a' has already been declared**
但是如果 let
宣告的变数在 不同层的Block ,就不会报错:
let a = 6;
if (true) {
let a = 20;
console.log(a); //出现20
}
console.log(a); //出现6
const
- 宣告一个只可读取的不可变常数-区块作用域 (block-level scope)
⇒ 只有在「区块」里面才看得到,即只有在 {}花括号
里的才是它的作用域范围。
宣告後不能更改值,否则会报错
const a = 123;
a = 456; // TypeError: Assignment to constant variable.
一宣告时就必定要指定给值,否则会报错
const b ;
b = 456; //SyntaxError: Missing initializer in const declaration
只要无宣告变数直接赋值就会被视为 全域变数
(写在全域环境的 var、let、const 变数同样可以视为全域变数)
另一点差异是 能不能透过 delet 操作删除变数
,先来看下面程序码:
//未宣告
a = 6;
delete a; //true
console.log(a); //a is not defined
//宣告
var b = 10;
delete b; //false
console.log(b); //10;
从以上范例可以发现,有使用var宣告的b是不可被删除的,而未宣告的a可以被删除。
这是因为如果没有经过var宣告的变数「会被当作物件属性」的方式新增,因此才会强烈建议变数一定要宣告,否则可轻易被删除的变数是很容易出现出问题的。
我们可以透过Object.getOwnPropertyDescriptor
来获取全域属性: (可参考MDN)
//未宣告
a = 6;
Object.getOwnPropertyDescriptor(window, 'a')
//{value: 6, writable: true, enumerable: true, configurable: true}
//宣告
var b = 10;
Object.getOwnPropertyDescriptor(window, 'b')
//{value: 10, writable: true, enumerable: true, configurable: false}
由上方a, b 变数的属性可发现,两者的配置性configurable有所不同。而configurable为false的代表此物件属性无法被删除,configurable为true的则反之。
因此,经过var宣告的变数是不能被delete的。
参考来源:
https://hsiangfeng.github.io/javascript/20200425/539985371/
https://ithelp.ithome.com.tw/articles/10191549
https://tw.alphacamp.co/blog/javascript-var-let-const
前言 接下来多篇的元件介绍会以官方文件 Components In-Depth 章节为主: 未知pa...
-802.1X 角色 .请求者不直接向 RADIUS 服务器进行身份验证。它向身份验证者进行身份验...
在资料库当中的资料也一定某种型态的资料,SQL中要开一个新栏位也需要定义资料型态,所以下面帮大家整理...
哈罗大家好~ 不知不觉,这个系列就要来到尾声了,这30天,我们分享了 Microsoft 365 帮...
前言 除了开发新功能,开会占据了我们许多时间,如果能够节省时间出来,我们才能去学些新技术、重构、甚至...