ECMAScript 与 javascript 的关系
2008 年 7 月 ES4中止, ES3.1发布
2009 年 12 月 ES5(ES3.1改名)正式发布
2011-6 ES5.1
2015-6 ES6(ES2015), 开始以年号命名
0 Strawman
1 Proposal
2 Draft
3 Candidate
4 Finished
Babel: 高版本 -> ES5
.babelrc
{
presets: [],
plugins: []
}
bebel
traceur
===============
let 声明的变量只在它所在的代码块有效
var 声明的变量全局只有一个
for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域
let 不存在变量提升
JavaScript并不强制要求在每个语句的结尾加;
,浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上;
//
和 非嵌套的 /* ... */
作为注释
JavaScript不区分整数和浮点数,统一用Number表示
1, 1.0, 1e1, .5, NaN, -Infinity, 0xff
字符串是以单引号'或双引号"括起来的任意文本
&&
,||
,!
逻辑运算
实际上,JavaScript允许对任意数据类型做比较
第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果
第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较
// NaN这个特殊的Number与所有其他值都不相等,包括它自己
NaN === NaN; // false
isNaN('a' / 1); // true
注意浮点数比较
1 / 3 === (1 - 2 / 3); // false
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
会产生 false 的值: '', 0, null, false, NaN, 0.0, 0e2, 0x0
undefined仅仅在判断函数参数是否传递的情况下有用
new Array(1, 2, 3); // [1, 2, 3]
JavaScript对象的键都是字符串类型
,值可以是任意数据类型
变量名
也可以用中文
,但是,请不要给自己找麻烦
JavaScript在设计之初,并不强制要求用var申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量
使用var申明的变量则不是全局变量,它的范围被限制在该变量被申明的函数体内(函数的概念将稍后讲解),同名变量在不同的函数体内互不冲突
ECMA 'use strict';
强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误
ASCII字符可以以\x##形式的十六进制表示
'\x41'; // 完全等同于 'A'
还可以用\u####表示一个Unicode字符
'\u4e2d\u6587'; // 完全等同于 '中文'
需要特别注意的是
,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果
substring(start[, end]) 切片
请注意,直接给Array的length赋一个新的值
会导致Array大小的变化
请注意,如果通过索引赋值
时,索引超过了范围,同样会引起Array大小的变化
Array.indexOf
Array.slice([start[, end])
复制一个Array
push()向Array的末尾添加若干
元素, 并返回新的长度
arr.pop(); // 空数组继续pop不会报错,而是返回undefined
shift: 去掉之意
unshift
Array.sort([sortby=func]) 返回排序后的数组
Array.reverse()
splice: 胶接
splice() 方法向/从数组中添加/删除项目,然后
返回被删除的项目
arrayObject.splice([index[, howmany[, item1,.....,itemX]]])
Array.concat(itemOrArr, ...)
如果Array的元素不是字符串,将自动转换为字符串后再连接
,
是默认的分隔符号
var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined; 但是 let 不会.
暂时性死区(temporal dead zone)
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域
。凡是在声明之前就使用这些变量,就会报错
“暂时性死区”也意味着typeof不再是一个百分之百安全的操作
😯如果一个变量根本没有被声明,使用typeof反而不会报错
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
let不允许在相同作用域内
,重复声明同一个变量
ES5 只有全局作用域和函数作用域, let实际上为 JavaScript 新增了块级作用域
块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了
ES5 规定,函数只能在顶层作用域和函数作用域之中声明,
不能在块级作用域声明;
但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数.
ES5 if 内声明的函数f会被提升到函数头部
如果真的想将对象冻结,应该使用Object.freeze方法
window/self/global, use this
全局环境中,this会返回顶层对象。
但是,Node 模块和 ES6 模块中,this返回的是当前模块。
函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this会指向顶层对象。
但是,严格模式下,这时this会返回undefined。
不管是严格模式,还是普通模式,
new Function('return this')(),总是会返回全局对象。
但是,如果浏览器用了 CSP(Content Security Policy,
内容安全策略),
那么eval、new Function这些方法都可能无法使用。
require('system.global/shim')();
in
判断的属性可能是继承得来的
hasOwnProperty()
[不完全]解构(解构不成功,变量的值等于undefined):
,
...
[]
只要某种数据结构具有 Iterator 接口, 就可以使用解构.
function* fibs () {
}
let [a='dft'] = [undefined]
如果等于 undefined, 才使用默认值
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
嵌套解构(括号很重要, 不然理解为代码块)
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
function move({x = 0, y = 0} = {}) {
return [x, y];
}
不要在模式中放置圆括号;
函数参数也属于变量声明,因此不能带有圆括号
- 变量声明不能出现()
- 赋值, 模式中不能包含()
- 函数参数(也属于变量声明)
赋值语句的非模式部分才可以使用()
任何部署了 Iterator 接口的对象,都可以用for...of循环遍历
for (let [key, value] of map)
JavaScript把null、undefined、0、NaN和空字符串''视为false
javascript 不支持
连续比较
网友评论