‘红宝书’第四版,延续了上一版的框架和格局,在此基础上又翔实地增补了ES2015-ES2019的全新内容。
有人说JavaScript并不是一门真正有内聚力的编程语言,至少形式上不是。ECMA-262规范定义了JavaScript,但是JavaScript没有唯一正确的实现,更重要的是这门语言与其宿主关系密切,实际上宿主为js定义了与外界交互所需要的全部API:DOM,网络请求,硬件系统,存储,事件,文件,加密,还有数以百计的其他API各种浏览器及其JavaScript引擎都是按照自己的理解实现了这些规范。
咱们先来看看 **_基础知识 _**的相关内容:
一、变量
有三个关键字可以声明变量:var 、let 、 const,其中var可以在ECMAScript的所有版本中使用,而let 、 const只适用于ECMAScript6及更晚的版本中使用。
1.var 关键字
要定义变量,可以使用var操作符,后跟变量名;
例如
var message;
定义了一个名为name的变量,可以用它保存任何类型的值,未初始化的时候,变量会保存一个特殊的值undefined;
未初始化的情况比如:
let message;
console.log(message==undefined); //true
等同于
let message=undefined;
console.log(message==undefined); //true
** 因此默认情况下,任何未初始化的变量都会取得undefined值。**
var声明作用域
function eg(){
name="kkb"; //全局变量
}
eg();
console.log(name); //'kkb'
此时name是个全局变量,只要调用一次函数eg(),就会定义这个变量,并且可以在函数外部访问到。
var 声明提升
function eg(){
console.log(name);
var name='kkb';
}
eg();//undefined;
之所以没有报错是因为,ECMAScript运行的时候把他看成了等价的代码如下
function eg(){
var name;
console.log(name);
name='kkb';
}
eg();//undefined;
2. let 关键字
let声明的范围是块作用域,var声明的范围是函数作用域;
if(true){
var name='kkb';
console.log(name);//kkb
}
console.log(name);//kkb
if(true){
let name='kkb';
console.log(name);//kkb
}
console.log(name);//ReferenceEror:name 没有定义
let不允许重复声明;
let暂时性死区,不会在作用域中被提升;
console.log(name);//undefined
var name='kkb';
console.log(name);//ReferenceEror:name 没有定义
let name='kkb';
3.const 关键字
const的行为与let基本相同,唯一重要区别是他声明变量时必须同时初始化变量而且不能修改
const name='kkb';
name='sss';//TypeError:给常量赋值;
不允许重复声明
const name='kkb';
const name='sss';//SyntaxError;
声明的作用域也是块
const name='kkb';
if(true){
const name='sss';
}
console.log(name);//kkb;
另外还有一点区别:
大家一般认为const是常量,不能被更改。但是请看下面这段代码:
const obj = {
age: 18
}
obj.age = 10;
我们更改了obj这个const的age个属性,但是没有任何报错。不是说const定义的变量不能被更改么?其实是const定义的变量的引用不能被更改,在上面的程序中,如果你说obj = ‘name’,程序是会报错的。但是上面例子中,const只是保证对象的指针不改变,而对象的内容改变不会影响到指针的改变,所以对象的属性内容是可以修改的。所以,建议只使用const定义简单类型的数据,定义对象还是使用let会不容易产生歧义。