介绍
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"}