了解JavaScript中的类

2023-05-16

javascript是一种基于原型的语言,javascript中的每个对象都有一个名为[[原型]]的隐藏内部属性,可用于扩展对象属性和方法。

直到最近,勤奋的开发人员使用构造函数来模仿JavaScript中面向对象的设计模式。语言规范ECMAScript 2015(通常称为ES6)引入了JavaScript语言的类。JavaScript中的类实际上并没有提供额外的功能,并且通常被描述为提供原型和继承的“语法糖”,因为它们提供了更清晰,更优雅的语法。由于其他编程语言使用类,因此JavaScript中的类语法使开发人员在语言之间移动变得更加直接。

类是函数:

JavaScript类是一种函数。使用class关键字声明类。我们将使用函数表达式语法初始化函数和类表达式语法来初始化类。

// Initializing a function with a function expression
const x = function() {}
// Initializing a class with a class expression
const y = class {}

我们可以使用object.getprototypeof()方法访问对象的[[原型]]。让我们用它来测试我们创建的空函数。

Object.getPrototypeOf(x);

Output
  
ƒ () { [native code] }

我们也可以在刚刚创建的类上使用该方法。

Object.getPrototypeOf(y);

Output
  
ƒ () { [native code] }

用函数和类声明的代码都返回函数[[原型]]。使用原型,任何函数都可以使用new关键字成为构造函数实例。

const x = function() {}
// Initialize a constructor from a functionconst 
constructorFromFunction = new x();
console.log(constructorFromFunction);

Output
  
x {}
constructor: ƒ ()

这也适用于类。

const y = class {}
// Initialize a constructor from a class
const constructorFromClass = new y();
console.log(constructorFromClass);

Output
  
y {}
constructor: class

这些原型构造函数示例在其他方面是空的,但是我们可以看到在语法的下面,这两个方法是如何实现相同的最终结果的。

定义一个类

一个构造函数函数是用一些参数初始化的,这些参数将被指定为该函数的属性,并引用该函数本身。按照惯例,标识符的第一个字母将大写。

constructor.js

// Initializing a constructor 
functionfunction Hero(name, level) {
    this.name = name;    
    this.level = level;
    }

当我们将其转换为类语法时,如下所示,我们看到它的结构非常相似。

class.js

// Initializing a class definition
class Hero {
    constructor(name, level) {
        this.name = name;        
        this.level = level;
    }}

我们知道构造器函数通过初始化器的第一个字母大写(可选)和熟悉语法来表示对象蓝图。class关键字以更直接的方式传递函数的目标。

初始化语法的唯一区别是使用class关键字而不是函数,并在constructor()方法中分配属性。

定义方法

构造函数函数的常见做法是将方法直接分配给原型,而不是在初始化过程中,如下面的greet()方法所示。

constructor.js

function Hero(name, level) {
    this.name = name;    
    this.level = level;
}// Adding a method to the constructor
Hero.prototype.greet = function() {
    return `${this.name} says hello.`;
}

对于类,这种语法被简化,方法可以直接添加到类中。

class.js

class Hero {
    constructor(name, level) {        
    this.name = name;        
    this.level = level;
    }    
    // Adding a method to the constructor
    greet() {        
          return `${this.name} says hello.`;
    }
}

让我们看看这些属性和方法的实际应用。我们将使用新关键字创建一个新的英雄实例,并分配一些值。

const hero1 = new Hero('Varg', 1);

如果我们用console.log(hero1)打印出更多关于新对象的信息,我们可以看到更多关于类初始化的细节。


Output
  
Hero {name: "Varg", level: 1}
__proto__:
  ▶ constructor: class Hero
  ▶ greet: ƒ greet()

我们可以在输出中看到constructor()和greet()函数被应用于hero1的uu proto_uuuu或[[prototype]],而不是直接作为hero1对象上的方法。虽然这在构造构造函数函数时很明显,但在创建类时并不明显。类允许更简单和简洁的语法,但会在过程中牺牲一些清晰度。

扩展类

构造器函数和类的一个优点是,它们可以基于父对象扩展为新的对象蓝图。这可以防止对相似但需要一些额外或更具体功能的对象重复代码。

可以使用call()方法从父级创建新的构造函数函数。在下面的示例中,我们将创建一个更具体的字符类mage,并使用call()将hero的属性分配给它,同时添加一个额外的属性。

constructor.js

// Creating a new constructor from the parent
function Mage(name, level, spell) {
    // Chain constructor with call
    Hero.call(this, name, level);    
    this.spell = spell;
}

此时,我们可以创建一个Mage使用相同属性的新实例,Hero以及我们添加的新属性。

const hero2 = new Mage('Lejon', 2, 'Magic Missile');

发送hero2到控制台,我们可以看到我们已经Mage根据构造函数创建了一个新的。


Output
  
Mage {name: "Lejon", level: 2, spell: "Magic Missile"}
__proto__:
    ▶ constructor: ƒ Mage(name, level, spell)

对于ES6类,使用super关键字代替call访问父函数。我们将用于extends引用父类。

class.js

// Creating a new class from the parent
class Mage extends Hero {
    constructor(name, level, spell) {
        // Chain constructor with super
        super(name, level);
        // Add a new property
        this.spell = spell;
    }}

现在我们可以以相同的方式创建一个新的Mage实例。

const hero2 = new Mage('Lejon', 2, 'Magic Missile');

我们将打印hero2到控制台并查看输出。


Output
  
Mage {name: "Lejon", level: 2, spell: "Magic Missile"}
__proto__: Hero
    ▶ constructor: class Mage

输出几乎完全相同,除了在类构造中[[Prototype]]链接到父类,在本例中是Hero。

下面是初始化、添加方法以及构造函数函数和类继承的整个过程的并行比较。

constructor.js

function Hero(name, level) {
    this.name = name;    
    this.level = level;
}// Adding a method to the constructor
Hero.prototype.greet = function() {
    return `${this.name} says hello.`;
}// Creating a new constructor from the parent
function Mage(name, level, spell) {
    // Chain constructor with call
    Hero.call(this, name, level);    
    this.spell = spell;
}

class.js

// Initializing a class
class Hero {
    constructor(name, level) {        
    this.name = name;        
    this.level = level;
    }    
    // Adding a method to the constructor
    greet() {
            return `${this.name} says hello.`;
    }
}
// Creating a new class from the parent
class Mage extends Hero {
    constructor(name, level, spell) {        
        // Chain constructor with super
        super(name, level);
         // Add a new property
        this.spell = spell;
    }
}

虽然语法完全不同,但两种方法的基本结果几乎相同。 类为我们提供了一种更简洁的方法来创建对象蓝图,构造函数更准确地描述了引擎盖下发生的事情。

结论

在本教程中,我们了解了JavaScript构造函数和ES6类之间的相似点和不同点。类和构造函数都模仿面向对象的继承模型到JavaScript,这是一种基于原型的继承语言。

理解原型继承对于成为有效的JavaScript开发人员至关重要。熟悉类非常有用,因为像React这样的流行JavaScript库经常使用class语法。

更多web前端学习相关知识,请查阅 HTML中文网 !!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解JavaScript中的类 的相关文章

随机推荐

  • CSS在页面加载时创建淡入效果

    下面本篇文章就来给大家介绍一下使用CSS在页面加载时创建淡入效果的方法 xff0c 希望对大家有所帮助 想要使用CSS在页面加载上创建淡入效果 xff0c 可以使用css的animation属性或transition属性在页面加载时创建淡入
  • CSS设置文本和边框(图像)阴影

    在CSS中可以使用阴影效果属性在HTML文档中添加文本和边框 xff08 图像 xff09 阴影 下面本篇文章就来给大家介绍一下CSS的阴影效果属性 xff0c CSS添加阴影效果的方法 xff0c 希望对大家有所帮助 1 添加文本阴影 在
  • 使用JavaScript清除div的内容

    JavaScript提供清除div内容的功能 xff0c 想要执行此功能有两种方法 xff1a 一种是使用innerHTML属性 xff0c 另一种是使用firstChild属性和removeChild 方法 下面本篇文章就来给大家介绍一下
  • 大话pixhawk运行Ardu:Copter启动过程

    1 xff1a 了解启动过程有什么帮助 xff1f 2 xff1a 硬件连接 3 xff1a 启动过程 amp 分析 rgbled on I2C bus 2 at 0x55 bus 100 KHz max 100 KHz init look
  • JavaScript将Set(集合)转换为Array数组

    在JavaScript中 xff0c 想要将Set xff08 集合 xff09 转换为Array数组 xff0c 可以通过以下方式实现 方法1 xff1a 使用Array from 方法 Array from 方法从对象或可迭代对象 xf
  • 使用CSS将图像进行模糊处理

    给定一个图像 xff0c 如何使用CSS将图像进行模糊处理 xff0c 转换为模糊图像 xff1f 下面本篇文章就来给大家介绍一下使用CSS模糊处理图像的方法 xff0c 希望对大家有所帮助 在CSS中 xff0c 可以使用filter属性
  • CSS设置占位符文本的对齐方式

    HTML的placeholder属性指定一个简短提示 xff0c 用于描述input字段或文本区域 xff08 textarea xff09 的预期值 xff0c 即占位符文本 短提示在用户输入值之前显示在字段中 在大多数浏览器中 xff0
  • 谈谈HTML的短语标签及其作用

    在HTML中 xff0c 短语标签是专用标签 xff0c 用于指示文本块具有结构意义 xff0c 执行与文本格式标签类似的特定操作 例如 xff0c abbr标签表示该短语包含缩写词 短语标签的一些例子有 xff1a abbr strong
  • 常见的类名id名命名参考规范

    web前端命名规范 下面是常见的命名参考规范 xff1a 主体 头部 xff1a header 内容 xff1a content container 尾部 xff1a footer 导航 xff1a nav 侧栏 xff1a sidebar
  • Vue.js开发的4个基本ES2015特性

    ES2015 又名ES6 是当前JavaScript语言的规范 如果您是JavaScript新手或者最近没有更新JavaScript知识 xff0c 那么在ES2015中有许多新特性可以使开发变得更好 更有趣 如果您是Vue开发人员 xff
  • VueJS项目的5个很棒的样板/模板

    你要开始一个重要的Vue项目吗 为了确保您从一个坚实的基础开始 xff0c 您可以使用一个模板 也称为样板 骨架 启动器或脚手架 xff0c 而不是从npm init或vue init开始 许多经验丰富的开发人员都以开源模板的形式收集了关于
  • 如何构建出色的Vue组件

    很少有人最初编写Vue组件时打算将其开源 我们大多数人开始为自己编写组件的原因 xff1a 我们有一个问题 xff0c 然后决定通过构建一个组件来解决它 有时我们发现自己想要在代码库的新位置解决相同的问题 xff0c 所以我们提取组件并对其
  • 在Vue.js中定义组件模板的7种方法

    Vue js 使用了基于 HTML 的模板语法 xff0c 允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据 所有 Vue js 的模板都是合法的 HTML xff0c 所以能被遵循规范的浏览器和 HTML 解析器解析 在Vue
  • 深入CSS,让网页开发少点“坑”

    通常我们在学习CSS的时候 xff0c 感觉语法很容易掌握 xff0c 实际应用中却碰到各式各样难以填补的 坑 xff0c 为避免大家受到同样的困惑与不解 xff0c 本文详细讲解了CSS中优先级和Stacking Context等高级特性
  • Pixhawk参数调整

    Pixhawk copter固件的默认参数是为3DR QUAD COPTER设计的 如果你想获得一个最佳的飞行表现的话 你需要对一些参数做一些调整 调整的参数主要是Extended Tuning下面的Roll和Pitch的PID xff0c
  • 用于Vue.js应用程序的4个AJAX模式

    Vue没有提供实现AJAX的正式方法 xff0c 而且有许多不同的设计模式可以有效地使用 每种方法都有其优缺点 xff0c 应该根据需求进行判断 您甚至可以同时使用多个 在本文中 xff0c 我将向您展示在Vue应用程序中实现AJAX的四个
  • 预渲染vue.js应用程序(使用node或laravel)

    服务器端渲染现在非常流行 但它也并非没有缺点 预渲染是一种替代方法 xff0c 在某些情况下甚至可能更好 下面我们来看一下如何预渲染vue js应用程序 在本文中 xff0c 我们将探讨预渲染如何与vue js一起工作 xff0c 并看两个
  • CSS实现不定宽高垂直水平居中的几种方法

    垂直居中 xff0c 在 CSS 中是一个老生常谈的问题 xff0c 面试的时候也会时常被提及 所以 xff0c 今天我们就来聊聊 9 种不同的居中方法 有常见的 flex transform absolute 等等 也有 CSS3 的网格
  • JavaScript中的JSON和JSONP

    简单地使用json并不能支持跨域资源请求 xff0c 为了解决这个问题 xff0c 需要采用jsonp数据交互协议 众所周知 xff0c js文件的调用不受跨域与否的限制 xff0c 因此如果想通过纯web端跨域访问数据 xff0c 只能在
  • 了解JavaScript中的类

    javascript是一种基于原型的语言 xff0c javascript中的每个对象都有一个名为 原型 的隐藏内部属性 xff0c 可用于扩展对象属性和方法 直到最近 xff0c 勤奋的开发人员使用构造函数来模仿JavaScript中面向