文章目录
Set
ES6提供了新的数据结构 set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符...
和for ...of...
进行遍历.
Set声明
格式:let 集合名 = new Set([集合元素1,集合元2素,...])
集合的属性和方法
集合本是也是一个对象,他有属性和方法:
- set.size :获取集合长度
- set.add() : 添加集合元素
- set.delete() : 删除集合元素
- set.has() : 价差集合是否有指定元素
- set.clear() : 清空集合元素
eg:
// 声明一个set
let s = new Set()
let s2 = new Set(['孙悟空','猪八戒','唐僧','沙僧','孙悟空'])
// 可以自动去重
console.log(s2,typeof(s2))
for(var v of s2){
console.log(v)
}
console.log(s2.size)
s2.add('白骨精')
s2.delete('孙悟空')
console.log(s2.has('孙悟空'))
s2.clear()
Set实例
对数组进行操作
let arr = [1,2,3,4,5,4,3,2,1]
// 1.数组去重
//let result = new Set(arr),再使用括号中那运算符转换成数组
let result1 =[...new Set(arr)]
console.log(result1)
// 2.交集
let arr2 =[4,5,6,5,6]
// let result2 = [...new Set(arr)].filter(item=>{
// let s2 = new Set(arr2)
// if(s2.has(item)){
// return true
// // filter如果返回为true就留下item,为false就放弃
// }else{
// return false
// }
// })
// 上述语可以简写为
let result2 =[...new Set(arr)].filter(item=>new Set(arr2).has(item))
console.log(result2)
// 3.并集
let union = [...new Set([...arr,...arr2])]
console.log(union)
// 4.差集(交集的逆运算)
// 在arr中,但不在arr2中
let diff = [...new Set(arr)].filter(item=>!(new Set(arr2).has(item)))
console.log(diff)
Map
ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串
,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用扩展运算符(...
)和 for ...of...
进行遍历。
Map的声明格式
空的map: let 集合名 = new Map()
戴参数的map:let 集合名 = new Map([[键,值],[键,值],...])
Map的属性和方法
- size返回Map 的元素个数
- set增加一个新元素,返回当前Map
- get返回键名对象的键值
- has检测 Map中是否包含某个元素,返回boolean值
- clear清空集合,返回undefined
eg:
let m = new Map()
let m2 = new Map([['name','yang'],['age',18],['sex','M']])
console.log(m2)
m.set('name','孙悟空')
m.set('wuqi',function (){
console.log('我的武器是金箍棒')
})
let key ={
school:'nefu'
}
m.set(key,['北京','上海','深圳'])
console.log(m)
for(let v of m){
console.log(v)
}
console.log(m.size)
m.delete('name')
console.log(m.get('wuqi'))
console.log(m.get(key))
console.log(m.has('wuqi'))
m.clear()
输出:
Class
ES6提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class 关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
class定义格式
class 类名{
// 属性
constructor(参数){
// constructor是固定的,当实例化对象的时候自动调用constructor
属性赋值
}
//方法,不能使用function
方法名(){
方法体
}
}
实例化对象
- 使用ES5创实例化对象:
function Phone(brand,price){
this.brand = brand
this.price = price
}
// 添加方法
Phone.prototype.call = function (){
console.log('我可以打电话')
}
// 实例化对象
let Huawei = new Phone('华为',5999);
Huawei.call()
console.log(Huawei)
输出:
- 使用Class实例化对象
class Phone{
// 构造方法
constructor(brand,price){
// constructor是固定的,当实例化对象的时候1自动调用constructor
this.brand = brand
this.price = price
}
call(){
console.log('我可以打电话')
}
}
let onePlus = new Phone('1+',1999)
onePlus.call()
console.log(onePlus)
输出:
class静态成员
引入
function Phone (){
}
// 添加的是函数属性,实例看不到
Phone.name='手机'
Phone.change = function (){
console.log('我可以改变世界')
}
// 添加的是原型属性,实例可以看到
Phone.prototype.size = '5.5inch'
let nokia = new Phone()
console.log(nokia.name)
nokia.change()
console.log(nokia.size)
发现:
Phone.属性
添加的就是函数属性,实例看不到
Phone.prototype.属性
添加的就是函数原型属性,实例可以看到
实际上就是原型链的原因:
实例指向的是函数的原型对象,而不是函数本身,所以给函数添加的属性实例自然看不到。
换到calss
换到Class中,通过 类.属性
添加的 属性属于类,而不属于实例对象,我们将这类属性称为calss的静态成员。
在Class中可以简化静态变量的定义过程,可以直接给在class中使用static
来标识这是一个静态变量。
class Phone{
// 静态属性
static name ='手机'
static change(){
console.log('我可以改变世界')
}
}
/*等价于
Phone.name = '手机'
Phone.change = function (){
console.log('我可以改变世界')
}*/
let nokia = new Phone()
console.log(nokia.name)
console.log(Phone.name)
Phone.change()
类的继承
ES5实现继承
function Phone (brand,price){
this.brand = brand
this.price = price
}
Phone.prototype.tele = function (){
console.log('我可以打电话')
}
// 智能手机
function SmartPhone (brand,price,color,size){
Phone.call(this,brand,price)
this.color = color
this.size = size
}
// 设置子级构造函数的原型
SmartPhone.prototype = new Phone
SmartPhone.prototype.constructor = SmartPhone
// 声明子类的方法
SmartPhone.prototype.photo = function (){
console.log('我可以拍照')
}
SmartPhone.prototype.playGame = function (){
console.log('我可以玩游戏')
}
const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch')
console.log(chuizi)
输出:
class的继承
继承结构
class 子类 extends 父类{
constructor(参数1,参数2,...){
// 调用父类构造方法
super(参数1,参数2...)
剩余参数的赋值
}
}
eg:
class Phone{
constructor(brand,price){
this.brand = brand
this.price = price
}
// 父类的成员方法
tele(){
console.log("我可以打电话")
}
}
class SmartPhone extends Phone {
constructor(brand,price,color,size){
// 调用父类构造方法
super(brand,price)
this.color = color
this.size = size
}
phone(){
console.log("拍照")
}
playGame(){
console.log("玩游戏")
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch')
xiaomi.tele()
xiaomi.phone()
xiaomi.playGame()
console.log(xiaomi)
重写
子类对父类方法的重写是指子类声明一个和父类同名的方法,将父类的方法进行覆盖
class Phone{
constructor(brand,price){
this.brand = brand
this.price = price
}
// 父类的成员方法
tele(){
console.log("我可以打电话")
}
}
class SmartPhone extends Phone {
constructor(brand,price,color,size){
// 调用父类构造方法
super(brand,price)
this.color = color
this.size = size
}
tele(){
console.log("我可以视频通话")
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch')
xiaomi.tele()
输出:
class的getter和setter的设置
class Phone{
// 没有构造函数是合法的
// 只要读取size属性就会执行get方法
get price(){
console.log("价格属性被读取")
// 该函数的返回值就是属性的值
return 'yang'
}
// 只要给size属性赋值就会执行set方法
set price(newVal){
// set必须有参数
console.log('价格属性被修改了')
}
}
let s=new Phone();
console.log(s.price)
s.price = 'free'
输出:
也可以自己写函数,直接设置get,set函数:
class Phone{
constructor(price,size){
this.price = price
this.size =size
}
setPrice(price){
this.price = price
}
getPrice(){
return this.price
}
}
let s = new Phone(1200,'5.5inch')
console.log(s.getPrice())
s.setPrice(2000)
console.log(s.getPrice())
输出: