前言

  JavaScript 语言在ES6中引入了 class 这一个关键字,在学习面试的中,经常会遇到面试官问到谈一下你对 ES6 中class的认识,同时我们的代码中如何去使用这个关键字,使用这个关键字需要注意什么,这篇来总结一下相关知识点。

正文

  1.es6之前创建对象

  先来看下es6之前我们要想创建一个对象,只能通过构造函数的方式来创建,将静态方法添加在原型上面使得每一个实例能够调用该方法。

        function Person(name, age) {
this.name = name
this.age = age
Person.prototype.sayHello = function () {
return "hello," + this.name + ",早上好"
}
}
let person = new Person("serendipity", 18)
console.log(person.sayHello())//hello,serendipity,早上好
console.log(person instanceof Person);//true
console.log(person instanceof Object);//true

  2.es6之后class的声明

  类是用于创建对象的模板,他们用代码封装数据以处理该数据。js中的 class 类建立在原型之上,但也具有某些语法和语义与ES5类相似语义共享。

  实际上,类是一种特殊的函数,就像定义函数声明和函数表达式一样,类的语法也有两个部分组成:类声明和类表达式。

        class Person {
constructor(name, age) {//自有属性,该属性出现在实例上,只能在类的构造器或者方法内部进行创建
this.name = name
this.age = age
}
sayHello() {//等价于Perosn.prototype.sayHello
return `hello,${this.name},早上好`
}
}
let person = new Person("serendipity", 18)
console.log(person.sayHello());//hello,serendipity,早上好
console.log(person instanceof Person);//true
console.log(person instanceof Object);//true
console.log(typeof Person);//function
console.log(typeof Person.prototype.sayHello);//function

  类声明允许在class中使用 constructor 方法定义一个构造器,而不需要定义专门的构造方法来当构造器使用。

  class 类的语法与普通es5之前的函数语法相似,但是还存在一些特性需要注意:

  (1)类的声明不会被提升,类的声明行为和 let 相似,因此执行时类会存在暂时性死区;

  (2)类中所有代码自动运行在严格模式下,且改严格模式无法退出

  (3) 类中所有方法都是不可枚举的,普通自定义方法只有通过 object.defineProperty() 才能将方法定义为不可枚举

  (4)类中的所有方法内部都没有 [[construct]] ,因此使用new 来调用他们会抛出错误

  (5)调用类构造器时不使用 new 会抛出错误

  (6)试图在类的方法内部重写类名会抛出错误

  将上面的代码转换为ES5之前的写法如下:

        let PersonClass = (function () {
"use strict"
const PersonClass = function (name, age) {
// 判断是否被new调用构造函数
if (typeof new.target === "undefined") {
throw new Error("Constructor must be call with new.")
}
this.name = name
this.age = age
}
Object.defineProperty(PersonClass.prototype, "sayHello", {
value: function () {
if (typeof new.target !== "undefined") {//保正调用时没有使用new
throw new Error("Method cannot be called with new.")
}
return "hello," + this.name + ",早上好!"
},
enumerable: false,
configurable: true,
writable: true
})
return PersonClass
})()
var personClass = new PersonClass("serendipity", 18)
console.log(personClass.name);//serendipity
console.log(personClass.sayHello());///hello,serendipity,早上好!

  两个PersonClass 声明,一个在外部作用域的 let 声明,另一个在立即执行函数内部的 const 声明,这就是为何类的方法不能对类名进行重写,而类的外部的代码则被允许。同时,只在类的内部类名才被视为使用了const声明,这意味着你可以在外部(相当于let)重写类名,但是不能在类的方法内部这么写。

  3.类的继承

  ES6之前的继承方式主要通过构造函数和原型链组合的方式来实现继承,具体代码如下:

        function Rectangle(length, width) {
this.length = length
this.width = width
Rectangle.prototype.getArea = function () {
return this.length * this.width
}
}
function Square(length) {
Rectangle.call(this, length, length)
}
Square.prototype = Object.create(Rectangle.prototype, {
constructor: {
value: Square,
enumerble: true,
writeable: true,
configurable: true
}
})
var square = new Square(3)
console.log(square.getArea());//9
console.log(square instanceof Square);//true
console.log(square instanceof Rectangle);//true

  上面的代码通过构造函数和原型上面添加静态方法实现了 Rectangle 父类,然后子类 Square 通过 Rectangle.call(this,length,length) 调用了父类的构造函数,Object.create 会在内部创建一个空对象来连接两个原型对象,再手动将 constructor 指向自身。这种方法实现继承代码繁杂且不利用理解,于是ES6 class 类的创建让继承变得更加简单,使用extends 关键字来指定当前类所需要继承的父类,生成的类的原型会自动调整,还可以使用 super() 方法来访问基类的构造器。具体代码如下:

        class Rectangle {
constructor(length, width) {
this.length = length
this.width = width
}
getArea() {
return this.length * this.width
}
}
class Square extends Rectangle {
constructor(length) {
super(length, length)
}
getArea() {
return this.length + this.length
} }
var square = new Square(3)
console.log(square.getArea());//6
console.log(square instanceof Square);//true
console.log(square instanceof Rectangle);//true

  上面的代码中 Square 类重写了基类的 getArea() 方法,当派生的子类中函数名和基类中函数同名的时候,派生类的方法会屏蔽基类的方法,同时也可以再子类中getArea () { return super.getArea() }中调用基类的方法进行扩展。

  4.继承类的静态成员

  静态成员:直接在构造器上添加的额外的方法。例如ES5中在原型上添加的方法就属于静态成员,ES6 class类引入简化了静态成员的创建,只需要在方法与访问器属性的名称前添加 static关键字即可。例如下面的代码用于区分静态方法和实例方法。

    function PersonType(name) {
this.name = name;
}
// 静态方法
PersonType.create = function(name) {
return new PersonType(name);
};
// 实例方法
PersonType.prototype.sayName = function() {
console.log(this.name);
};
  var person = PersonType.create("Nicholas");

  在ES6中要想使用静态成员如下:

        class Rectangle {
constructor(length ,width) {
this.length = length
this.width = width
}
getArea() {
return this.length * this.width
}
static create(length,width) {
return new Rectangle(length , width)
}
}
class Square extends Rectangle{
constructor (length){
super(length,length)
}
}
var square =Square.create(3,4)
console.log(square.getArea());//12
console.log(square instanceof Square);//false
console.log(square instanceof Rectangle);//true

  上面的代码中,一个新的静态方法 create() 被添加到 Rectangle 类中,通过继承,以Square.create() 的形式存在,并且其行为方式与Rectangle.create() 一样。需要注意静态成员不懂通过实例来访问,始终需要直接调用类自身来访问他们。

写在最后

  以上就是本文的全部内容,希望给读者带来些许的帮助和进步,方便的话点个关注,小白的成长踩坑之路会持续更新一些工作中常见的问题和技术点。

js--class类、super和estends关键词的学习笔记的更多相关文章

  1. js高级程序设计(第三版)学习笔记(第一版)

    ecma:欧洲计算机制造商协会iso/iec:国际标准化和国际电工委员会 dom级别(10*)文档对象模型1:DOM核心(映射基于xml文档)与dom html(在dom核心基础上)2:对鼠标,事件, ...

  2. 《JS高程》基本类型和引用类型的值学习笔记

    ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值. 创建方式类似:创建一个变量并为其赋值. (1)基本类型值和引用类型值比较 基本类型值 引用类型值 简单的数据段 可能由 ...

  3. JS高程12.2.3元素大小的学习笔记

    <JavaScript高级程序设计>中讲述了通过JS如何控制页面中元素的大小,其中涉及到三对属性:偏移量,客户区大小,滚动大小.以前自己经常看到这三对属性,但是具体不是很清楚,容易混淆.所 ...

  4. 一个重构的js分页类

    // JavaScript Document /**//** * js分页类 * @param iAbsolute 每页显示记录数 * @param sTableId 分页表格属性ID值,为Strin ...

  5. 分享非常好用的前端分页js工具类 灵活 简单易懂

    分享自己封装的前端分页js工具类  下面是默认样式效果截图 可以随意更改js及css 很灵活 /** * pageSize, 每页显示数 * pageIndex, 当前页数 * pageCount 总 ...

  6. JS常用类

    JS常用类 一.Number 1.常用数字 整数:10 小数:3.14 科学计数法:1e5 | 1e-5 正负无穷:Infinity | -Infinity 2.常用进制 二进制:0b1010 八进制 ...

  7. JS创建类的方法--简单易懂有实例

    版权声明:本文为博主原创文章,转载请注明出处 Javascript是一种基于对象的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有Class. ...

  8. Vue.js的类Class 与属性 Style如何绑定

    Vue.js的类Class 与属性 Style如何绑定 一.总结 一句话总结:数据绑定一个常见需求是操作元素的 class 列表和它的内联样式.因为它们都是属性,我们可以用 v-bind 处理它们:我 ...

  9. js构建类的方法

    Javascript是一种基于对象的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有Class.(不过,ES6引入了Class这个概念,作为对 ...

随机推荐

  1. windows 上 OpenSSH 服务 启用秘钥登录(微软真心逆天)

    windows 上 OpenSSH 服务 启用秘钥登录(微软真心逆天) windows 安装 OpenSSH 服务 最近需要在windows 服务器上部署自动发布程序,那么就需要用到 scp 和 ss ...

  2. 在vs中调试关闭之后不关闭页面

    在vs中调试api时会自动打开一个新的浏览器窗口,在关闭这个浏览器窗口时,会关闭调试.关闭调试时也会关闭浏览器窗口. 设置成调试时在已有的浏览器中打开调试页面,关闭调试也不会关掉浏览器窗口,反之亦然 ...

  3. 02 SVN 与 Git 的优缺点

    上一篇博客大致聊了聊关于版本控制系统的周边,这一篇我们就来继续唠唠作为近年来最受欢迎的两个版本控制系统的优缺点吧. 聊优缺点之前,先简单了解一下这两个这两个版本控制系统好了: 关于 SVN SVN 概 ...

  4. Kubernetes网络的iptables模式和ipvs模式支持ping分析

    1.iptables模式无法ping通原因分析 iptables模式下,无法ping通任何svc,包括clusterip.所有ns下,下面来分析原因: 查看kubernetes的网络模式 curl 1 ...

  5. 使用docker搭建最新版本的gitea,并配置HTTPS访问

    使用docker搭建最新版本的gitea,并配置HTTPS访问 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 简介 之前有搭建 ...

  6. Sherlock and His Girlfriend题解

    题目描述 Sherlock 有了一个新女友(这太不像他了!).情人节到了,他想送给女友一些珠宝当做礼物. 他买了 n件珠宝.第i 件的价值是i+1.那就是说,珠宝的价值分别为2,3,4,-,n+1 . ...

  7. hdu 3117 Fibonacci Numbers 矩阵快速幂+公式

    斐波那契数列后四位可以用快速幂取模(模10000)算出.前四位要用公式推 HDU 3117 Fibonacci Numbers(矩阵快速幂+公式) f(n)=(((1+√5)/2)^n+((1-√5) ...

  8. 企业该选择什么样的CRM系统

    不论您是需要CRM系统来优化业务流程,还是准备更换一款新的CRM系统,在这之前都应该先明确企业的需求,并了解CRM的哪些功能能够对企业有所帮助.例如,企业的管理者想了解每个销售人员的业绩情况,那么就应 ...

  9. 互联网时代CRM软件帮助企业销售升级

    随着信息技术的发展,互联网+的浪潮逐渐改变了我们的生活.对于企业来说,他们的管理模式和服务模式也需要作出改变,企业不再满足只进行内部业务的优化和管理,传统CRM开始不再符合企业的需求.由此可见,在网络 ...

  10. js实现文字分割动画

    <!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...