下面的对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 functionsuper.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~

ES6 class关键字 ~ 非常详细相关推荐

  1. ES6 | let 关键字 + const关键字 + 箭头函数 + rest参数 + 扩展运算符 ... + Symbol + 迭代器 + 生成器 + 变量的解构赋值 + 模板字符串

    目录 ECMASript 相关介绍 ECMASript 6 新特性 let 关键字 const关键字 变量的解构赋值 模板字符串 简化对象写法 箭头函数 => 参数默认值 rest参数 扩展运算 ...

  2. es6 super关键字

    super关键字 super这个关键字,既可以当作函数使用,也可以当作对象使用.在这两种情况下,它的用法完全不同. 第一种情况,super作为函数调用时,代表父类的构造函数.ES6 要求,子类的构造函 ...

  3. es6 super 关键字

    super 关键字 我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象. const proto = { foo: 'hello' ...

  4. ES6新增关键字:let和const及let的常用场景

    1.ES6: ● 我们所说的ES5和ES6其实就是在js语法的发展过程中的一个版本而已 ● ECMAScript就是js的语法,ES6新增了一些功能 2.let和const关键字 和var的区别 ● ...

  5. ES6——super关键字

    super关键字有两种使用场景 1.当用作方法时 在ES6的构造函数中,ES6的语法规定,在继承于父类的子类的构造函数中,必须使用super(),因为在子类中是不存在上下文指向(this)的,需要使用 ...

  6. ES6笔记(完整详细版)

    第三阶段 企业级开发 第一章 环境搭建 一.Node介绍 Node也叫NodeJS,Node.js,由Ryan-Dahl于2009年5月在GitHub发布了第一版.Node是一个JavaScript运 ...

  7. c语言volatile关键字(详细)总结附示例讲解

    目录 一.简介 二.示例代码解析 2.1 修饰变量 2.2 修饰硬件寄存器地址 三.其他相关链接 一.简介 volatile属于C语言的关键字.开发者告诉编译器该变量是易变的,无非就是希望编译器去注意 ...

  8. Oracle之comment关键字的详细讲解

    一.comment是oracle数据库系统的关键字,所以不能用来命名表明或字段名 二.comment关键字用于对表,字段添加注释,有利于用户对表结构以及数据库对象含义的理解. 三.用户可以通过数据字典 ...

  9. 关于Java中final关键字的详细介绍

    Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...

最新文章

  1. [裴礼文数学分析中的典型问题与方法习题参考解答]4.3.13
  2. Python开发【第十一篇】:JavaScript
  3. vue路由守卫判断用户是否登录,如果没登陆就跳转到登录
  4. Java给定一个字符串数组,判断每个字符出现次数
  5. android怎么设置适配器,Android之自定义实现BaseAdapter(通用适配器三)
  6. 如何关闭MyEclipse自动更新
  7. Android趣味课程:超简单猜数游戏
  8. 如何提取差异脑区的灰质体积与临床量表算相关?——基于体素的形态学方法(VBM)
  9. Oracle --- 表空间
  10. 【爬虫实战】7基础Python网络爬虫——淘宝商品比价定向爬虫(MOOC学习笔记)
  11. 面试问遇到最难的事情_太难的事情
  12. Druid java.sql.SQLException: connection holder is null
  13. IOS收起键盘的几种办法(摘抄自唐巧《iOS开发进阶》)
  14. Apache atlas的UI界面如何修改密码
  15. Android手机AP模式下本机IP
  16. 智汀家庭云与Home Assistant如何接入HomeKit,并连接米家设备
  17. u盘安装浪潮服务器_安装linux操作系统--浪潮服务器
  18. 深入hotstuff与pbft协议的核心
  19. c++关键字virtual的用法(面试)
  20. 【我的OpenGL学习进阶之旅】介绍一下 图元的类型:三角形、直线和点精灵

热门文章

  1. mysql服务器的字符集
  2. 遊戲是這樣寫成的 (第三篇: 簡單的遊戲框架)
  3. FPGA_EP2C8T144_SCH(PDF)
  4. Cognos 8 错误及故障排除(转载)
  5. jsp+mysql 数据库操作
  6. UVA11968 In The Airport【最值】
  7. Bailian2737 大整数除法【大数】
  8. 民族融合 —— 魏晋南北朝
  9. Momentum(动量/冲量)的理解及应用
  10. LaTeX —— 特殊符号与数学字体