let和const
let和var的区别
- let声明的变量只在当前(块级)作用域内有效
- let声明的变量不能被重复声明
- 不存在变量提升
- {} 内形成块级作用域
- 在if和for语句中 {} 会形成块级作用域
- var obj = {}; 这种情况不能是块级作用域,而是对象
- const和var的区别
- var声明的是变量,而const声明的是常量
- 常量必须在声明的时候赋值,++不能重复声明++
- 当const为引用类型时,常量可被修改
- 当常量的地址不变化,且指向该地址的属性时,常量可被改变
- 而当常量的地址指向新地址时,该常量不可被修改
const XM = {
age:15,
name:'小明'
};
console.log(XM); // 15
XM.age = 18;
console.log(XM); // 18
变量的解构赋值
扩展运算符
const arr = [1,2,3,4];
const [a,b,...c] = arr; // c =>[3,4]
-
注意点
- 数组中,扩展运算符必须放在最后,否则报错
- 对象中,扩展运算符后面可加属性,但合并的属性还是会排在最后
-
默认值
- 无属性值或属性值为undefined时才会取默认值
- 当数组中有undefined和null,对应undefined才会选择默认值,而null不会
let girlFriend = { name: '小红', age: undefined }; let {name, age = 24,hobby = ['学习']} = girlFriend; // name: '小红', age=24, hobby=['学习']
-
对象的解构赋值
- const {a,b} = {a:1, b:2} 左边{}是需要赋值的变量,右边时需要解构的对象
-
获取多个函数返回值
function getUserInfo(uid) { // ..ajax return { status: true, data: { name: '小红', sex: 'nan', uid: uid }, msg: '请求成功' } } const {status, data, msg: message} = getUserInfo(1234);
ES6扩展
-
模拟ajax数据请求
function getUserInfo(uid) { // ..ajax return { status: true, data: { name: '小红', sex: 'nan', uid: uid }, msg: '请求成功' } } const {status, data, msg: message} = getUserInfo(1234);
-
字符串扩展
- padStart(n, str) 用于头部补全,padEnd(n, str)尾部补全
let str = 'i'; let str1 = str.padStart(7, 'mooc'); // moocmoi let str2 = str.padEnd(6, 'mooc'); // immocm
- repeat() 重复,复制
- 参数如果是小数,会被取整;如是负数,则会报错
function repeat(str, num){ return new Array(num + 1).join(str); } console.log(repeat('a', 3)); // aaa
- startsWith()与endsWith()
- 判断是否以某个字符串开头或者结尾,返回布尔值。接受一个参数
- includes() ·判断字符串是否存在
-
对象扩展
- Object.freeze()
- 冻结对象,失去被修改的能力;对象、数组类型都可用
- Object.defineProperty()
- 将属性添加到对象上,或修改现有属性的特性
- writable属性表示是否可修改该属性,值为布尔值
- Object.seal() 防止对象被扩展
var CST = {}; Object.defineProperty(CST,'base_name',{ value: '小明', writable: true // 表示可修改该属性 }); CST.base_name = '小花'; console.log(CST.base_name); // 小花 Object.seal(CST);
- Object.keys() and Object.values() 自身属性/键值
- Object.entries() 返回是一个数组
for(let [k, v] of Object.entries(obj)){ console.log([k, v]); }
-
Object.is(num1, num2) 比较两个数是否相等
-
Object.assign() 合并对象
-
用扩展运算符复制、合并对象都是浅拷贝的
-
Object.setPrototypeof 修改对象原型
-
super 指定对象的原型
- 只有对象简表达式才能调用super,普通和箭头函数都不行
const obj = {name: '小明'} const cObj = { say(){ console.log(`My name is ${super.name}`); } } Object.setPrototypeOf(cObj, obj); cObj.say();
- Object.freeze()
- 函数扩展
-
箭头函数
- 没有arguments
- 没有关键字this (let _this = this)
-
void关键字
- 让代码执行完但不返回值或者只返回undefined
const pop = arr => void arr.pop(); console.log(pop([1,3,5]));
-
reduce()
- 方法接受一个函数,作为累加器,第二个参数为初始值
function sum(...number){ return number.reduce((a, b) =>{ return a + b },0) } console.log(sum(2,9,6,8)); // 25
-
-
数组扩展
- Array.from() 将一个ArrayLike对象或者Iterable对象转换成一个数组
- Array.of() 把数字转换成数组
- Array.fill(value, rang) 填充数组
- Array.includes(value) 是否有该value
- find 根据条件(回调),按顺序遍历数组
const res = [1, 7, 6, 9].find( (value, index, arr) => value % 2 === 0); // 6
Promise
- catch 使用实例的then方法,可以捕获错误
- finally 不论成功还是失败 其内容一定会执行
function f(val) {
return new Promise((resolve, reject) => {
if (val) {
resolve({
name: '小明'
});
} else {
reject('404');
}
})
}
f(true)
.then(data => {
console.log(data);
return f(false)
})
.catch(e => {
console.log(e);
return f(true)
})
.finally(() => {
console.log(100)
})
- Promise.all() 该方法把多个promsie实例合成一个新的promise实例
- Promise.race() 有一个promise实例成功或者失败就会把它返回
Promise动画移动案例
function moveTo(el, x, y, cb) {
return new Promise(resolve => {
el.style.transform = `translate(${x}px,${y}px)`;
setTimeout(function() {
resolve();
}, 1000)
});
}
let el = document.querySelector('#el');
document.querySelector('button').addEventListener('click', e => {
moveTo(el, 100, 200)
.then(function() {
console.log('第一次移动');
return moveTo(el, 150, 270)
})
.then(function() {
console.log('第二次移动');
return moveTo(el, 260, 150)
})
.then(function() {
console.log('第三次移动');
return moveTo(el, 0, 0)
})
.then(function() {
console.log('移动结束');
})
})
Class
- 面向对象三大基本特性:多态、继承、封装
- 构造函数的this指代类实例化后赋值的变量
- 静态属性与静态方法
- 不会被类实例所拥有的属性与方法 只是类自身拥有
- 只能通过类调用
- 声明方式
- 静态属性:类名声明
- 静态方法: static 关键字声明
- getter 与 setter
let year = prompt("请输入年份");
class getYear{
constructor(){
this._age = 18;
}
get age(){
return new Date().getFullYear() - year
}
set age(val){
if (!isNaN(year) && year.length != 4) this._age = 18;
}
}
const get_year = new getYear();
document.write(`今年的年龄是:${get_year.age}岁`);
- new关键字调用函数过程
- 创建一个空的对象
- 把构造函数的prototype属性,作为空对象的原型
- this赋值为这个空对象
- 执行函数
- 如果函数没有返回值 则返回this[返回之前这个空对象]
- extends
- super
- 作为父类构造函数调用
- 作为对象的方式调用
- 非静态方法中访问super -> 父类原型
- 在静态方法中访问super -> 父类
- 子类调用this前必须调用super(),super()指代的是父类的constructor
- super
- 模拟一个音乐播放器类
<div id="app"></div>
class AudioPlayer {
constructor(container) {
this.container = document.querySelector(container);
this.songsList = []; //歌单列表
this.dom = null; //用于存放dom
this.audio = new Audio(); //Audio对象
this.status = 0; //标记播放器状态
this.getSongs();
this.createElement();
this.bindEvents();
this.render();
}
getSongs() {
//……ajax……
this.songsList = [
{
cover: '', //封面
url: '.mp3', //资源地址
singer: {}, //歌手信息
name: '' //歌曲名字
}
];
}
createElement() {
//生成dom
const div = document.createElement('div');
div.innerHTML = `
<div class="btn">播放按钮</div>
<div>进度条</div>
`;
this.dom = div;
}
bindEvents() {
this.dom.querySelector('.btn').addEventListener('click', () => {
console.log('开始播放');
})
}
render() {
this.container.appendChild(this.dom)
}
}
new AudioPlayer('#app');