众所周知 JavaScript如今已广泛应用在Web编程领域,但它的诞生却是在 10 天之内,虽然操刀设计的大神很牛,但也难免留下了不少的后遗症,同时在应用领域为保证兼容很多问题也没有得到很好的解决,此时就要求开发者在程序开发的过程中注意避免错误。首先让人迷惑的就是JavaScript标准规范的命名,为了让JavaScript成为全球标准,几个公司联合ECMA(European Computer Manufacturers Association)组织定制了JavaScript语言的标准,被称为ECMAScript标准。由于JavaScript是网景的注册商标所以标准就以ECMAScript(简称ES)保留下来。

变量作用域

JavaScript设计之初变量可以直接使用,不需要var声明,而且作用域都是全局的,也就是挂在window变量上的。这显然是不合适的,尤其是在多个js文件中声明了形同变量名的情况下。因此ECMA推出了strict模式,要求使用变量前需要var关键字声明,否则会提示错误。

如果var在函数内部声明,则变量的作用域在整体函数。同时JavaScript函数会扫描函数内所有语句将变量声明语句提到最前,称为变量提升

'use strict';
function foo() {
    var x = 'Hello, ' + y;
    console.log(x);
    var y = 'Bob';
}
foo();

虽然是strict模式,但上面的代码不会报错,console会输出Hello, undefined

ES6中引入了let关键字用于声明块级作用域,如在for循环中的变量:

'use strict';
function foo() {
    var sum = 0;
    for (let i=0; i<100; i++) {
        sum += i;
    }
    // SyntaxError:
    i += 1;
}

对象的key与Map结构

JavaScript中对象的key都是字符串类型,如果字符串满足变量命名条件(只包含字母 $, _, 数字,且不能数字打头)则可以直接写成key值,否则需要写成字符串形式如middle-school

var xiaohong = {
    name: '小红',
    'middle-school': 'No.1 Middle School'
};

JavaScript对象简单的可以简单的用于Map数据结构,但它的key只能是字符,这是个问题,所以ES6中引入了Map类型,Map类型的key可以是任意类型的对象元素。

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95

for...in 与 for...of

for...in 循环会取出对象中所有属性逐一遍历,包括对象继承来的属性。对Array对象除了会遍历列表的index(整型)外还会遍历对象的其他赋值属性

var a = ['A', 'B', 'C'];
a.field = 'Haha';
for (var i in a) {
    console.log(i); // '0', '1', '2', 'field'
    console.log(a[i]); // 'A', 'B', 'C', 'HaHa'
}

for...of 是ES6中引入的语法,解决了 for...in 循环会带上所有field的问题,for...of 用于iterable遍历。只循环数组,Map,或Set集合中的元素。forEach是ES5.1中引入的Array,Set,Map等数据结构的一个遍历方法:

var a = ['A', 'B', 'C'];
或 var s = new Set(['A', 'B', 'C']);
或 var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
a.forEach(function (element) {
    console.log(element);
});

undefined与null

undefined并不是JavaScript的关键字,而是一个全局变量,表示某个变量没有定义。而null表示某个变量定义了,但是没有值。