比特微 VBA jsp cocoa sed process flexbox NEJ vue绑定class vue前端框架 后台模板 java设计模式视频 jq选择子元素 oracle显示所有数据库 安卓小程序源码 edate函数的使用方法 mysql事务 python随机函数 python高级教程 python学习文档 python编程工具 python正则匹配空格 python安装模块 java编程实例 java的substring java中继承 java开发者 java安装步骤 java文件删除 java读取文本 linux用户 python网站开发实例 千元以下最好的手机 popen 蒙文字体 深入浅出通信原理 cms教程 原创检测工具 unity3d中文版 jsp源码
当前位置: 首页 > 学习教程  > 编程语言

ES6 class关键字 ~ 非常详细

2020/12/28 19:37:06 文章标签:

下面的对ES6中class关键字的整理,希望可以帮助到有需要的小伙伴~ 文章目录类的声明构造函数getter与setter不允许提前声明不允许重复声明静态方法静态方法的语法类的继承实现类的继承继承于内置对象Super关键字类的实例传统面向对象是基于类的面向对象,类…

下面的对ES6中class关键字的整理,希望可以帮助到有需要的小伙伴~

文章目录

    • 类的声明
      • 构造函数
      • getter与setter
      • 不允许提前声明
      • 不允许重复声明
    • 静态方法
      • 静态方法的语法
    • 类的继承
      • 实现类的继承
      • 继承于内置对象
      • Super关键字
    • 类的实例

传统面向对象是基于类的面向对象,类的继承实际上是构造函数的继承

JSON是基于原型的面向对象

es6 给了JSON类的语法规则,但是底层没有提供类,底层是构造函数。类的继承实际上是构造函数的继承。

// 这个原型指向对象
Hero.prototype = {
    age : 18,
    myJob : function () {
        console.log("eat");
    }
}
var hero = new Hero();

// ES6创建类
class Hero {
    // 构造器
    constructor() {
        this.name = "张无忌";
        this.sayMe = function () {
            console.log("this is 张无忌");
        }
    }
}

类的声明

声明类具有以下两种方式:

  • 类的声明方式

    class name [extends]{
    	// class body
    }
    
    • name: 表示当前声明的类名。

    • extends:继承

      但是不同于类表达式,类声明不允许再次声明已经存在的类,否则将会抛出一个类型错误。

  • 类的表达式方式

    const MyClass = class [className][extends]{
    	// class body
    );
    // 或者
    let MyClass = class [className][extends]{
    	// class body
    );
    // 或者
    var MyClass = class [className][extends]{
    	// class body
    );
    

    和函数表达式相同的一点是,类表达式可以是命名也可以是匿名的。如果是命名类表达式,这个名字只能在类体内部才能访问到。

实例:

/*
    1. 类的声明方式
    class className {
        内部结构
    }
    * class关键字 - 用于创建类
    * className - 创建的类名
    * 使用类的声明方式时–不允许重复声明的

*/

class Hero {}

/*
2.类的表达式方式

    const/let/var className = class [className]{
        内部结构
    }
    * class关键字 – 用于创建类
    * myclass/className - 表示创建的类名
        * myClass -类名,用于后面的代码逻辑进行调用
        * className -类名,用于当前类的内部使用的
*/

const myHero = class Hero {}

// 使用var关键字可以重复声明一个类,其余声明类的方式都不允许重复声明
var myHero2 = class Hero2 {}
var myHero2 = class Hero2 {}



构造函数

构造函数(Constructor )是用于创建和初始化类中创建的一个对象的一种特殊方法。

constructor([arguments]) { ...}
  • 在一个类中只能有一个名为“constructor”的特殊方法。一个类中出现多次构造函数(Constructor)方法将会抛出一个SyntaxError错误。
  • 在一个构造方法中可以使用super关键字来调用一个父类的构造方法。
  • 如果没有显式指定构造方法,则会添加默认的constructor方法。
  • 如果不指定一个构造函数( constructor )方法,则使用一个默认的构造函数( constructor ) 。
/*
    创建类 - 结构
    * 外层的类的语法结构
    * 内层的构造器的语法结构
*/

class Hero {
    // 构造器
    constructor() {
        this.name = "Jenny";
        this.sayMe = () => {
            console.log("this is Jenny");
        }
    }
}

let hero = new Hero();
console.log(hero); // Hero { name: 'Jenny', sayMe: [Function] }
hero.sayMe(); // this is Jenny


getter与setter

与ECMAScript 5一样,在“类”的内部可以使用get和 set 关键字(不可以自己定义),对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

在ES5中,et 和 set 是函数名,可以自己定义

/*// ES5 - get 和 set 是函数名,可以自己定义
function fn() {
    var v = 100; // 局部变量
    return {
        get : function () {
            return v;
        },
        set : function (value) {
            v = value;
        }
    }
}

var obj = fn();
console.log(obj.get()); // 100
obj.set(99);
console.log(obj.get()); // 99*/


/*function fn() {
    var v = 100;
    this.get = function () {
        return v;
    }
    this.set = function (value) {
        v = value;
    }
}

var obj = new fn();
obj.set(999);
console.log(obj.get()); // 999*/

// ES6
// 创建对象的属性 可以 设置和获取
/*class Hero {
    constructor() {
        this.v = 100;
    }
}

var hero = new Hero();
console.log(hero.v); // 100*/

// get 和 set [关键字]
class Hero {
    constructor() {
        this.v = 100;
    }

    get getV() {
        return this.v;
    }

    set setV(value) {
        this.v = value;
    }
}

var hero = new Hero();
console.log(hero); // Hero { v: 100 } 没有get和set方法
hero.getV(); // TypeError: hero.getV is not a function
console.log(hero.v);
console.log();


// 可以设置一个属性  没有自带的 get和set Object.defineProperty

不允许提前声明

声明类时,是不存在声明提前的现象的。如下示例代码所示:

new Foo():// ReferenceError: Foo is not defined
class Foo {}

上述代码示例中,Foo类调用在前,声明在后。由于ECMAScript6不允许类的声明提前,结果为报错。
这种规定的原因与继承有关,必须保证子类在父类之后定义。

不允许重复声明

声明类时,是不存在重复声明的。如果一个类被重复声明的话,则引起解析错误。

如下示例代码所示:

class Foo {};
class Foo {}; // SyntaxError; ldentifier 'Foo' has already been declared

若之前使用类表达式定义了一个类,则再次声明这个类同样会引起解析错误。

let Foo = class {};
class Foo {}}; // SvntaxError; ldentifier 'Foo' has already been declared

静态方法

静态方法的语法

static关键字为一个类定义了一个静态方法。静态方法不会在类的实例(通过类生成的对象)上被调用,相反被类本身调用。

static methodName() {...}

methodName:表示指定类中的静态方法名称。

注意:

静态方法直接在类上进行调用,不能在类的实例上调用。

ES6 实例:

/*
    在类的声明中
    * 构造器和普通方法中的this -> 指代创建后的对象
    * 静态方法中的this -> 指代当前的类
*/

class Hero {
    constructor() {
        this.name = "lucy";
        this.sayMe = ()=>{
            console.log("this is " + this.name); // this指向的是当前对象

            // 在构造器中调用静态方法,
            // 1.类名直接调用 即 类名.静态方法()
            Hero.sayYou(); // this is sayYou
            // 2. this.constructor.静态方法名()
            this.constructor.sayYou(); // this is sayYou
        }
    }
    // 对象的方法有2种 - 可枚举 / 不可枚举
    // 在构造器外面定义方法 - 不可枚举(存在但不能直接打印)
    toString () {
        console.log("name toString" + this.name);
        // this指向的是当前对象
        // return "name toString " + this.name
    }

    static sayYou() {
        console.log("this is sayYou"); // this指向的是当前类
    }

    static sayHe() {
        // 在当前静态方法中,调用另一个静态方法
        this.sayYou();
    }
}

let hero = new Hero();
hero.sayMe(); // this is lucy
console.log(hero.toString()); // undefined toString()方法中没有return语句,是打印不出结果的
// console.log(hero.toString()); // name toString lucy

// 调用sayYou()静态方法
Hero.sayYou(); // this is sayYou
// 调用sayHe()静态方法
Hero.sayHe(); // this is sayYou

类的继承

实现类的继承

类的继承在底层中实际上是 原型的继承

语法:

class ChildClass extends ParentClass {...}
  • extends:使用class创建类的时候,用extends指出该类的父类

注意:

  1. 必须在子类的构造器中写入super(),该super()指向父类的构造器,子类才能获取到父类构造器中的属性和方法

  2. 继承的.prototype必须是一个Object或者null.

class Parent {
    constructor() {
        this.name = 'parent';
        this.sayMe = function() {
            console.log('this is sayme')
        }
    }
    sayYou() {
        console.log("这是父类的一个普通方法"); // 这是父类的一个普通方法  undefined
    }

    static staticMethod() {
        console.log("这是父类的静态方法");
    }
}

// 声明Child类时,指定Child类作为Parent类的子类
class Child extends Parent {
    constructor() {
        super(); // super -> 指向当前子类的父类的构造器,否则获取不到父类构造器中的属性和方法
        this.age = 18;
    }


}

let child = new Child(); //
console.log(child); // Child { name: 'parent', sayMe: [Function], age: 18 }
console.log(child.sayYou()); //这是父类的一个普通方法
console.log(Parent.staticMethod()); // 这是父类的静态方法   undefined

继承于内置对象

写一个类继承于内置对象,基于内置对象扩充自己需要的方法,不会改变内置对象原型的内容。

之前使用原型方法的时候,把自己定义的方法加在了内置方法的原型上,改变了内置方法的原型,是不友好的

实例:

/*// myDate类继承于内置对象Date
class myDate extends Date{
    constructor() {
        super();
    }
    getFormattedDate(){

    }

}

let date = new Date();
console.log(date.getFullYear()); // 2020  只能单独返回年、月、日*/


// 继承于Date内置对象

// myDate类继承于内置对象Date
class myDate extends Date{
    constructor() {
        super();
    }

    // 自己定义方法 返回 年-月-日
    getFormattedDate(){
        var months = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"];
        //            日         -          月                    -          年
        return this.getDate() + "-" + months[this.getMonth()] +  "-" + this.getFullYear();
    }

}

/*
let date = new Date();
console.log(date.getFullYear()); // 2020  只能单独返回年、月、日*/

let date = new myDate();
console.log(date.getFormattedDate()); // 25-12月-2020

// 2.继承于数组
let arr = [1,2,3,4,5,4,3,2,1];
class MyArray extends Array {
    constructor() {
        super();
    }
    // Set数据结构中的值是唯一的,可以利用Set给数组中的值去重
    quchong(array) {
        return new Set(array);
    }
}

var array = new MyArray();
console.log(array.quchong(arr)); // Set { 1, 2, 3, 4, 5 }

Super关键字

super关键字可以当作函数使用、当作对象使用。这两种情况是不同的。

  • super关键字当作函数调用 - 代表父类的构造函数

    ES6要求子类的构造函数必须执行一次super函数

    注意:

    super虽然代表了父类A的构造函数,但是返回的是子类B的实例

    即 super内部的 this指的是B,因此 super()在这里相当于A.prototype.constructor.call(this)。

  • super关键字作为对象

    • 在普通方法中,指向父类的原型对象
    • 在静态方法中,指向父类

    注意:

    由于super指向父类的原型对象,super()不能调用定义是父类实例上的方法和属性。

类的实例

注意:父类中方法的返回值 必须用 return , 否则会返回undefined

// 定义一个类
class Parent {
    // 当前的构造器(如果省略,JS会自动生成一个构造器)- 创建对象的初始化方法
    constructor(name) {
        this.name = name;
    }
    // 当前类的(实例对象的)方法,不是当前类的原型方法
    toString() {
        console.log("this is toString method");
    }
    // 静态方法 - 由当前类直接调用的方法
    static staticMethod() {
        return "this is static method";
    }

    
}

// super作为对象,在普通方法中指向父类的原型对象,所以父类中的toString()方法必须是原型中的方法
    // 在类的原型中添加方法
    Parent.prototype.sayMe = function () {
        return "this is parent method."
    }




// 类也同样具有原型(类似于ES5中的构造函数)
// 对象中有一个隐式原型 - 指向类的原型
/*let parent = new Parent();
parent.toString(); // this is parent method.*/


// 定义一个类作为另一个类的子类
class Child extends Parent {
    // 因为父类的构造函数中有一个name形参,所以子类的构造函数中也要有和父类一样是形参,否则子类就不能继承父类了
    // 别忘了 super()里面也要写上父类中构造函数的形参
    constructor(name,age) {
        super(name); // super指向父类的构造器
        this.age = age;
        // 以下用法:super -> 指向父类的实例对象(具有隐式原型)
        //  原型对象不能调用实例对象,实例对象能调用原型对象
        super.sayMe(); // super指向父类的原型对象

        // super.staticMethod(); // 报错 TypeError: (intermediate value).sayMe is not a function

        super.toString(); // super指向父类实例化的对象 this is tostring method .

        // super的不同用法导致super的含义不同
    }

    sayMe() {
        // super 指向父类的原型对象
        console.log("this is child method. " + super.sayMe())
    }

    static staticMethod() {
        // super - 指向父类
        console.log("this is child static method. " + super.staticMethod())
    }
}

// 因为子类的构造函数中有形参name 和 age , 所以实例化子类的时候也要给形参传值
let child = new Child("lucy",18);
// console.log(child); // Child { name: 'lucy', age: 18 }
// 父类和子类中有相同函数名toString(),当子类对象调用该方法的时候,子类和父类的相同方法会被同时调用
child.sayMe();
/*
this is parent method.
this is child method. undefined

如果 super.staticMethod() 的返回值是 undefined
原因:super作为对象,在普通方法中指向父类的原型对象,而父类中的toString()方法不是原型中的方法

把父类中的toString()方法改为原型中的方法后:
返回结果是:
this is child method. this is parent method.
*/


// Child.staticMethod();
/*
this is static method
this is child static method. undefined
*/

end~
在这里插入图片描述


本文链接: http://www.dtmao.cc/news_show_550325.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?