ES5只有全局作用域和函数作用域,没有块级作用域
ES5规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明
ES5提供String.fromCharCode方法,用于从码点返回对应字符
ES5对字符串对象提供charAt方法
ES5不允许此时使用第二个参数,添加修饰符,否则会报错
ES5 数组forEach(), filter(), every() 和some()都会跳过空位
ES5 数组map()会跳过空位,但会保留这个值
ES5 数组join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串
从ES5开始,函数内部可以设定为严格模式
ES6新增了let命令,用来声明变量,类似 javascript var
ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用
ES6的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错
ES6开始,全局变量将逐步与顶层对象的属性脱钩。
ES6解构赋值,从数组(不是可遍历的结构-Iterator -)中提取值,按照对应位置,对变量赋值,如果解构不成功,变量的值就等于undefined
ES6解构赋值,如果解构不成功,变量的值就等于undefined
ES6解构赋值允许指定默认值
ES6对象结构赋值,对象的属性没有次序,变量必须与属性同名,才能取到正确的值
ES6内部使用严格相等运算符(===)
ES6加强了对Unicode的支持,并且扩展了字符串对象
ES6为字符串添加了遍历器接口(Iterator)
ES6改变了这种行为。如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符
ES6 正则扩展返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符。
ES6对正则表达式添加了u修饰符,含义为“Unicode模式”
ES6提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)
ES6引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。
ES6提供三个新的方法——entries(),keys()和values()——用于遍历数组
ES6则是明确将空位转为undefined
ES6扩展运算符(…)也会将空位转为undefined
ES6 数组遍历for…of循环也会遍历空位
ES6允许为函数的参数设置默认值,即直接写在参数定义的后面
ES6引入rest参数(形式为“…变量名”)
ES6 rest参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
ES6 函数的length属性,不包括rest参数。
ES6 扩展运算符(spread)是三个点(…)。它好比rest参数的逆运算
ES6允许使用“箭头”(=>)定义函数
ES6也是如此,第一次明确规定,所有ECMAScript的实现,都必须部署“尾调用优化”
ES6尾递归的实现,往往需要改写递归函数,确保最后一步只调用自身
ES6的尾调用优化只在严格模式下开启,正常模式是无效的
ECMAScript 2017将允许函数的最后一个参数有尾逗号(trailing comma)
ES7推出了字符串补全长度的功能。
'6'.padStart(2, '0') // '06' String s=String.format("%02d", 1);// java
'133'.padEnd(11, '*') // '********133'
'133'.padEnd(11, '*') // '133********'
许多欧洲语言有语调符号和重音符号。js为了表示他们?
// '\u01D1'==='\u004F\u030C' //false js 无法识别
'\u01D1'.normalize() === '\u004F\u030C'.normalize() // js 可以识别
// 解构赋值
var [a, b, c] = [1, 2, 3];
var [a2, b1, c1] = [1, 2, 3];
var [head, ...tail] = [1, 2, 3, 4];
var { foo, bar } = { foo: "aaa", bar: "bbb" };
var { bar, foo } = { foo: "aaa", bar: "bbb" };
let不像var那样会发生“变量提升”现象(js engine 在渲染时先扫描 var 和 function 声明,实现一个变量声明提升)
let声明的变量就“绑定”(binding)这个区域,不再受外部的影响(不用考虑变量声明重复问题)
let不允许在相同作用域内,重复声明同一个变量,并且严格遵循先声明后使用规则
const声明一个只读的常量
const一旦声明变量,就必须立即初始化,不能留到以后赋值,并严格遵循先声明后使用得原则
// let 和 const
const [a, b, c, d, e] = 'hello';
let {length : len} = 'hello';
const add = ([x, y])=>{
return x + y;
}
在浏览器环境指的是window对象,在Node指的是global对象。
顶层对象的属性与全局变量挂钩,被认为是JavaScript语言最大的设计败笔之一。
提案:在语言标准的层面,引入global作为顶层对象。也就是说,在所有环境下,global都是存在的,都可以从它拿到顶层对象。
var a=1
window.a ==1
let a1 =1 // 同时用 var 和 let 声明同名变量
window.a1
codePointAt方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString方法转换一下
var s = "\uD842\uDFB7"
String.fromCodePoint('0x20BB7')
'abc'.charAt(0) // "a"
// 字符串遍历
var s = 'a';
//s.codePointAt(0).toString(16) // "20bb7"
for(let item of s ){
let value = item.codePointAt(0).toString(16)
console.log(value);
}
// 常用判断场景: 字符串以什么开头,以什么结尾,包含
//这三个方法都支持第二个参数,表示开始搜索的位置
var s = 'Hello world!';
s.startsWith('world', 6) // true 从第n个位置直到字符串结束。
s.endsWith('Hello', 5) // true 针对前n个字符
s.includes('Hello', 6) // false 从第n个位置直到字符串结束。
// 常用场景:清空字符串
// 参数如果是小数,会被取整。
// 如果repeat的参数是负数或者Infinity,会报错。
// 如果参数是0到-1之间的小数,则等同于0
// 0到-1之间的小数,取整以后等于-0,repeat视同为0。
// 参数NaN等同于0。
'na'.repeat(0) // ""
模板字符串(template string)是增强版的字符串,用反引号(`)标识
模板字符串中嵌入变量,需要将变量名写在${}中
如果,大括号中是一个对象,将默认调用对象的toString方法
var name = "Martin", time = "today";
console.log(`Hello ${name}, how are you ${time}?`);
let str = '(name) => `Hello ${name}!`';
// let func = new Function('name', str);
let func = eval.call(null, str);
func('Jack') // "Hello Jack!"
“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数
tag函数的第一个参数是一个数组
“标签模板”的一个重要应用,就是过滤HTML字符串,防止用户输入恶意内容
标签模板的另一个应用,就是多语言转换(国际化处理)
console.log`123`
var siteName = 'PHJRSTBT';
var visitorNumber = '12';
//const i18n =()=>{}
// i18n 是一个函数
`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!`
const SaferHTML = (templateData)=> {
var s = templateData[0];
for (var i = 1; i < arguments.length; i++) {
var arg = String(arguments[i]);
// Escape special characters in the substitution.
s += arg.replace(/&/g, "&")
.replace(/, "<")
.replace(/>/g, ">");
// Don't escape special characters in the template.
s += templateData[i];
}
return s;
}
var sender = ''; // 恶意代码
var message = SaferHTML`${sender} has sent you a message.`;
Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false
Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true'/0) // true
Number.isNaN('true'/'true') // true
//逐步减少全局性方法,使得语言逐步模块化。
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45
Number.isInteger(25) // true
Number.isInteger(25.0) // true
Number.isInteger(25.1) // false
Number.isInteger("15") // false
Number.isInteger(true) // false
JavaScript能够准确表示的整数范围在-253到253之间(不含两个端点),超过这个范围,无法精确表示这个值
ES6引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限
Math.pow(2, 53) // 9007199254740992
Math.pow(2, 53) === Math.pow(2, 53) + 1
Number.EPSILON // 新增一个极小的常量 2.220446049250313e-16
Number.EPSILON.toFixed(20) // '0.00000000000000022204'
Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 // true
Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER // true
Number.isSafeInteger('a') // false
Number.isSafeInteger(null) // false
Number.isSafeInteger(NaN) // false
Number.isSafeInteger(Infinity) // false
Number.isSafeInteger(-Infinity) // false
Number.isSafeInteger(3) // true
Number.isSafeInteger(9007199254740990) // true
Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true
字符串对象正则方法:match()、replace()、search()和split()
var s = '';
var regex = /^\uD83D/.test('\uD83D\uDC2A') // 判断是否是 Unicode 字符
var regex = /^.$/u.test(s) // true,如果不添加u修饰符,正则表达式就会认为字符串为两个字符,从而匹配失败。
new RegExp(/abc/ig, 'i').flags // es6 正则扩展,覆盖更新原来得修饰符,只使用新指定的修饰符
// 数字转数字数组
const sortNumbers = (...numbers) => numbers.sort();
sortNumbers(2, 5, 3) // 10
(function(...a) {}).length // 0
console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5,该运算符主要用于函数调用
Math.max(...[14, 3, 77])
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Array.prototype.push.apply(arr1, arr2);
arr1.push(...arr2);
// ES6 合并数组
[1, 2, ...more]
// ES6 生成数组
[a, ...rest] = list
// 如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上面。
let log = ::console.log; // bind 方法
函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
// 解决堆栈溢出
function factorial(n, total) {
"use strict";
if (n === 1) return total;
return factorial(n - 1, n * total);
}
factorial(5, 1) // 120
function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
"use strict";
if( n <= 1 ) {return ac2};
return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}
Fibonacci2(100) // 573147844013817200000