分享一下我一年前端自学路上的学习笔记。
变量声明let和常量声明const
- ES6之前声明变量都使用var(松散类型,可以保存任何数据),没有块级作用域(使用立即执行函数封装块级作用域),存在变量提升(JS预解析机制)
- ES6使用let声明变量,const声明常量,{}内存在块级作用域,不存在变量提升,但产生暂时性死区。
- const声明的常量,不能修改。声明的对象,对象包含的值可以修改。也就是说不能修改指针,可以修改成员。
- 直接上代码,你能直观的感觉到ES6的简洁。
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function () {
console.log(i)
})
}
funcs.forEach(function (func) {
func()
})
原本想要依次输出0-9,结果输出10个10
//使用立即执行函数解决
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push((function (value) {
return function () {
console.log(i)
}
}(i)))
}
funcs.forEach(function (func) {
func()
})
//使用闭包解决
function show (i) {
return function () {
console.log(i)
}
}
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(show(i))
}
funcs.forEach(function (func) {
func()
})
//使用ES6解决
var funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function () {
console.log(i)
})
}
funcs.forEach(function (func) {
func()
})
类的声明和继承
- ES5中声明一个类使用构造函数,实现完美继承需要通过构造函数和原型链组合的方式,同时还要创建一个中间对象,并且要指明实例与构造函数的关系。
- ES6使用class和constructor声明一个类,使用class A extends B,constructor和super()来实现继承
class Animal {
constructor() {
this.type = 'animal'
}
says(say) {
console.log(this.type + 'says' + say)
}
}
let animal = new Animal()
animal.says('hello') // animal says hello
class Cat extends Animal {
constructor() {
super() //表示调用父类的构造函数,但this指向自己
this.type = 'cat'
}
}
let cat = new Cat()
cat.says('hello') // cat says hello
箭头函数
- ES5中定义参数的默认值使用||运算符,ES6可以直接在参数后面加上默认值
- ES5使用function来声明函数,ES6使用箭头函数=>
- 箭头函数不需要function关键字来声明函数,省略了return关键字,最重要的是this继承当前上下文。上代码。
//使用function声明函数
class Animal {
constructor() {
this.type = "animal";
}
say(val) {
setTimeout(function () { //setTimeout异步任务被挂起。this指向window
console.log(this); //window
console.log(this.type + " says " + val);
}, 1000)
}
}
var animal = new Animal();
animal.say("hi"); //undefined says hi
//使用箭头函数=>
class Animal {
constructor() {
this.type = "animal";
}
say(val) {
setTimeout(() => { //异步任务被挂起,但this指向定义所在位置
console.log(this); //Animal
console.log(this.type + ' says ' + val);
}, 1000)
}
}
var animal = new Animal();
animal.say("hi"); //animal says hi
模板字符串
- ES5输出表达式时,我们要使用单引号”将内容括起来并用加号+拼接,换行拼接使用反斜杆\
- ES6则使用反引号将表达式括起来,用${}来限定界限
扩展运算符
- ES6使用扩展运算符…来组装对象和数组,可以快速组装,选择组装,去重组装
解构赋值
- ES5中我们想要获取对象的某个属性,需要一个个获取。即将对象的某个属性赋值给变量。
- ES6使用解构赋值直接获取
const [A ,B] = 想要获取的对象
扩展对象属性
- ES5中,我们都是键值对形式,避免不了键值对重名情况。ES6中,键值对重名就可以简写
- ES5中为某个对象属性进行方法赋值时,我们需要使用function,ES6中就可以省略function
- ES6提供了一个浅拷贝对象的方法,Object.assign() 即将自身可枚举的属性拷贝给目标对象
Promise
- 一种异步编程解决方案,说白了就用同步方式写异步代码。
- ES5中回调或嵌套代码过多,可读性差,耦合度高。所以ES6提出promise,相当于一个容器,里面保存着未来才会结束的结果。
- promise有三种状态:pending fulfilled rejected。状态改变只有两种,即从进行中到成功或者从进行中到失败。只要发生改变就会凝固,即不会改变。
- Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。多个promise实例都决议成功,则promise.all决议成功,并都返回决议成功。若有个决议失败,则promise.all决议失败,并返回决议失败。
//手写一个promise
var promise = new Promise((resolve, reject) => {
if (操作成功) {
resolve(value)
} else {
reject(error)
}
})
promise.then(function (value) {
// success
}, function (value) {
// failure
})
//下面代码输出顺序 23541
setTimeout(function () {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2);
for (var i = 0; i < 10000; i++) {
i == 9999 && resolve();
}
console.log(3);
}).then(function () {
console.log(4);
});
console.log(5);
//下面代码输出顺序 1243
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)