介绍

JS的组成部分:ECMASript(核心)+DOM(文档对象模型)+BOM(浏览器对象模型)

ECMASript
定义语法,关键字,语句,声明,操作
定义类型,布尔型,数字,字符串,对象等
内置对象和函数的标准库x,数字(Math),数组方法,对象内省的方法等等。

BOM(browser Object Model)
是指浏览器对象模型,它使JavaScript有能力与浏览器进行"对话".

DOM(Document Object Model)
是指文档对象类型,通过它,可以访问HTML文档的所有元素

let和const命令

ES6新增了let和const,局部作用域的定义,比var是全局可重复定义更易代码维护。

{
  let a = 10;
  var b = 1;
}

console.log(a); // 报错:ReferenceError: a is not defined``
console.log(b); // 打印:1

变量的解构赋值

数据可以按照位置一次性赋值多个变量,不需要像以前那样,定义一个赋值一个。

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

//字符串赋值
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

默认值

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x = 3} = {x: undefined};
x // 3

var {x = 3} = {x: null};
x // null

字符串的新增方法

// JavaScript 内部,字符以 UTF-16 的格式储存,每个字符固定为2个字节。
let s = '𠮷a';
s.codePointAt(2) // 97

includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

// 第二个参数,表示开始搜索的位置。
let s = 'Hello world!';

s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

ES2019 对字符串实例新增了trimStart()和trimEnd()这两个方法。它们的行为与trim()一致,trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。

const s = '  abc  ';

s.trim() // "abc"
s.trimStart() // "abc  "
s.trimEnd() // "  abc"

正则表达式

字符串对象共有 4 个方法,可以使用正则表达式:match()、replace()、search()和split()。ES6 将这 4 个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上。

修饰符

描述

i

执行对大小写不敏感的匹配。

g

执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。

m

执行多行匹配。

Match

var reg = new RegExp("飞雪","g");
var str = "风雨送春归飞雪迎春到,飞雪连天向天横";
console.log(str.match(reg)); 
 //打印数组: [0]="飞雪" [1]="飞雪"

 //也可以用以下方法简写
var reg = new RegExp(/飞雪/g);

Search

var txt="hello world!";
console.log(txt.search("world")); //返回值:6 此时为字符串
console.log(txt.search(/World/)); //返回值:-1 search()方法对大小写敏感
console.log(txt.search(/World/i)); //返回值:6 i忽略大小写的检索

Replace

var str="你好 世界!"
console.log(str.replace(/世界/, "中國"))//返回值:你好 中國!

split

var str="How are you doing today?"
document.write(str.split(" "))

document.write("<br/>")
document.write(str.split(""))

document.write("<br/>")
document.write(str.split(" ",1))
//第二个参数代表返回的数组长度不>1

数值运算

ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。

// ES5的写法
parseInt('12.34') // 12
parseFloat('123.45#') // 123.45

// ES6的写法
Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45

Number.isInteger()用来判断一个数值是否为整数。

Number.isInteger(25) // true
Number.isInteger(25.0) // true,整数和浮点数采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值
Number.isInteger(25.1) // false
Number.isInteger('15') // false

Math.trunc方法用于去除一个数的小数部分,返回整数部分。

Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0

对于非数值,Math.trunc内部使用Number方法将其先转为数值。

Math.trunc('123.456') // 123
Math.trunc(true) //1
Math.trunc(false) // 0
Math.trunc(null) // 0

函数的扩展

ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

function Point(x = 0, y = 0) {
  this.x = x;
  this.y = y;}

const p = new Point();
p // { x: 0, y: 0 }

参数默认值可以与解构赋值的默认值,结合起来使用。

function foo({x, y = 5}) {
  console.log(x, y);}

foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined


function fetch(url, { body = '', method = 'GET', headers = {} }) {
  console.log(method);
  }

fetch('http://example.com', {})
// "GET"
fetch('http://example.com')
// 报错

利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。

function throwIfMissing() {
  throw new Error('Missing parameter');}

function foo(mustBeProvided = throwIfMissing()) {
  return mustBeProvided;}

foo()
// Error: Missing parameter

ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;}

add(2, 5, 3) // 10

注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。

// 报错
function f(a, ...b, c) {
  // ...
}

name属性

ES6 对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5 的name属性,会返回空字符串,而 ES6 的name属性会返回实际的函数名。

var f = function () {};
// ES5
f.name // ""

// ES6
f.name // "f"

扩展运算符

扩展运算符提供了数组合并的新写法。

// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]

var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];

// ES5的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6的合并数组
[...arr1, ...arr2, ...arr3]

箭头函数

var f = v => v;
// 等同于
var f = function (v) {
       return v;
  };
  
var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;};

catch 命令的参数省略
JavaScript 语言的try…catch结构,以前明确要求catch命令后面必须跟参数,接受try代码块抛出的错误对象。

try {
  // ...
} catch (err) {
  // 处理错误
}

//ES2019可以省略
try {
  // ...
} catch {
  // ...
}

数组的扩展

ES5 写法中,push方法的参数不能是数组,所以只好通过apply方法变通使用push方法。有了扩展运算符,就可以直接将数组传入push方法。

// ES5的 写法
var arr1 = [0, 1, 2];var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);

// ES6 的写法
let arr1 = [0, 1, 2];let arr2 = [3, 4, 5];
arr1.push(...arr2);

扩展运算符提供了复制数组的简便写法。

const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

下面是浅拷贝,a3和a4是用两种不同方法合并而成的新数组,但是它们的成员都是对原数组成员的引用。如果修改了引用指向的值,会同步反映到新数组。

const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];

const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];

a3[0] === a1[0] // true
a4[0] === a1[0] // true

对象扩展

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }


let foo = { ...['a', 'b', 'c'] };
foo
// {0: "a", 1: "b", 2: "c"}


{...'hello'}
// {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}