- JavaScript中有三部分ECMScript、BOM、DOM。
名称 | 功能 |
---|---|
ECMScript | js标准(所有的js解析器都可以兼容) |
BOM | js操作浏览器的api |
DOM | js操作html的api |
- let与var
let声明的变量是局部变量,只能在声明的代码块中使用。
var声明的可以在全局调用,var存在变量提升。
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
-
基本数据类型
(用于保存单个值)
string number boolean null undefined
引用数据类型
(用于保存多个值)
数组 函数 对象 正则表达式 -
变量都维护在栈区,基本数据类型的值保存在栈区,而引用数据类型的引用地址保存在栈区,值保存在堆区。
-
ES5 比较两个值是否相等,只有两个运算符:相等运算符 == 和严格相等运算符===。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。
ES6中用Object.is()来判断。
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
- Symbol()
对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
let s = Symbol();
typeof s
// "symbol"
- 内置函数
typeof a //查看变量a的数据类型
isNaN() //当参数为NaN时返回true,判断一个变量是否为NaN类型
isFinite() //当参数无穷大/小返回false,判断参数是否为有穷的
- this关键字总是指向函数所在的当前对象,ES6 新增关键字super,指向当前对象的原型对象。
如果使用"()"调用函数,观察"()"左边是否是函数名,如果是函数名,继续观察函数名左边是否存在对象,如果是,那么this指向这个对象;如果不是指向全局对象(global/window)
super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。
const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
//对象obj.find()方法之中,通过super.foo引用了原型对象proto的foo属性。
- 解构
扩展运算符(spread)是三个点(…),好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
扩展运算符用于函数中
function push(array, ...items) {
array.push(...items);
}
function add(x, y) {
return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
// push(array, ...items) ,add(...numbers),该运算符将一个数组,变为参数序列。
console.log(...[1, 2])// 1 2
只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。
扩展运算符提供了数组合并的新写法。
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
扩展运算符可以与解构赋值结合起来,用于生成数组。
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如 Map 结构。
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]
- 数组及方法
添加或者移除元素 【对原值进行了改变】
push() 入栈,将元素添加到数组的最后
参数:入栈的元素
返回值:入栈后数组的长度
pop() 出栈,将数组中的最后一个元素移除,并且返回
参数:none
返回值:被出栈的元素
shift() 出队,将数组中的第一个元素移除,并且返回
参数:none
返回值:被移除的元素
unshift() 插队,将元素添加到数组的最前面
参数:插队的元素
返回值:插队后数组的长度
排序方法【改变原值】
sort();
默认情况下,按照每位字符在字符编码表中出现的位置进行排序
sort(comparator)
comparator
接受两个参数a,b;
如果a在b之前返回-1
如果a在b之后返回1
截取方法
concat() 【不改变原值】
数组合并
参数:多个数组
返回值:合并后的新数组
slice(begin [,end])【不改变原值】
截取子数组,并且返回
参数: begin表示截取的开始位置;end默认为0
返回值:截取后的子数组
splice(begin,delete,insert,...)【改变原值】
arr.splice(3,2)
arr.splice(3,2,"terry","larry")
返回值:被删除的元素组成的数组
- 事件
事件三要素:事件源、事件处理函数、事件对象。
事件流(元素嵌套,为每层元素添加事件处理函数)
1. 事件捕获(外->内)
2. 事件冒泡(内->外)
在多数浏览器中,默认按照事件冒泡的方式来执行事件处理函数,也就是越靠里的元素上的事件处理函数越先执行。
- 正则表达
字符串对象共有 4 个方法,可以使用正则表达式:match()、replace()、search()和split()。
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
- Generator
Generator 函数是一个状态机,封装了多个内部状态。
Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态 - Promise
Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
//timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。
- async
async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。