JavaScript高级程序设计学习 ① 完整的JavaScript包含什么?var、let、const的使用与异同?for循环中为什么最好使用let?Undefined、Null、NaN分别是什么?

一、完整的JavaScript包含什么?他们的含义又是什么?

1.1 完整的JavaSctript包含三个部分

核心ECMAScript、文档对象模型DOM、浏览器对象模型BOM

1.2 JavaScript 三个部分的含义

1.2.1 ECMAScript

ECMA-262定义了一门语言的语法、类型、语句、关键字、保留字、操作符、全局对象;ECMA-262迭代了很多版本,比如ECMA-262的第六版就是俗称的ES6。

ECMAScript是ECMA-262所定义的语言,是对实现这个规范描述所有方面的一门语言的称呼。

JavaScript实现了ECMAScript。

1.2.2 DOM 文档对象模型

文档对象模型(DOM)是一个应用编程接口,用于在HTML中使用拓展的XML。

DOM将整个页面抽象为一组分层节点。

<html>
	<head> 
		<title>Page Title</title>
	</head>
	<body>
		<p>Hello World</p>
	</body>
</html>

代码通过DOM可以表示成一组分层节点。

1.2.3 BOM 浏览器对象模型

浏览器对象模型(BOM),用于支持访问和操作浏览器的窗口。使用BOM,开发者可以操控浏览器显示页面之外的部分。BOM的核心是Window对象,表示浏览器的实例。

二、var、let、const的使用与异同?

2.1 var、let、const异同点总览

可声明变量 作用域 变量提升 冗余声明 需要初始化变量 不可修改
var 所有类型 函数作用域 × ×
let 所有类型 块作用域 × × × ×
const 所有类型 块作用域 × ×

2.2 var、let、const异同点详情和使用

2.2.1 作用域

var的作用域为函数作用域,即是一旦在函数中声明,整个函数中都可使用。

let 和 const 的作用域为块作用域,即在{}中定义let,则在{}外则无法访问。

下面给出var、let和const作用域的示例, 对于var声明的变量,可以看到即使是在块内声明,整个函数都可以访问到,当然他的作用域也仅仅局限于当前函数test()之中。

function test() {
    if (true) {
        var a = "HelloWorld"
        console.log("块内声明:" + a)
    }
    console.log("块外:" + a)
}
test()
console.log("函数作用域外:" + a)

 而对于let和const声明的变量而言,只能在当前块中访问,当前函数作用域以及函数作用域外都不能访问到。

function test() {
    if (true) {
      //const a = "HelloWorld"
        let a = "HelloWorld"
        console.log("块内声明:" + a)
    }
    console.log("块外:" + a)
}
test()
console.log("函数作用域外:" + a)

 

2.2.2 变量提升

var存在变量提升,即是使用var会自动将var所定义的变量,自动提升到函数作用域顶部。

let、const则不存在变量提升。

下面给出var、let和const变量提升的示例。var 变量提升指的是,使用这个关键字声明的变量会自动提升到函数作用域顶部,不会报错,而是会显示undefined未赋值。

console.log(a)
var a = "HelloWorld"
console.log(a)

 即是上面的代码行等价于如下代码:

var a
console.log(a)
var a = "HelloWorld"

而let和const不存在变量提升,如果在使用这个变量前没有定义,会直接报错。

console.log(a)
let a = "HelloWorld"
// const a = "HelloWorld"

 2.2.3 冗余声明

var可以冗余声明,let、const则不允许出现冗余声明。

冗余声明指的是反复声明同一个变量多次,var允许冗余声明。

var a = "1"
var a = "2"
var a = "3"
console.log(a)

 

 let和const则不允许冗余声明,会直接报错。

let a = "1"
let a = "2"
//const a = "1"
//const a = "2"
console.log(a)

 

 2.2.4 初始化变量和修改

 const声明变量的同时必须初始化变量,且不能修改const的值。

const a 

 

const a = 1;
	  a += 2;

 

三、 for循环中为什么最好使用let而不是const、var

3.1 var存在变量渗透、以及在使用定时器时会出现诡异的错误

3.1.1 变量渗透

所谓变量渗透即是因为var的作用域为整个函数作用域,通过var定义的i,会在整个函数中有定义。而不是仅仅在这个循环体中有定义。

for (var i = 0; i < 3; i++) {

}
console.log(i);

 

3.1.2 定时器“错误”

同时如果在循环中加入定时器,需要对i的值进行操作,那么只能得到导致循环结束的i的值

for (var i = 0; i < 3; i++) {
    setTimeout(() => { console.log(i) }, 0)
}

3.2 const从定义上就不允许修改,用于当作循环计数的i时会直接报错

for (const i = 0; i < 3; i++) {
}

 

 3.3 使用let可以完美规避掉上面这三个问题,因此for循环中最好使用let。

使用let定义for循环时的i,则定时器中函数引用的变量为JavaScript引擎为每次迭代声明的新变量,而不是直接打印最后结束时候的i值,此时也不会发生变量渗透的问题,i不会作用于函数外。

for (let i = 0; i < 3; i++) {
    setTimeout(() => { console.log(i) }, 0)
}
console.log(i)

 

四、Undefined、Null、NaN分别是什么?

4.1 Undefined

当使用var或let声明了变量但没有初始化时,就相当于给变量赋予了undefined值。

let a
var b
console.log(a)
console.log(b)

 

4.2 Null

null值表示一个空对象指针,null用typeof会传回object

console.log(typeof(null))

 

undefined由null派生而来,ECMA-262将他们定义为表面上相等,即是null==undefined会返回true,当然并不是全等于。

console.log(undefined == null)
console.log(undefined === null)

 

4.3 NaN

NaN(Not a Number)为一个特殊的数值,用于表示本来要返回数值的操作失败了。0,+0或-0相除会返回NaN

比如0/0 会返回NaN,而3/0会返回Infinity

console.log(0/0)
console.log(3/0)

 

NaN在进行大小比较的时候也会出现很诡异的情况

console.log(NaN > 3);
console.log(NaN <= 3);
console.log(NaN == NaN);
console.log(NaN === NaN);
console.log(NaN != NaN);

NaN 既不大于3也不等于3,也不等于自己,更不全等于自己。  

 

五、关系操作符,为什么会出现3 > 23 ?

这四行代码执行后,会有一行返回false,即是出现奇怪的 “23 < 3”

console.log("23" > "3");
console.log(23 > "3");
console.log("23" > 3);
console.log(23 > 3);

“23”和“3”都是字符串的时候,会逐步比较他们的字符编码,“2”的编码50小于“3”的编码51,即会返回false。

其他情况当包含有数值时,字符串便会被转化为数值再进行比较。

猜你喜欢

转载自blog.csdn.net/zujiasheng/article/details/126858300
今日推荐