ES6-day03

简介: ES6-day03

ES6-类-Symbol

1.类

javascript语言中,生成实例对象使用构造函数;ES6提供了类Class这个概念,作为对象的模板。定义一个类通过class关键字,ES6的类可以看成是构造函数的另一种写法。

ES5 如何继承
实例使用属性和方法
  1.从实例对象本身查找属性或者方法
  2.如果实例没有,从构造函数的原型对象中找
  3.如果还没有,从父构造函数的原型对象中找



function Person(){}
Person.prototype={};
var p1=new Person();
p1.sayName=function(){};
p1.sayName(); //p1去调用sayName,自身有访问自身,自身没有访问构造函数原型对象,构造函数原型对象没有去找父构造函数
1.经典继承
function Animal(type,age,weight,length){
    this.type=type;
    this.age=age;
    this.weight=weight;
    this.length=length
}
Animal.prototype={
    constructor:Animal,
    sayType:function(){
        console.log(this.type)
    }
}
function Dog(type,age,weight,length,name,color){
        // 经典继承又称为构造函数继承
        Animal.call(this,type,age,weight,length);
        this.name=name;
        this.color=color;
}
处理完构造函数处理原型对象
2.//原型链继承
Dog.prototype=new Animal();
Dog.prototype.constructor=Dog;
Dog.prototype.sayColor=function(){
    console.log(this.color)
}
var d1=new Dog('狗',1,'10kg','40cm','可乐','白色');
console.log(d1);
d1.sayType();
d1.sayColor();
ES6
1.如何定义一个类
class Person{
    constructor(name,age){
        this.name=name;
        this.age=age
  }
    sayName(){ //--类似于存在类的原型对象中
        console.log(this.name)
    }
}
2.constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。通过static关键字来定义静态属性和静态方法。
class Person{   }      =>         class Person{
                                    constructor(){}
                                  }
3.定义在类体的方法称为实例方法,其实是存在于Person.prototype中,可供所有的实例调用。
class Person{
    constructor(name,age){
        this.name=name;
        his.age=age
  }
    sayName(){ //---  其实可以理解为存在于Person.prototype中
        console.log(this.name)
    }
}
4.静态方法
  通过static关键字来定义静态属性和静态方法。也可以在外侧添加静态属性;静态属性和静态方法是定义在类【构造函数】上的,所以可以通过类【构造函数】直接访问。在静态方法中,this指向当前类【构造函数】
  class Person{
        //静态属性是构造函数私有属性 并不是公共属性
        static test=['hello'];//可以是引用数据类型
    static test1='hello';//可以是基本数据类型
    test3=[];---实例私有属性
    //静态方法
    static sayName(){
            return this.test3
        }
    }
class Person{
    //构造器 默认有一个,可以显式提供
    constructor(name,age){
        // 实例的私有属性
        this.name=name;
        this.age=age;
    }
    test=['hello']
    // 实例的方法 原型对象中的方法
    sayName(){
        console.log(this.name)
    }
    // 静态方法
    static sayType(p){
        return p instanceof Person
    }
  //静态属性
    static gende='男'
};
let p=new Person('zhangsan',12);
let p2=new Person({});
p.test.push('tom')
console.log(p,p2);//维护的是私有属性 创建的是不同子类构造函数对象
p.sayName();
console.log(Person.sayType(p));//静态方法由类去调用
console.log(p.test===p2.test);//私有属性不相同
console.log(p.sayName===p2.sayName)//存放在原型对象中的是同一个方法
实例方法和实例属性写在哪
  实例可以调用的方法和属性
静态方法和静态属性写在哪
  类本身调用的方法和属性

2.继承

class可以通过extends关键字实现继承,子类可以没有构造函数,系统会默认分配。子类提供了构造函数则必须要显式调用super。super函数类似于借用构造函数。类似于Animal.call()

1.子类对象指向父类对象

2.子类原型对象继承父类原型对象

class Animal{
    // 静态属性
    static animalAttr='Animal的静态属性';
    constructor(name,age,weight){
        this.name=name;
        this.age=age;
        this.weight=weight;
    }
    // 实例方法
    sayName(){
        console.log('实例方法')
    }
    // 静态方法
    static animalmethod(){
        console.log('Animal静态方法')
    }
}
// 要实现继承
class Dog extends Animal{
    constructor(name,age,weight,color){
        super(name,age,weight);
        this.color=color;
        console.log('Dog的构造器')
    }
}
let dog=new Dog('豆豆',1,10,'golden');
// 继承 子类的原型对象继承父类的原型对象
dog.sayName();
// 继承 子类的对象通过__proto__指针指向父类的对象
Dog.animalmethod();
console.log(Dog.animalAttr);
console.log(Dog.__proto__===Animal);
console.log(Dog.prototype.__proto__===Animal.prototype)

3.Symbol

ES6引入的一种新的原始数据类型Symbol,表示独一无二的值。Symbol函数可以接受参数,表示对于这个唯一值的描述。属于基本数据类型,Symbol()函数会返回symbol类型的值

// 创建symbol值
let  sy1=Symbol('hello');
let  sy2=Symbol();
console.log(sy1==sy2);
###1. 为了解决冲突
let obj={
    name:'zhangsan',
    age:12
}
// 新增属性 修改属性
let sy3=Symbol('name');
let obj1={
    ...obj,
    // 属性名是变量名时使用中括号
    [sy3]:"myname"
}
console.log(obj1)
案例:
let sy1=Symbol('age');
let sy2=Symbol('name');
let obj={
  name:"zhangsan",
  age:12,
  [sy1]:'myname',
  [sy2]:'myage',
  [Symbol('email')]:'kangjie@briup.com'
}
for(let key in obj){
  console.log(key);
}
let ss=Object.getOwnPropertySymbols(obj);
console.log(obj[ss[2]]);
### 2.消除魔术字符串
 魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
function test(shape,options){
  let area=0;
  switch(shape){
    case Shape.SJX:
      area=.5 * options.width*options.height
      break;
    case Shape.ZFX:
      area=options.width*options.height
      break;
    case Shape.CIRCLE:
      area=Math.PI*Math.pow(options.r,2)
      break;
    default:
      area=-1     
  }
  return area
}
let Shape={
  SJX:Symbol('sjx'),
  ZFX:Symbol('zfx'),
  CIRCLE:Symbol('circle')
}
let res=test(Shape.SJX,{width:100,height:100,r:100});
console.log(res);
### 3.全局注册表
Symbol() 不同的是,用 Symbol.for() 方法创建的的 symbol 会被放入一个全局 symbol 注册表中。Symbol.for() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了。假如是,则会直接返回上次存储的那个。否则,它会再新建一个。
// 将symbol放到全局注册表中
let sy1=Symbol.for('hello');
// 从全局注册表中找到该key对应的value
let sy2=Symbol.for('hello');
console.log(sy1===sy2);//true
// 每次都会创建一个不同symbol值  虽然描述符一样 但是Symbol value值不一样
let sy3=Symbol('hello');
let sy4=Symbol('hello');
console.log(sy3==sy4);//false
Symbol.keyFor()
// Symbol.keyFor()可以检测symbol值是否在全局注册表中注册过。 返回对于symbol的描述或者undefined
let sy1=Symbol.for('hello');
console.log(Symbol.keyFor(sy1));
let sy2=Symbol('world');
console.log(Symbol.keyFor(sy2))

1.迭代器

迭代器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)

Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费。

Iterator 的遍历过程是这样的。

  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。
1.迭代器实现了Iterator接口,只要有实现了Iterator就可以使用for-of遍历
let arr=[1,2,3,4,5];
console.log(arr.keys());
console.log(arr.values());
console.log(arr.entries());
// keys values entries 当前变量是迭代器对象
// 迭代器对象实现了Iterator接口,只要实现了迭代接口就可以使用for-of 遍历
// let [a,b]=10; 报错10 is not iterable
let str='hello'; //实现了迭代器接口,可以遍历
// console.log(a,b);
for(let key of str){
    console.log(key)
}
// 以前遍历字符串
let [...a]=str;
console.log(a)
let result=str.split("")
console.log(result);
for(i=0;i<str.length;i++){
    console.log(str.charAt(i))
}
遍历迭代器对象
let keys=arr.keys()
for(let key of keys){
    console.log(key)
}
let values=arr.values();
for(let value of values){
    console.log(value,'--------')
}
let entries=arr.entries();
for(let entry of entries){
    console.log(entry)
}
while(!(result=keys.next()).done){
    console.log(result)
}
for-of实现原理就是调用迭代器的next()方法,第一次调用将指针指向数据结构的第一个成员,依次调用依次指向,直到没有成员可以指向,done为true
  迭代过程:创建一个指针对象,指向当前的数据结构起始位置;
      第一次调用指针对象的next方法,指向数据结构的第一个成员;
            第二次调用指针对象的next方法,指向数据结构的第二个成员;
      直到done为true,指向数据结构的结束位置;
let keys=arr.keys();
let values=arr.values();
let entries=arr.entries()
console.log(keys.next())
console.log(keys.next())
console.log(keys.next())
console.log(keys.next())
console.log(keys.next())
console.log(keys.next())
console.log(entries.next())
原生具备 Iterator 接口的数据结构如下
  Array、Map、Set、String、TypedArray、arguments、NodeList 

2.Set

Set类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。Set 构造函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。

Set API
var set=new Set()
//创建Set集合 成员是唯一的,key-value是一样的
//添加元素
set.add('hello');
set.add('world');
set.add('world');
console.log(set);
// 删除元素
set.delete('hello');
console.log(set);
// 遍历
let keys=set.keys()
let values=set.values()
let entries=set.entries();
console.log(keys,values,entries);
set.forEach((value)=>{
    console.log(value)
})
//判断有没有某个成员
set.has('hello');返回布尔值true或者false
//清空set
set.clear();
//返回set成员个数
set.size
------------------------------------------------
set应用 set构造函数可以接受数组或者其他可遍历的数据结构
let set=new Set([1,2,3,4,1,2,3,4]);
console.log(set);
//数组去重 
let arr=[1,2,3,5,3,2];
let result=new Set(arr);
console.log(result);
//将字符串转换为数组
let [...arr1]='hello';
//将set集合转换为数组
let [...arr2]=result;
console.log(arr2);
console.log([...new Set(arr)])
let s = new Set();
s.add([1]);
s.add([1]);
console.log(s);
console.log(s.size);

3.Map集合

Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。Map 可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

let obj={
    name:"zhangsan",
    age:12
}
//遍历键值对组成的数组
let arr=Object.entries(obj);
console.log(arr);
//将数组作为参数放到Map中
let map=new Map(arr)
console.log(map);
// 添加元素
map.set('1','1');
console.log(map);
// 删除元素
map.delete('name');
console.log(map);
// 获取元素
console.log(map.get('age'));
// 遍历
let keys=map.keys()
let values=map.values()
let entries=map.entries();
console.log(keys,values,entries);
map.forEach((value,key)=>{
    console.log(value,key)
})

Map
Object
意外的键 Map 默认情况不包含任何键。只包含显式插入的键。 一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
键的类型 一个 Map的键可以是任意值,包括函数、对象或任意基本类型。 一个Object 的键必须是一个 String 或是Symbol。
键的顺序 Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。 一个 Object 的键是无序的。注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。
Size Map 的键值对个数可以轻易地通过size 属性获取 Object 的键值对个数只能手动计算
迭代 Map 是 iterable 的,所以可以直接被迭代。 迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能 在频繁增删键值对的场景下表现更好。 在频繁添加和删除键值对的场景下未作出优化。

4.数值扩展

Number.isFinite(), Number.isNaN()

与isFinite、isNaN不同,这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false

    Number.isFinite(0.8); // true
    Number.isFinite(NaN); // false
    Number.isFinite(Infinity); // false
    Number.isNaN(NaN) // true
    Number.isNaN(15) // false

Number.parseInt(), Number.parseFloat()

ES6 将全局方法parseInt()parseFloat(),移植到Number对象上面,行为完全保持不变。

Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45

Number.isInteger()

Number.isInteger()用来判断一个数值是否为整数。

Number.isInteger(25) // true
Number.isInteger(25.1) // false

async异步函数

async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。

await关键字只在async函数内有效。如果你在async函数体之外使用它,就会抛出语法错误 SyntaxError 。async/await的目的为了简化使用基于promise的API时所需的语法。async/await的行为就好像搭配使用了生成器和promise。async函数一定会返回一个promise对象。如果一个async函数的返回值看起来不是promise,那么它将会被隐式地包装在一个promise中。

简单来说 是一个函数,是一个异步编程解决方案,内部封装了generator函数,是一个语法糖,内部自带执行器,与await配合使用;异步编程,同步处理;

async function loadArticle() {
      try {
        let res = await axios.get('http://122.199.0.35:8888/index/category/findAll')
        console.log(res.data.data);
      } catch(error) {
        throw new Error('请求失败');
      } finally {
        console.log('最终执行');
      }
    }
loadArticle()
forEach、for in、for of三者区别
forEach更多的用来遍历数组
for in 一般常用来遍历对象或数组
for of遍历实现了迭代器接口的对象,遍历对象需要通过Object.keys()


目录
相关文章
|
1天前
|
存储 JavaScript 前端开发
什么是Es6,有什么特点
什么是Es6,有什么特点
10 1
|
25天前
|
前端开发
关于es6
关于es6
8 0
|
2月前
|
JSON JavaScript 前端开发
浅谈ES5与ES6
浅谈ES5与ES6
35 3
|
前端开发 索引
ES7,ES8
ES7,ES8
62 0
|
网络架构 索引
ES6(一)
- 使用let,声明的变量仅在块级作用域内有效 - var命令声明的,在全局范围内都有效 - const声明一个只读的常量。一旦声明,常量的值就不能改变。 - const的作用域与let命令相同:只在声明所在的块级作用域内有效。 - let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。 - let不允许在相同作用域内,重复声明同一个变量。 - 什么时候用 let,什么使用用 const——如果不知道用什么的时候,就用 const
52 0
|
前端开发 容器
ES6 Day04
ES6 Day04
76 0
|
前端开发 Java 网络架构
ES6(总结)
ES6(总结)
68 0
初学es6
初学es6
75 0
|
JavaScript 前端开发 Java
【ES6】初识
【ES6】初识
|
JavaScript 前端开发 Java
ES6+
ES6+
161 0