ES6语法
比较var let const
var有什么问题?
1.声明提升
javascript
console.log(num); // undefined
var num = 123
这样应该是报错会更好
所以,let这样操作会直接报错
javascript
console.log(num);
let num = 123
// 报错
2.变量覆盖
javascript
var num1 = 123
var num1 = 1234
console.log(num1); // 1234
// 2.变量覆盖
javascript
let num2 = 123
let num2 = 1234
// 报错
// let 不允许变量覆盖
3.var没有块级作用域
javascript
function f2() {
for (var i = 0; i < 3; i++) {
console.log(i);
}
console.log(i);
}
f2()
const
特性:
-
定义常量,值不能修改
-
const 声明了值一定要赋值
-
let的属性const都支持
-
全局常量一般大写
快速去重的方法
ES6之前
使用两个传统的for循环
而ES6可以,利用集合
javascript
let arr = [12, 43, 43, 123, 12, 55]
let item = [...new Set(arr)]
// 利用集合
console.log(item);
Promise
javascript
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve()
console.log(2)
})
promise.then(() => {
console.log(3);
})
console.log(4);
输出是 1243
因为promise构造函数的方法同步执行
而.then异步执行
闭包
什么是闭包?
闭包就是__方法里面有一个方法
javascript
function a() {
function b() {
let a = 1
return function () {
console.log(a)
}
}
}
闭包的意义何在?
1.延长变量的生命周期
2.创建私有环境
javascript
let name = "admin"
function fn1() {
let b = 1
console.log(name);
}
// console.log(b); 报错
fn1()
JS的执行机制
JS运行的时候会生成一个临时的变量对象.AO(active object)
运行的时候会把所有的变量和临时的方法都放进去,全局变量不在这个里面
1.函数执行完之后,AO销毁
2.函数执行完之后,AO销毁,但是临时的方法还在
3.函数执行完之后,AO销毁,但是临时的方法还在,但是临时的方法里面有变量,这个变量还在
作用域链
javascript
let name = "小明"
function fn2() {
let name = "小白"
function fn1() {
let name = "小红"
console.log(name);
}
fn1()
}
fn2() // 小红
// 函数抱着函数就形成了作用域链,就近原则
// 一层一层的向外找
其实,闭包就是桥梁,所谓沟通内外部方法的桥梁
javascript
function outer() {
let a1 = 111
let a2 = 222
return function inner() {
return a1
}
}
function h5() {
let num = outer()
console.log(num); // 不会输出
// 为什么不建议定义全局变量
// 1. 污染全局变量
// 2.全局变量不会被垃圾机制所回收
}
闭包的问题
闭包会常驻内存,所以要慎用
闭包的应用
Vue中的data()为什么是一个函数,实际上就是一个闭包的设计,Vue中会有很多对应的组件,每一个组件都有一个data,保证了各个组件之间都拥有了一块私有的作用域。
如果不用闭包,各个组件之间就会干扰,这就是闭包的作用
私有作用域
javascript
let makeCounter = function () {
let num = 0
function changeBy(val) {
num += val
}
return {
add: function () {
changeBy(1)
},
reduce: function () {
changeBy(-1)
},
get: function () {
return num
}
}
}
// 一个经典的闭包的私有作用域应用
let counter1 = makeCounter()
let counter2 = makeCounter()
console.log(counter1.get());
counter1.add()
counter2.add()
counter1.add()
console.log(counter1.get());
console.log(counter2.get());
// 他们俩都有各自独立的作用域
原型链与继承
原型是什么?
原型是prototype
原型链是什么?
原型链是什么 proto 谷歌浏览器上 是[[prototype]]
javascript
// 常规对象上没有原型
let obj = {}
let list = []
obj.prototype.a = 56
list.prototype[0] = 123
// 对象和数组上没有
原型是函数上特有的
javascript
// 原型是函数上特有的
function fn() {
}
fn.prototype.name = "cc"
fn.prototype.fn2 = function () {
console.log("fn2")
}
/**
* 原型是函数特有的
* 为什么要在函数原型上挂载东西
* 为了继承
*/
原型链是大家都有的
原型链,原型,继承三者的关系
javascript
// 不是构造函数
function Person() {
}
Person.prototype.name = "cc"
Person.prototype.age = 18
Person.prototype.say = function () {
console.log(this.age)
}
let person1 = new Person()
/**
* new一个东西的时候才是叫做构造函数
* 通过new关键字继承了它的原型属性和方法
* person1就是Person构造函数的实例
*/
console.log(person1.name); // cc
/**
* 首先从当前实例属性去找
* 如果找到了就返回
* 否则就沿着原型链一层一层网上找
* 知道找到了null为止
* 如果找到null还没找到就会报错
*/
/**
* 还有一个问题
* 自身也有属性,父类也有属性
* 它怎么判断呢?
* 它会通过一个forin去循环整个对象
* 对象本身就有一个方法hasOwnPropery
*/
person1.name = "自己的"
console.log(person1.name); // 自己的
// 这样子就能查到私有属性
let item
for (item in person1) {
if (person1.hasOwnProperty(item)) {
console.log(item);
}
}
/**
* 问题是自己没有这个hasOwnPropery方法
* 父类也没有这个方法
* 这个方法从哪里来的?
* 这个是他爹的爹Object上的方法
* Object.hasOwnProperty
* 它爹直接继承Object
*/
/**
* 总结:被构造的东西,它的原型链指向的是构造他的方法的原型
*/