web思维进阶 & 类及模块化应用

156 阅读3分钟

知识点概要

  • ES6中类的使用
    • 类的书写实现方式
    • 公有私有属性
    • 静态成员
      • eg:面试题(单例模式)
    • 访问器属性
    • 继承
    • 抽象类
      • 小试牛刀面试题
      • 如何实现链式调用?
      • __proto__prototype之间有什么关系?
  • ES6中继承extends、super
  • ES6静态方法和属性
  • ES6中模块化import、export

一、类的书写实现方式

  • ES5
//ES5通过构造函数来模拟一个类,
//使其拥有一些类的特性,
//其本质上还是一个函数
function Person(name){
    this.name = name;
    this.height = "180cm";
    this.age = 18;
    //this指向实例化的对象
}

//通过实例化得到一个对象
const zhangsan = new Person("张三");
const wangwu = new Person("王五");

//方法
Person.prototype.fn = function(){
    console.log("fn");
}
  • ES6 class语法糖
//ES6只是用class语法糖来书写实现一个类,
//使其写法更加优雅更能区别其是一个类,
//本质上还是使用的ES5构造函数类似的方法来实现
class Person{
    constructor(name){
        this.name = name;
        this.height = "180cm";
        this.age = 18;
    }
    //方法 自动挂载到类的原型上
    fn(){
        console.log("fn");
    }
}

//通过实例化得到一个对象
const zhangsan = new Person("张三");
const wangwu = new Person("王五");

二、公有私有属性

//ES5
//ES5中不存在私有共有属性概念,
//在ES5中实现私有属性通常通过函数作用域将变量声明在函数内部来模拟私有属性使其不被外部访问到
function Person(name){
    this.name = name;
    const _weight = "60kg";
    //_weight就是模拟的一个私有属性
}

//ES2020 # 修饰符
class Person{
    constructor(name){
        this.name = name;//默认公有属性
    }
    #weight = “60kg”;
    //#weight 就是一个私有属性
    //输出实例化的对象仍可以看到这个属性,但是无法获取该属性
}

三、静态成员

//静态成员支和类有关而和实例化出来的对象无关的属性方法成员

//ES5
function Person(name){
    this.name = name;
}
Person.age = 18;

//ES6
class Person{
    constructor(name){
        this.name = name;
    }
    static age = 10;
    //使用ES6新特性static关键字修饰
}
Person.age = 18;//亦可使用



  • eg:面试题(单例模式) :要求一个类只能有一个实例。
class Person{
    static instance;
    constructor(name){
        if(!instance){
            instance = this;
        }else{
            return instance
        }
        this.name = name;
    }
}
const zhangsan = new Person("张三");
const lisi = new Person("李四");
//输出查看lisi对象还是实例化的第一个对象zhangsan

四、访问器属性

class Person{
    constructor(){
    }
    get name(){
        return "张三"
    }
    set name(newVal){
        name = newVal
    }
}
const a = new Person();
a.name //该操作会触发get操作
a.name = "李四" //该操作会触发set操作

五、继承

  • ES5
function Dad(){
    this.name = "张三"this.age = 18;
}
function Son(){
    Dad.call(this)
}
  • ES6 extends
class Dad(){
    constructor(){
        this.name = "张三"this.age = 18;
    }
    fn(){
        console.log("fn")
    }
}
class Son extends Dad(){
    constructor(){
       super()
       //super 只存在于子类中
    }
    test(){
       super.fn();
       //super关键字可以调用父类的方法
    }
}

六、抽象类

class AbstractPerson{
  constructor(){
      //new.target 可以判断当前需要实例化的对象指向哪个类
      if(new.target===AbstractPerson){
          throw new Error("AbstractPerson抽象类不可被实例化")
      }
      this.age = 18;
    }
}
const ap = new AbstractPerson()
  • 1.小贤是一题喔可爱的小狗(Dog),它叫的很好听(wow),每次看到主人的时候都会乖乖的叫一声(yelp),从这里可以得到以下对象:
class Dog(){
    wow(){
        console.log("wow")
    }
    yelp(){
        this.wow()
    }
}
//小芒和小贤一样,原来也是一条可爱的小狗,
//可是有一天突然疯了(MadDog),一看到人就会每隔半秒不停的叫(yelp),
//请根据描述,按示例的形式用代码来实现。
//题解:继承、原型、setInterval
class MadDog(){
    yelp(){
        setInterval(()=>this.wow(),500)
    }
}
const xiaomang = new MadDog()
xiaomang.yelp()
  • 2.如何实现链式调用?
//1. 返还 this
class Person(){
    fn(){
        console.log("fn")
        return this
    }
}

//2. 返还实例化对象
class Person(){
    fn(){
        console.log("fn")
        return new Person()
    }
}
  • 3.__proto__prototype 之间有什么关系?

    • __proto__是每个对象都有的属性,prototype是函数才有的属性
    • 用法:
      • prototype属性可以给函数和对象添加可共享(继承)的方法、属性
      • __proto__是查找某函数或对象的原型链方式
    • 联系:
      • prototype__proto__都指向原型对象,任意一个函数都有一个prototype属性,指向该函数的原型对象,同样任意一个构造函数实例化的对象,都有一个__proto__属性同样指向该函数的原型对象。
    • prototype构造函数访问原型对象,__proto__对象实例访问原型对象