JavaScript逐点突破第4篇之语言基础,外加3道题目练习

implements package public

interface protected static

let private

模块代码中保留

await

[](()声明变量并赋值


在 JavaScript 中,有 3 个关键字可以声明变量: varconstlet。其中,varECMAScript的所有版本中都可以使用,而 constlet 只能在ECMAScript 6(将在后面学到) 及更晚的版本中使用。

[](()var 关键字

要定义变量,可以使用 var关键字,后跟变量名:

var xhsRookies

这行代码定义了一个名为 xhsRookies的变量,可以用它保存任何类型的值。ECMAScript实现变量初始化,因此可以同时定义变量并设置它的值:

var xhsRookies = ‘hi’

xhsRookies被定义为一个保存字符串值hi的变量。像这样初始化变量不会将它标识为字符串类型,只是一个简单的赋值而已。随后,不仅可以改变保存的值,也可以改变值的类型:

var xhsRookies = ‘hi’

xhsRookies = 100 // 合法,但不推荐

在这个例子中,变量 xhsRookies首先被定义为一个保存字符串值hi的变量,然后又被重写为保存了数值 100 。虽然不推荐改变变量保存值的类型,但这在ECMAScript中是完全有效的。

1. var 声明作用域

使用 var操作符定义的变量会成为包含它的函数的局部变量。比如,使用 var在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁:

function xhsTest() {

var xhsRookies = ‘hi’ // 局部变量

}

xhsTest()

console.log(xhsRookies) // 出错!

这里,xhsRookies变量是在函数内部使用var 定义的。函数叫 xhsTest(),调用它会创建这个变量并给它赋值。调用之后变量随即被销毁,因此示例中的最后一行会导致错误。不过,在函数内定义变量时省略 var操作符,可以创建一个全局变量:

function xhsTest() {

xhsRookies = ‘hi’ // 全局变量

}

xhsTest()

console.log(xhsRookies) // “hi”

去掉之前的 var之后,xhsRookies 就变成了全局变量。只要调用一次函数 xhsTest(),就会定义这个变量,并且可以在函数外部访问到。

虽然可以通过省略 var 操作符定义全局变量,但不推荐这么做。在局部作用域中定义的全局变量很难维护,也会造成困惑。

如果需要定义多个变量,可以在一条语句中用逗号分隔每个变量(及可选的初始化):

var xhsRookies = ‘hi’,

xhsFound = false,

xhsNumber = 29

这里定义并初始化了 3 个变量。

2. var 声明提升

使用 var时,下面的代码不会报错。这是因为使用这个关键字声明的变量会自动提升到块作用域 5 顶部:

{

console.log(xhsNumber) // undefined

var xhsNumber = 26

}

之所以不会报错,是因为 ECMAScript 运行时把它看成等价于如下代码:

{

var xhsNumber

console.log(xhsNumber) // undefined

xhsNumber = 26

}

这就是所谓的“提升”(hoist),也就是把所有变量声明都拉到块作用域的顶部。

[](()let 声明

letvar的作用差不多,但有着非常重要的区别。最明显的区别是,let声明的范围是块作用域, 而var 声明的范围是函数作用域。

{

var xhsRookies = ‘xhs-rookies’

console.log(xhsRookies) // xhs-rookies

}

console.log(xhsRookies) // xhs-rookies

{

let xhsNumber = 26

console.log(xhsNumber) // 26

}

console.log(xhsNumber) // ReferenceError: xhsNumber 没有定义

在这里,xhsNumber变量之所以不能在块作用域外部被引用,是因为它的作用域仅限于该块内部。块作用域是函数作用域的子集,因此适用于 var的作用域限制同样也适用于let

let也不允许同一个块作用域中出现冗余声明。这样会导致报错:

var xhsRookies

var xhsRookies

let xhsNumber

let xhsNumber // SyntaxError;标识符xhsNumber已经声明过了

当然,JavaScript 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,而这是因为同一个块中没有重复声明:

var xhsRookies = ‘xhs-rookies’

console.log(xhsRookies) // ‘xhs-rookies’

{

var xhsRookies = ‘xhs-rookies-boy’

console.log(xhsRookies) // ‘xhs-rookies-boy’

}

let xhsNumber = 30

console.log(xhsNumber) // 30

{

let xhsNumber = 26

console.log(xhsNumber) // 26

}

对声明冗余报错不会因混用letvar而受影响。这两个关键字声明的并不是不同类型的变量, 它们只是指出变量在相关作用域如何存在。

var xhsRookies

let xhsRookies // SyntaxError

let xhsNumber

var xhsNumber // SyntaxError

1. 全局声明

var关键字不同,使用 let 在全局作用域中声明的变量不会成为window对象的属性(var声明的变量则会)。

var xhsRookies = ‘xhsRookies’

console.log(window.xhsRookies) // ‘xhsRookies’

let xhsNumber = 26

console.log(window.xhsNumber) // undefined

不过,let声明仍然是在全局作用域中发生的,相应变量会在页面的生命周期内存续。因此,为了 避免 SyntaxError,必须确保页面不会重复声明同一个变量。

2. let 作用域

在 let出现之前,代码块中定义的迭代变量会渗透到外部:

{

var xhs = 5

}

console.log(xhs) // 5

改成使用 let 之后,这个问题就消失了,因为 let 变量的作用域仅限于代码块内部:

{

let xhs = 0

}

console.log(xhs) // ReferenceError: xhs 没有定义

[](()const 声明

const的行为与let基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const声明的变量会导致运行时错误。

const xhsNumber = 26

xhsNumber = 36 // TypeError: 给常量赋值

// const 也不允许重复声明

const xhsRookies = ‘xhs-rookies’

const xhsRookies = ‘xhs-rookies-boy’ // SyntaxError

// const 声明的作用域也是块

const xhsRookies = ‘xhs-rookies’

console.log(xhsRookies) // xhs-rookies

[](()变量命名规则

  • 严格区分大小写(大写的变量和小写的变量是不同的变量);

  • 变量名可以由数字、字母(大小写都可以)、下划线、美元符($)组成,但是不能以数字开头;

  • 不能是 javascript 中的关键字和保留字,如:if,else,function 等;

  • 变量名需要有意义,即语义化,增强代码可读性,比如:存储年龄用 age,姓名用 name,可以防止过段时间就不理解代码是什么了,也可以防止合作时别人看不懂;

  • 使用驼峰命名法:从第二个单词开始,首字母大写,如用户个人数据(userPersonalData);

[](()题目自测


[](()一:下列代码输出结果是什么?

var xhsRookies = ‘hello’

function textFun() {

var xhsRookies = ‘hi’

}

console.log(xhsRookies)

A. hello

B. hi

C 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 . hi hello

D. hello hi

Answer:A

这道题考查的是 var 声明作用域,在第一行 xhsRookies变量在 textFun函数作用域外使用 var定义的,第三行xhsRookies变量是在textFun作用域内部使用 var 定义的。所以最后一行输出 xhsRookies其实是第一行定义的,结果是:hello

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值