ES6&JS高级

学习总结

ES6

一、Symbol

一种新的原始数据类型Symbol,表示独一无二的值;是JS语言的第七种数据类型,是一种类似于字符串的数据类型

Symbol特点

1)Symbol的值是唯一的,用来解决命名冲突的问题
2)Symbol值不能与其他数据进行运算
3)Symbol定义的对象属性不能使用for…in 循环遍历,但可以使用Reflect.ownKeys来获取对象的所有键名

创建Symbol
//创建Symbol
let s = Symbol();
console.log(s,typeof s)//Symbol(),Symbol
let s2 = Symbol('tjc')
let s3 = Symbol('tjc')
console.log(s2 === s3)//false
//Symbol.for创建
let s4 = Symbol.for('tjc');
let s5 = Symbol.for('tjc');
console.log(s4 === s5)//true
Symbol 给对象添加属性和方法
let game = {...}

let methods = {
  up:Symbol(),
  down:Symbol()
}
game[methods.up] = function(){
  console.log("我可以改变形状");
}
game[methods.down] = function(){
  console.log("我可以快速下降");
}
console.log(game)

let youxi = {
  name:"狼人杀"
  [Symbol('say')]: function(){
  console.log("我可以发言")
  }
}
Symbol内置属性

在这里插入图片描述

Symbol.hasInstance

当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法

class Person{
  static [Symbol.hasInstance](param){
    console.log(param)
    console.log("我被用来检测类型了")
    return false
  }
}
let o = {}
console.log(o instanceof Person)
Symbol.isConcatSpreadable

对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开

const arr = [1,2,3]
const arr2 = [4,5,6]
arr2[Symbol.isConcatSpreadable] = false
console.log(arr.concat(arr2))

二、迭代器

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口就可以完成遍历操作。

1)ES6 创造了一种新的遍历命令 for…of循环,lterator 接口主要供 for…of消费
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧']
//使用for...of遍历数组
for(let v of xiyou){
  console.log(v)
}
for(let v in xiyou){
  console.log(v)
}
//for...in循环,保存键名
//for...of循环,保存键值

在这里插入图片描述

2)原生具备iterator 接口的数据(可用 for of 遍历)

a)Array
b)Arguments
c)Set
d)Map
e)String
f)TypedArray
g)NodeList

3)工作原理

a)创建一个指针对象,指向当前数据结构的起始位置
b)第一次调用对象的next方法,指针自动指向数据结构的第一个成员
c)接下来不断调用 next方法,指针一直往后移动,直到指向最后一个成员
d)每调用next方法返回一个包含value和done属性的对象

const xiyou = ['唐僧','孙悟空','猪八戒','沙僧']
let iterator = xiyou[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

在这里插入图片描述
*注:需要自定义遍历数据的时候,要想到迭代器

const banji = {
  name: "终极一班",
  stus: [
    'xiaoming',
    'xiaoning',
    'xiaotian',
    'knight'
  ],
  [Symbol.iterator]() {
    //索引变量
    let index = 0;
    let _this = this;
    return {
      next: function () {
        if (index < _this.stus.length) {
          const result = { value: _this.stus[index], done: false };
          index++;
          return result;
        }else{
          return{value:undefined,done:true}
        }
      }
    };
  }
}
for (let v of banji) {
  console.log(v);
}

在这里插入图片描述

三、生成器

一个特殊的函数
异步操作 (纯回调函数 node fs ajax mongodb)
函数代码的分隔符 yield

function * gen(){
  console.log("hello tjc")
}
let iterator = gen();
iterator.next();


function * gen(){
  console.log(111)
  yield 'tjc';
  console.log(222)
  yield 'xth';
  console.log(333)
  yield 'happy birthday';
  console.log(444)
}
// let iterator = gen();
// iterator.next();
// iterator.next();
// iterator.next();
// iterator.next();
for(let v of gen()){
  console.log(v)
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

生成器函数参数

next方法可以传入实参

function * gen(arg){
  console.log(arg)
  let one = yield 'tjc';
  console.log(one)
  let two = yield 'xth';
  console.log(two)
  let three = yield 'happy birthday';
  console.log(three)
}
let iterator = gen('AAA');
console.log(iterator.next());
//next方法可以传入实参
console.log(iterator.next('888'));
console.log(iterator.next('CCC'));
console.log(iterator.next('DDD'));

在这里插入图片描述
*有此特性做支撑,异步编程参数传递就能够实现了

实例

异步编程 文件操作 网络操作(ajax,request) 数据库操作

1.要求:1s后控制台输出111,2s后输出222
function one(){
  setTimeout(()=>{
    console.log(111)
    iterator.next();
  },1000)
}
function two(){
  setTimeout(()=>{
    console.log(222)
    iterator.next();
  },1000)
}
function three(){
  setTimeout(()=>{
    console.log(333)
    iterator.next();
  },1000)
}
function * gen(){
  yield one();
  yield two();
  yield three();
};
let iterator = gen();
iterator.next();
2.要求:模拟获取 用户数据 订单数据 商品数据
function getUsers(){
  setTimeout(()=>{
    let data = '用户数据'
    //调用next方法,并且将数据传入
    iterator.next(data)
  },1000)
}

function getOrders(){
  setTimeout(()=>{
    let data = '订单数据'
    iterator.next(data)
  },1000)
}

function getGoods(){
  setTimeout(()=>{
    let data = '商品数据'
    iterator.next(data)
  },1000)
}

function * gen(){
  let users= yield getUsers();
  console.log(users)
  let orders = yield getOrders();
  console.log(orders)
  let goods = yield getGoods();
  console.log(goods)
};
let iterator = gen();
iterator.next();

四、Set(集合)

ES6 提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator 接口,所以可以使用「扩展运算符」和「for…of…」进行遍历;Set内的数组会自动去重

集合的属性和方法:

1)size 返回集合的元素个数
2)add 增加一个新元素,返回当前集合
3)delete 删除元素,返回 boolean 值
4)has 检测集合中是否包含某个元素,返回boolean值

//声明一个Set
let s = new Set();
let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);
//元素个数
console.log(s2.size);
//添加新元素
s2.add('喜事儿');
//删除元素
s2.delete('坏事儿')
console.log(s2)
//检测
console.log(s2.has('好事儿'))
for(let v of s2){
  console.log(v)
}
//清空
s2.clear();
console.log(s2)

在这里插入图片描述

集合实践
let arr = [1,2,3,4,5,,4,3,2,1]
1.数组去重
//1.数组去重
let result = [...new Set(arr)]
console.log(result)
2.交集
//2.交集
let arr2 = [4,5,6,5,6]

  //复杂写法
let result = [...new Set(arr)].filter(item => {
  let s2 = new Set(arr2)
  if(s2.has(item)){
    return true
  }else{
    return false
  }
});
console.log(result)

  //简单写法
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item))
console.log(result)
3.并集
//3.并集
let union = [...new Set([...arr,...arr2])]
console.log(union)
4.差集
//4.差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)))
console.log(result)

五、Map

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了 iterator 接口所以可以使用『扩展运算符』和『for…f…』进行遍历。

Map的属性和方法:

1)size 返回 Map 的元素个数
2)set 增加一个新元素,返回当前 Map
3)get 返回键名对象的键值
4)has 检测Map中是否包含某个元素,返回boolean 值
5)clear 清空集合,返回 undefined

//声明Map
let m = new Map();

//添加元素
m.set('name','尚硅谷')
m.set('change',function(){
  console.log("我们可以改变你!!")
})
let key = {
  school : 'ATGUIGU'
}
m.set(key,['北京','上海','深圳'])

//size
console.log(m.size)

//删除
m.delete('name')

//获取
console.log(m.get('change'))
console.log(m.get(key))

//遍历
for(let v of m){
  console.log(v)
}

//清空
m.clear()
console.log(m)

在这里插入图片描述

六、class类

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,S6的class 可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

1)class声明类
2)constructor 定义构造函数初始化

constructor() 方法,这就是构造方法,而this关键字则代表实例对象

class Phone {
  //构造方法,名字不能修改constructor()
  constructor(brand, price) {
    this.brand = brand;
    this.price = price;
  }
  //方法必须使用该语法,不能使用ES6的对象完整形式
  call() {
    console.log("我可以打电话")
  }
}
//实例化对象
let onePlus = new Phone("1+",1999)
console.log(onePlus)

constructor()方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加。

3)extends 继承父类
class Phone {
  //构造方法,名字不能修改constructor()
  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
  }

  photo(){
    console.log("拍照")
  }

  playGame(){
    console.log("玩游戏")
  }
}

const xiaomi = new SmartPhone('小米',779,'黑色','4.7inch')
xiaomi.call();
xiaomi.photo()
xiaomi.playGame()

在这里插入图片描述
prototype:它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象。
prototype属性的作用:就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。

class Point {
  constructor() {
    // ...
  }

  toString() {
    // ...
  }

  toValue() {
    // ...
  }
}

// 等同于

Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

上面代码中,constructor()、toString()、toValue()这三个方法,其实都是定义在Point.prototype上面。
4)super 调用父级构造方法
5)static 定义静态方法和属性(属于类不属于实例对象)
6)父类方法可以重写

class Phone {
  //构造方法,名字不能修改constructor()
  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
  }

  photo(){
    console.log("拍照")
  }

  playGame(){
    console.log("玩游戏")
  }
//重写部分
  call(){
    console.log("我可以拨打视频通话")
  }
}

const xiaomi = new SmartPhone('小米',779,'黑色','4.7inch')
xiaomi.call();
xiaomi.photo()
xiaomi.playGame()
对象方法

1.Object.assign()方法可以很方便地一次向类添加多个方法。

class Point {
  constructor(){
    // ...
  }
}

Object.assign(Point.prototype, {
  toString(){},
  toValue(){}
});

2.Object.is()判断两个值是否相等
3.Object.setPrototypeof()设置原型对象

七、其他

1.箭头函数

箭头函数适合与this无关的问题,定时器,数组的方法回调
箭头函数不适合与this有关的回调,事件回调,对象的方法

特性:

1.this是静态的,this始终指向函数声明时所在作用域下的this的值
2.不能作为构造实例化对象
3.不能使用 arguments 变量
(类数组对象:arguments;是一个特殊的对象,它的属性名是按照传入参数的序列来的,第1个参数的属性名是’0’,第2个参数的属性名是’1’,以此类推,并且它还有length属性,存储的是当前传入函数参数的个数,很多时候我们把这种对象叫做类数组对象)
4.箭头函数的简写
1)省略的小括号,当形参有且只有一个的时候

let add = n => {
  return n + n;
}
console.log(add(9))

2)省略花括号,当代码体只有一条语句的时候,此时return必须省略,而且语句执行结果就是函数的返回值

let pow = n => n*n
console.log(pow(8))
2.ES6允许给函数参数赋值初始值

1.形参初始值,具有默认值的参数,一般位置要靠后(潜规则)
2.与解构赋值结合

function connect({host="127.0.0.1",username,password,port}){
  console.log(host)
  console.log(username)
  console.log(password)
  console.log(port)
}
connet({
  host: 'mq.com',
  username:'root',
  password:'root',
  port:1005
})
3.rest参数

用于获取函数的实参,用来代替arguments
rest参数必须放在参数最后

function date(...args){
  console.log(args);
}
date('檀健次','檀小呆','弹力球')

返回的为数组
在这里插入图片描述

4.扩展运算符[…]

能将[数组]转换为逗号分隔的参数序列

//声明一个数组
const tjc = ['檀健次','沈翊','莫青成']
//声明一个函数
function chunwan(){
  console.log(arguments)
}
chunwan(tjc);
chunwan(...tjc);

在这里插入图片描述

5.应用
1)数组的合并
const kuaizi = ['王太利','肖央']
const fenghuang = ['曾毅','玲花']
const zuixuanxiaopingguo = [...kuaizi,...fenghuang]
console.loe(zuixuanxiaopingguo)
2)数组的克隆
const sanzhihua = ['E','G','M']
const sanyecao = [...sanzhihua]
console.log(sanyecao)
3)将伪数组转为真正的数组
const divs = document.querySelectorAll('div')
const divArr = [...divs]
console.log(divArr)
6.模块化

优点:
1)防止命名冲突
2)代码复用
3)高维护性

JS高级

一、原型与原型链

原型Prototype

默认指向一个Object空对象(即称为:原型对象)
原型对象中有一个属性constructor,他指向函数对象
给原型对象添加属性(一般都是方法),作用:函数的所有实例对象自动拥有原型中的属性(方法)

//每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象)
console.log(Date.prototype,typeof Date.prototype)
function Fun(){

}
console.log(Fun.prototype)//默认指向一个Object空对象

//原型对象中有一个属性constructor,它指向函数对象
console.log(Date.prototype.constructor === Date)
console.log(Fun.prototype.constructor === Fun)
//给原型对象添加属性(一般是方法) ====> 实例对象可以访问
Fun.prototype.test = function(){
  console.log('test()')
}
var fun = new Fun()
fun.test()

在这里插入图片描述

显示原型&隐式原型

一句话解释,函数里面有个prototype属性指向原型对象,实例化对象里面有个__proto__属性他也指向原型对象,且与构造函数的原型对象是同一个,然后原型对象里面有个constructor属性他指向的是构造函数

显示原型(prototype)

定义函数时自动添加的,默认值是一个空Object

隐式原型(proto

创建对象时自动添加的,默认值为构造函数的prototype属性值
对象的隐式原型的值为其对应构造函数的显示原型的值
在这里插入图片描述

*原型链(隐式)

访问一个对象属性时,先在自身属性中查找,找到返回;如果没有,再沿着__proto__这条链向上查找,找到后返回;如果最终没找到,返回undefined
作用:查照对象的属性(方法)
在这里插入图片描述

构造函数/原型/实例对象的关系(图解)

在这里插入图片描述

构造函数/原型/实例对象的关系2(图解)

在这里插入图片描述

补充知识

1.函数的显示原型指向的对象默认是空Object实例对象(但Object不满足)
2.所有函数都是Function的实例(包含Function)
3.Object的原型对象是原型链的尽头

function Fn(){
  this.test1 = function(){
    console.log('test1')
  }
}
console.log(Fn.prototype)
Fn.prototype.test2 = function(){
  console.log('test2')
}

var fn = new Fn()
fn.test1()
fn.test2()
console.log(fn.toString)

// 1.函数的显示原型指向的对象默认是空Object实例对象(但Object不满足)
console.log(Fn.prototype instanceof Object) //true
console.log(Object.prototype instanceof Object) //false
console.log(Function.prototype instanceof Object) //true

//2.所有函数都是Function的实例(包含Function)
console.log(Function.__proto__ === Function.prototype)  //true

// 3.Object的原型对象是原型链的尽头
console.log(Object.prototype.__proto__) //null
原型链属性问题

1.读取对象的属性值时,会自动到原型链中查找
2.设置对象的属性值时,不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值
3.方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

function Fn(){

}
Fn.prototype.a = 'XXX'
var fn1 = new Fn()
console.log(fn1.a,fn1)

var fn2 = new Fn()
fn2.a = 'YYY'
console.log(fn1.a,fn2.a,fn2)

在这里插入图片描述

function Fn(){

}
Fn.prototype.a = 'XXX'
var fn1 = new Fn()
console.log(fn1.a,fn1)

var fn2 = new Fn()
fn2.a = 'YYY'
console.log(fn1.a,fn2.a,fn2)

function Person(name,age){
  this.name = name
  this.age = age
}
Person.prototype.setName = function(name){
  this.name = name
}
var p1 = new Person('Tom',12)
p1.setName('Bob')
console.log(p1)

var p2 = new Person('Jack',12)
p2.setName('Cat')
console.log(p2)
console.log(p1.__proto__ === p2.__proto__)

在这里插入图片描述

二、instanceof

表达式:A(实例对象) instanceof B(构造函数)
如果B函数的显示原型对象在A原型链上,返回true,否则返回false
在这里插入图片描述

//案例1
function Foo(){

}
var f1 = new Foo()
console.log(f1 instanceof Foo)   //true
console.log(f1 instanceof Object)    //true



//案例2
console.log(Object instanceof Function)    //true
console.log(Object instanceof Object)    //true
console.log(Function instanceof Function)   //true
console.log(Function instanceof Object)    //true

function Foo(){

}
console.log(Object instanceof Foo)    //false

(未完待续 . . . )

下周计划

复习ES6,继续学习JS高级,复习Java与高数,继续写算法题

生活碎片

河科院湖边夜景

和然然去逛街
在这里插入图片描述
和然然去吃饭
在这里插入图片描述
还是和然然去吃饭
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值