ES6和ES3(常规js)语法区别:
1、var和let、const命令
- 作用域:ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
- 变量提升:var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错
// var 的情况 console.log(foo); // 输出undefined var foo = 2; // let 的情况 console.log(bar); // 报错ReferenceError let bar = 2;
2、块级作用域 : es5只有全局作用域和函数作用域,并没有块级作用域
ES6:
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
3、块级作用域和函数声明 :es5规定,函数只能在顶层作用域和函数作用域内声明,不能在块级作用域声明
// 情况一 es5非法 es6合法
if (true) {
function f() {}
}
// 情况二 es5非法 es6合法
try {
function f() {}
} catch(e) {
// ...
}
4、const命令 :const声明一个只读的常量,常量的值不能改变,并且只声明不赋值也会报错,其他的属性跟let类似
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
const foo;
// SyntaxError: Missing initializer in const declaration
5、ES6声明变量有6种方法
ES5 只有两种声明变量的方法:var
命令和function
命令。ES6 除了添加let
和const
命令,另外两种声明变量的方法:import
命令和class
命令。所以,ES6 一共有 6 种声明变量的方法
6、globalThis 对象
JavaScript 语言存在一个顶层对象,它提供全局环境(即全局作用域),所有代码都是在这个环境中运行。但是,顶层对象在各种实现里面是不统一的。
- 浏览器里面,顶层对象是
window
,但 Node 和 Web Worker 没有window
。 - 浏览器和 Web Worker 里面,
self
也指向顶层对象,但是 Node 没有self
。 - Node 里面,顶层对象是
global
,但其他环境都不支持。
同一段代码为了能够在各种环境,都能取到顶层对象,现在一般是使用this
变量,但是有局限性。
- 全局环境中,
this
会返回顶层对象。但是,Node 模块和 ES6 模块中,this
返回的是当前模块。 - 函数里面的
this
,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this
会指向顶层对象。但是,严格模式下,这时this
会返回undefined
。 - 不管是严格模式,还是普通模式,
new Function('return this')()
,总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么eval
、new Function
这些方法都可能无法使用。
综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。
// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
// 方法二
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};