目录
八、rest参数:获取函数参数, 用来代替arguments
一、let变量声明以及声明特性
1.变量不可重复声明
let star = '郑建'
let star = 'Zack Jason' // 报错 变量重复声明
// 使用var可以重复声明
2.块级作用域(在{}里声明的变量 不可以在{}外使用)
if(true) {
let girl = 'Molly'
}
console.log(girl) // 报错 不可以访问这个变量
3.不存在变量提升
console.log(song); // 报错没声明就调用
let song = '恋爱达人';
4.不影响作用域链
{
let dog= '小狗'
function fn(){
console.log(dog);
}
fn(); // 可以打印出dog 函数里没有找到定义的dog会往作用域链上找
}
二、const变量声明以及声明特性
1.一定要赋初始值
const NAMe = '郑建'
2.一般常量用大写(潜规则)
const A = 100;
3.常量值不能修改
const NAME = '郑建'
NAME = 'Zack Jason' // 报错 const声明的变量不可修改值
4.块级作用域
if(true) {
const NAME = '郑建'
}
console.log(NAME); // 报错 外部不可访问{}内部定义的变量
5.对于数组和对象的元素修改,不算对常量的修改,不会报错(引用类型的引入地址 你修改东西的时候没有改变,所以不会报错, 它检测的是引用地址)
const TEAM = ['郑建', 'Zack Jason'];
TEAM.push('Meiko'); // 不会报错
三、解构赋值
1.数组解构
const F4 = ['郑建', 'Molly', 'Zack Jason', '莫丽'];
let [Z, M, ZA, ML] = F4;
console.log(Z); // 郑建
console.log(M); // Molly
console.log(ZA); // Zack Jason
console.log(ML); // 莫丽
2.对象的解构 (拿key)
const zhao = {
name: '赵B山',
age: '??',
xiaopin: function() {
console.log('我是黑社会')
}
};
let {name, age, xiaopin} = zhao;
console.log(name); // 赵B山
console.log(name); // ??
xiaopin(); //调用xiaopin函数
四、模板字符串
1.声明
let str = `你是一个笨蛋`
console.log(str, typeof str) // 你是一个笨蛋 string
2.内容中可以直接出现换行符
let str = `我
是
你
爷
爷`;
//如果传统的写法换行需要用+''+拼接
3.变量拼接通过${变量}
let lovest = '郑建';
let out = `${lovest}是我心目中最搞笑的人!!`;
console.log(out); // 郑建是我心目中最搞笑的人!!
五、对象的简化写法
1.ES6允许在大括号里面直接写入变量和函数,作为对象的属性和方法
let name = '郑建';
let chang = function() {
console.log('嗯嗯')
};
const school = {
//name = name; //简化为name
name,
change,
improve() { // 在类里面这个样定义函数属性 improve: improve(){}
console.log("嗯呢")
}
}
六、箭头函数
1.箭头函数的声明
// 普通的声明一个函数
let fn function(a, b) {
return a + b;
}
//箭头函数声明一个函数
let fn1 = (a, b) => {
return a + b;
}
2.箭头函数的this是静态的 this始终指向函数声明时所在的作用域下的this的值(没有自己的this)
function getName() {
coonsole.log(this.name)
}
let getName2 = () => {
console.log(this.name)
}
设置window对象的name属性
window.name = '尚硅谷';
const school = {
name: '儿子'
}
// 直接调用
getName(); // 尚硅谷
getName2(); // 尚硅谷
// call 方法调用 call方法是可以改变this的值
getName.call(school); // 儿子
getName2.call(school); // 尚硅谷
// 无论你怎么改变 箭头函数始终指向当前它声明的作用域下的this值
3. 不能作为构造实例化对象
let Person = (name, age) => {
this.name = name;
this.age = age;
}
let me = new Person('郑建', 18)
console.log(me)
// 以上是会报错的
4.不能使用arguments变量
let fn = () => {
cosnole.log(arguments);
}
fn(1, 2, 3)
// 以上是错误的
5.箭头函数的简写(一个形参省略小括号,函数体一行省略花括号和return)
// 1.省略小括号,当形参只有一个的时候
let add = n => {
return n + n
}
console.log(add(9)); // 18
// 2.省略花括号,当代码体只有一条语句的时候,此时return必须省略
// 而语句的执行结果就是返回结果
let pow = n => n * n;
// 3. 如果函数体返回一个对象简写的时候一定要用()包裹起来 否则对象的{}被当成函数体的{}
let pow1 = () => ({ name: '证件' })
七、函数参数赋初始值
1.形参初始值 ; 注意: 默认值参数一定要放在最后
function add(a, b, c = 10) {
return a + b + c
}
let result = add(1, 2)
console.log(result) // 13
八、rest参数:获取函数参数, 用来代替arguments
1.ES5获取实参的方式
function date() {
console.log(argumenets); // 打印出来的是一个对象
}
date('郑建', '啊郑', '啊建');
2.rest参数的使用
// rest参数必须放到参数最后
function fn (a, b, ...args) {
console.log(a); // 1
console.log(b); // 2
console.log(args); // 3 4 5 6
}
fn(1, 2, 3, 4, 5, 6)
九、扩展运算符
1.扩展运算符能将数组转换为逗号分隔的参数序列
const tfboys = ['郑建', '证件', '正紧'];
console.log(...tfboys); // '郑建', '证件', '正紧'
2.合并数组
const tfboys = ['郑建', '证件', '正紧'];
const aaa = ['嗯嗯', '啊啊']
console.log(...tfboys, ...aaa); // 郑建 证件 正紧 嗯嗯 啊啊
十、Symbol
//创建Symbol
let s = Symbol();
let s2 = Symbol('郑建');
let s3 = Symbol('郑建');
console.log(s2 === s3); // false
// 创建Symbol.for 创建
let s4 = Symbol.for('郑建');
let s5 = Symbol.for('郑建');
console.log(s4 === s5); // true
// 不能参与运算
let result = s + 100; // 报错
十一、迭代器for...of
const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧']
// 使用for...of遍历数组
for(let v of xiyou) {
console.log(v); // 分别输出唐僧 孙悟空 猪八戒 沙僧
}
十二、生成器函数声明与调用
1.基本使用
// 生成器的声明
function * gen(arg) {
console.log(arg); // aaa
let one = yield 111;
console.log(one); //BBB
let two = yield 222;
console.log(two); // CCC
}
// 执行获取迭代器对象
let iterator = gen('aaa');
console.log(iterator.next()); // {value: 111, done: false}
console.log(iterator.next('BBB')); // {value: 222, done: false}
console.log(iterator.next('CCC')); // {value: undefined, done: true}
2.案例(利用生成器解决回调地狱问题)
需求: 1s后控制台输出111,2s控制台输出222, 3s控制台输出333
// 回调地狱
setTimeout(() => {
console.log(111); // 1s后控制台输出111
setTimeout(() => {
console.log(222); // 2s后控制台输出222
setTimeout(() => {
console.log(333); // 3s后控制台输出333
}, 3000)
}, 2000)
},1000)
// 用生成器解决回调地狱的问题
function one() {
setTimeout(() => {
console.log(111);
iterator.next();
}, 1000)
}
function tow() {
setTimeout(() => {
console.log(222);
iterator.next();
}, 2000)
}
function three() {
setTimeout(() => {
console.log(333);
iterator.next();
}, 3000)
}
// 定义生成器函数
function * gen() {
yield one();
yield two();
yield three();
}
// 调用生成器函数
let iterator = gen();
iterator.next();
十三、promise
1.promise的基本使用
const p = new Promise(function(resolve, reject){
setTimeout(() => {
// 成功
let data = '成功';
resolve(data); // 成功的回调函数
//失败
let err = '数据读取失败'
reject(err)
}, 1000)
});
// then()参数一为成功的回调: 调用resolve()就会执行成功的回调,数据res是通过resolve方法参数传过来的
// then()参数二为成功的回调: 调用reject()就会执行失败的回调,数据err是通过reject方法参数传过来的
p.then(res => {
console.log(res)
}, err => {
console.log(err)
})
2.使用promise封装ajax
const p = new Promise((resolve, reject) =>{
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化
xhr.open('GET', '请求的路径');
// 3.发送
xhr.send();
// 4.绑定事件,处理响应结果
xhr.onreadystatechange = function() {
// 判断
if(xhr.readyState === 4) {
// 判断响应状态码
if(xhr.status => 200 && xhr.status < 300) {
// 表示成功
resolve(xhr.response);
}else{
// 如果失败
reject('xhr.status')
}
}
}
})
// 调用指定回调
p.then(res => {
console.log(value)
}, err => {
console.error(err)
})
3.promise的.then方法
promise对象的.then()方法里面成功返回一个不是promise对象 在外面你还是能接收到一个Promise对象,并且返回的结果就是你return的结果
如果return的是一个Promise对象 return的这个promise对象如果resolve它最外层的.then方法也是得到的成功的状态 返回的结果为最里面resolve传进去的值
// 创建一个 promise对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
// reject('出错了');
}, 1000)
});
// 调用 then方法 then方法返回结果是Promise对象,对象状态由回调函数的执行结果决定了
// 1.如果回调函数中返回的结果是 非Promise类型的属性,状态为成功,返回值为对象的成功的值
const result = p.then(res => {
// 1. 非promise类型的属性
// return '嗯嗯'; // 当前返回的不是一个Promise类型是 状态为成功 返回的也是一个
// 2.是promise对象
return new Promise((resolve, reject) => {
resolve('ok');
// reject('error');
})
// 3.抛出异常
// throw new Error('出错了')
throw '出错了'
}, err => {
})
// 1.return 非promise类型 打印出一个成功的promise值为 '嗯嗯'
// 2.return promise类型 (1)如果返回的promise函数体里调用resolve 打印的是成功的ok
// (2)如果返回的promise函数体里调用reject 打印的是失败的erro
// 3.return promise类型里面调用的成功状态或者失败状态 p.then()就打印什么状态
console.log(result)
4.链式调用(then的后面又接.then)
p.then(res => {
}, err => {
}).then(res => {
}, err => {
}).then(res => {
}, err => {
})
5.chtch: 就是reject的一个语法糖
const p = new Promise((resolve, reject) => {
resolve('成功')
reject('失败')
})
p.then(res => {
cosnole.log('res') // 成功
}).catch(err => {
cosnole.log('err') // 失败
})
或
p.catch(err => {
cosnole.log('err') // 失败
})
十四、Set(集合): 类似数组 里面的元素是唯一的
// 声明一个set并赋值
let s2 = new Set([1, 2, 1, 3])
console.log(s2) // {1, 2, 3} 去重了两个1现在只有一个1
// 元素个数 size相当于length
console.log(s2.size); // 4
//添加新属性
s2.add('4')
console.log(s2); // Set(4) {1, 2, 3, 4}
//删除属性
s2.delete('4')
console.log(s2); // Set(3) {1, 2, 3}
// 检测
console.log(s2.has(1)) //true
// 清空
s2.clear()
console.log(s2) // Set(0) {}
// 遍历
for(let v of s2) {
console.log(v);
}
2.使用案例
let arr = [1, 2, 3, 4, 3, 2, 1];
// 1. 数组去重
// new Ser(arr)去重 ...new Ser(arr)的...是让元素 1, 2, 3 4
let result = [...new Ser(arr)]
console.log(result); // [1, 2, 3, 4]
// 交集
let arr2 = [2, 3, 4, 5, 4, 3, 2, 1]
let result1 = [...new Set(arr)].filter(item => {
let s2 = new Set(arr2); // 2 3 4 5 1
if(s2.has(item)) {
return true
}else {
return false
}
});
console.log(result1); // [2, 3, 4, 1]
// 并集
let union = [...new Set([...arr, ...arr2])];
console.log(union); // [1, 2, 3, 4, 5]
// 差集(就是别人没有的 我自己有的)
// 略
十五、Map
// 声明
let m = new Map();
// 添加元素
m.set('name', '郑建');
console.log(m); // Map {'name' => '郑建'}
m.set('change', function() {
console.log();
});
let key = {
school: '嗯嗯';
};
m.set(key, ['北京', '上海', '北京']);
console.log(m); // Map {'name' => '郑建', 'change' => function() { console.log('嗯嗯')}, 'Obkect' => Array[3]}
//size
console.log(m.size); // 3
// 删除
m.delete('name'); // Map {'change' => function() { console.log('嗯嗯')}, 'Obkect' => Array[3]}
// 获取
console.log(m.get('change')); // function() { console.log('嗯嗯')}
// 清空
m.clear();
console.log(m); // Map {}
// 遍历
for(let v of m){
console.log(v); // 依次打印例如: ["name", "郑建"] ["change", f]
}
十六、class
1.ES5定义
// 定义一个函数对象
function Phone(brand, price){
this.brand = brand;
this.price = price;
}
// 给类添加方法
Phone.prototype.call = function() {
console.log("我可以摇人");
}
// 实例化对象
let Huawei = new Phone('华为', 9999);
Huawei.call(); // 我可以摇人
console.log(Huawei); // Phone {brand: "华为", price: 9999}
2.ES6定义
class Shouji{
// 构造方法 用来初始化值的
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 方法
call() {
console.log("我能打电话");
}
}
let onePlus = new Shouji("1+", 1999);
console.log(onePlus); Shouji {brand: "1+", price: 1999}
3.class的静态成员(只能通过类名调用 不能通过实例对象调用)
class Phone{
//通过static关键字定义
static name = '手机';
static change() {
console.log("八八八八")
}
}
let nokia = new Phone();
console.log(nokia.name); // undefined
console.log(Phone.name); // 手机
4.类继承
class Phone{
// 构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log("我可以打电话");
}
}
class SmartPhone extends Phone {
// 构造方法
constructor(brand, price, color, size){
super(brand, price)
this.color = color;
this.size = size;
}
}
const xiaomi = new SmartPhone('小米', 988, '黑色', '4.7inch')
//调用父类的方法
xiaomi.call(); // 我可以打电话
5.子类对父类方法的重写
class Phone{
// 构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log("我可以打电话");
}
}
class SmartPhone extends Phone {
// 构造方法
constructor(brand, price, color, size){
super(brand, price)
this.color = color;
this.size = size;
}
// 重写父类的方法
call() {
console.log("我可以视频通话");
}
}
const xiaomi = new SmartPhone('小米', 988, '黑色', '4.7inch')
//调用父类的方法
xiaomi.call(); // 我可以视频通话
6.getter和setter
// get和set
class Phone{
get price(){
console.log("价格属性被读取了");
return 'iliveyou'
}
set price(newVal) { // 必须有一个参数 否则报错
console.log("价格属性被读取了");
}
}
// 实例化对象
let s = new Phone();
// 调用set 的那个函数体 传一个free进去
s.price = 'free'
// s.price: 读取实例对象s的price属性 并且属性price它绑定了一个函数 也就是说访问price属性就会执行它绑定的函数里面的内容 而且里面的返回值就是属性的值
console.log(s.price); // 打印出'iliveyou'
十七、数值的扩展
1.Number.EPSILON
// 我们都知道小数点之间的数值运算是有误差的 例如0.1 + 0.2 = 0.300000004;我们想想中它应该等于0.3 所以两个数的差值的 的绝对值小于最小精度(Number.EPSILON) 我们说0.300000004 等于 0.3吧
const equal = (a, b) => {
if(Math.abs(a-b) < Number.EPSILON) {
return true;
}else{
return false;
}
}
console.log(0.1 + 0.2 === 0.3) // true
console.log(equal(0.1 + 0.2, 0.3))
2.进制
// 二进制
let b = 0b1010;
console.log(b); // 10
// 八进制
let o = 0o777;
console.log(o); // 511
// 十进制
let d = 100;
console.log(d); // 100
// 十六进制
let x = 0xff;
console.log(x);255
3.Number.isFinite 检测一个数是否有限数
console.log(Number.isFinite(100)); // true
console.log(Number.isFinite(100 / 0)); // false
console.log(Number.isFinite(Infinity)); // false
4.Number.isNaN检测一个数值是否为NaN
console.log(Number.isNaN(123)); // false
5.Number.parseInt、 Number.parseFloat
console.log(Number.parseInt('123465ssss')); // 123465
console.log(Number.parseFloat('1.23465ssss嗯嗯')); // 1.23465
6.Number.isInteger判断一个数是否为整数,返回的是布尔值
console.log(Number.isInteger(5)); // true
console.log(Number.isInteger(2.5)); // false
7.Math.trunc 将数字的小数部分抹掉(向下取整)
console.log(Math.trunc(3.5)); // 3
8.Math.sign判断一个数到底为整数、负数、还是零
console.log(Math.sign(100)); // 1
console.log(Math.sign(0)); // 0
console.log(Math.sign(-100)); // -1
十八、ES6对象方法扩展
1.Object.is 判断两个值是否完全相等
console.log(Object.is(120, 120)); // true
console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); // false
2.Object.assign对象的合并等价于 {...Object, ...Object}
const config1 = {
host: 'localhost',
port: 3306,
name: 'root',
pass: 'root',
test: 'test'
};
const config2 = {
host: 'www/sfsd.com',
port: 33060,
name: 'aaa',
pass: 'bbb'
};
// 参数一: 被覆盖 参数二: 覆盖
// 同名就被覆盖 如果不同名就照写下来
Object.assign(config1, config2); // {host: 'www/sfsd.com', port: 33060, name: 'aaa', pass: 'bbb', test: 'test' }
3.Object.setPrototypeOf(参数一, 参数二) 设置原型, 参数二设置为参数一的原型对象;
Object.getPrototyppeOf(参数一) 获取参数一自己的原型对象
const school = {
name: '尚硅谷'
}
const cities = {
xiaoqu: ['北京', '上海']
}
// 设置 cities 为 school的原型对象
Object.setPrototypeOf(school, cities);
console.log(school); // 略
// 获取对象(打印出来的是自己)
console.log(Object.getPrototypeOf(school));
十九、模块化
略 太简单了 写太麻烦 不想写