zoukankan      html  css  js  c++  java
  • JS的类

    JS在创建之初不支持类,因为很多开发者为处理类创建了好多代码库,最终导致ES6引入了类。

    ES5及更早的版本都不支持类,与类最接近的是:创建一个构造器,然后将方法指派到该构造器的原型上。就是原型继承。原型继承的模式在许多JS库中都存在,这也是ES6类的出发点。

    类的声明:

    以class关键字开始,其后是类的名称;剩余部分的语法看起来像是对象字面量中的方法简写,在方法之间不需要使用逗号。栗子如下:

    class personClass{
        constructor(name){
            this.name = name;
        }
        sayName(){
            console.log(this.name);
        }
    }
    let person = new personClass("Miya");
    person.sayName();  //Miya
      console.log(typeof personClass); //function
      console.log(person instanceof personClass); //true
      console.log(typeof personClass.prototype.sayName);  //function
     
      //使用类表达式
      let personClass = class {  ...  }

    class中使用特殊的constructor方法名称直接定义一个构造器,之外的方法名称则没有特别的含义,可以根据需求随意添加。

    personClass声明实际上创建了一个拥有constructor方法及其行为的函数,typeof personClass会得到“function”结果的原因。sayName()方法最终是personClass.prototype上的一个方法。

    为什么要使用类的语法?

    类和自定义类型之间的区别:

    1,类声明不会被提升,类声明的行为与let相似,因此在程序执行到声明处之前,类都会位于暂时性死区。

    2,类声明中的所有代码会自动运行并锁定在严格模式下。

    3,类的所有方法不可枚举。

    4,类的所有方法内部没有constructor,因此使用new来调用类里面的方法会报错。

    5,调用类构造器时不使用new,会报错。

    6,试图在类的方法内部重写类名,会报错。

    使用类表达式的功能等价于类声明。区别就是代码风格问题,就像:函数声明和函数表达式之间的区别。看下面的定义方法:

    let personClass = class personClass2{
        constructor(name){
            this.name = name;
        }
        sayName(){
            console.log(this.name);
        }
    }
      console.log(typeof personClass); //function
    console.log(typeof personClass2); //undefined

    类表达式命名为personClass,personClass2标识符只在类定义内部存在。在类的外部,typeof personClass2的结果为“undefined”,因为在外部不存在personClass2的绑定。其实上面的personClass的定义等价于:

    let personClass = (function(){
        "use strict";
        const personClass2 = function(name){
            if(typeof new.target === "undefined"){
                throw new Error("Constructor must be called with new");
            }
            this.name = name;
        }
        Object.defineProperty(personClass2.prototype,"sayName",{
            value:function(){
                if(typeof new.target !== "undefined"){
                    throw new Error("Method cannot ba called with new.");
                }
                console.log(this.name);
            },
            enumerable:false,
            writable:true,
            configurable:true
        })
        return personClass2;
    })

    在编程中,能被当作值来使用的就称为一等公民(firstt-class citizen),意味着它能作为参数传给函数,能作为函数返回值,能用来给变量赋值。JS的函数就是一等公民(一等函数)。

    ES6的类也是一等公民,使得类可以被多种方式所使用,例如,作为参数传入函数:

    function createObject(classDef){
        return new classDef();
    }
    
    let obj = createObject(class {
        sayHi(){
            console.log("Hi!");
        }
    })
    obj.sayHi();  //Hi!
    

     类表达式的另一个用途是立即调用类构造器,用于创建单例,看下面栗子;

    let person = new class{
        constructor(name){
            this.name = name;
        }
        sayName(){
            console.log(this.name);
        }
    }("miya") 
    console.log(person.sayName())  //miya
    

     此处创建了一个匿名表达式,并立即执行了它。此模式允许你使用类语法来创建单例,从而不留下任何可被探查的类引用,类表达式后面的圆括号表示要调用前面的函数,并且还允许传入参数。

    在类上创建访问器属性(类似于对象字面量):

     自有属性需要在类构造器中创建,类还允许在原型上定义访问器属性。栗子如下:

    class htmlEle{
        constructor(ele){
            this.ele = ele;
        }
        get html(){
            return this.ele.innerHTML;
        }
        set html(value){
            this.ele.innerHTML = value;
        }
    }
    var des = Object.getOwnPropertyDescriptor(htmlEle.prototype, "html");
    console.log("get" in des);  //true
    console.log("set" in des);  //true
    console.log(des.enumerable);  //false

    可计算的成员名:

    类里面的方法,以及访问器属性getter和setter都可以被设置为可计算属性名。

    生成器方法:

    对象的类,其实目的在于让每个实例化后的对象都能共享某些属性。类的实现是基于其原型继承机制的。如果两个实例都从同一个原型对象上面继承了属性,我们就说它们是同一个类的实例。
    JavaScript中类的一个重要特性-----动态可继承。

    定义类是模块开发和重用代码的有效方式之一。一定得掌握的呦!!!

    1,类和原型

    类的所有实例对象都是从同一个原型对象上继承属性。原型对象是类的核心。

    构造函数是类的公共标识。但原型是唯一的标识。

    instanceof运算符检测对象的继承关系,而不是检测创建对象的构造函数。

    在JavaScript中定义类的步骤:1,定义一个构造函数,设置初始化新对象的实例属性,2,给构造函数的prototype对象定义实例的方法。3,给构造函数定义类字段和类属性。

    【续】

     人生最要紧,是活得有趣。  ——梁启超

  • 相关阅读:
    【转】QPainter中坐标系变换问题
    【转】Python3 (入门6) 库的打包与安装
    【转】Python3 操作符重载方法
    【转】Python3 日期时间 相关模块(time(时间) / datatime(日期时间) / calendar(日历))
    正则表达式过滤HTML、JS、CSS
    JavaScript的类型转换
    JavaScript的数据类型,值和变量
    JavaScript介绍
    Ant学习笔记
    GeoServer端口配置
  • 原文地址:https://www.cnblogs.com/tangjiao/p/8990971.html
Copyright © 2011-2022 走看看