JavaScript 有类吗?

Posted

技术标签:

【中文标题】JavaScript 有类吗?【英文标题】:Does JavaScript have classes? 【发布时间】:2011-02-14 17:20:35 【问题描述】:

上周我和一个朋友发生了争执。他说 javascript 中没有类之类的东西。

我说过你可以说var object = new Object()

他说“因为没有使用class这个词。这不是一个类。”

谁是对的?


作为注释;未来你需要一个简洁的 Classy JS 实现:

https://github.com/tnhu/jsface


编辑:2017 年 7 月

ECMAScript 2015 中引入的 JavaScript 类主要是 JavaScript 现有的基于原型的继承的语法糖。类语法并未向 JavaScript 引入新的面向对象的继承模型。 JavaScript 类提供了一种更简单、更清晰的语法来创建对象和处理继承。

- Mozilla ES6 类:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes

【问题讨论】:

在上面的例子中它是在讨论类 Rectangle,所以定义一个类我们不再需要使用 function 关键字 ie (function Rectangle(dimensions) ? 现在有一个 class 关键字上课? 我发现这个 reddit 线程提供了很多人对这个主题的看法。大多数人似乎在说 es6 类算作真正的类,但当然也有一些相互矛盾的意见。任何想深入探讨这个问题并形成自己观点的人都可以看一看:reddit.com/r/javascript/comments/8q6267/… 【参考方案1】:

人们所说的“语言 X 有类”通常是指支持面向对象编程。

是的,Javascript 是一种面向对象的语言。

【讨论】:

JS 是一种函数式语言 @ndesign11 甚至没有接近。拥有一流的函数并不能使 JavaScript 成为一种函数式语言。【参考方案2】:

在 Javascript 中,几乎所有东西都是object(对象可以从其他对象继承)。它没有经典意义上的classes

虽然你可以通过函数原型来重现传统类定义/实例化的大部分功能。

【讨论】:

“在 Javascript 中一切都是对象”:不正确。还有一些原始值,如undefinednull等。 无效? javascript 中是否存在 void - 我是 as3 人看到...我从未在 js 中看到 void。 @Glycerine 据我所知,JavaScript 中最接近 AS3 的 void 的是 undefined【参考方案3】:

AFAIK Javascript 使用原型概念,它不是 OO。这意味着您不能使用 OOP 的典型概念,如继承或多态。

【讨论】:

JavaScript 是一种基于原型的编程语言,这意味着它一种面向对象的语言。 我喜欢这个网站,因为总有东西要学;) 继承和多态都可以在Javascript中应用。 让我感到羞耻,但请不要再否决这个问题......我当时年轻又愚蠢:) 这是我的非官方downVote。【参考方案4】:

从技术上讲,“JavaScript 没有类”的说法是正确的。

虽然 JavaScript 是面向对象的语言,但它不是 class-based language,而是 prototype-based language。这两种方法之间存在差异,但由于可以像使用基于类的语言一样使用 JavaScript,因此许多人(包括我自己)通常将构造函数简单地称为“类”。

【讨论】:

您可以使用原型模拟类,也可以使用类模拟原型,例如看看他的原型设计模式。 我想我已经赚到了!好一个史蒂夫 @SteveHarrison,ECMAScript 2015 中引入的 JavaScript 类主要是 JavaScript 现有的基于原型的继承的语法糖。所以这意味着 javascript 现在正在成为基于类的语言? 是的,作为一名 Java 开发人员,我经常向人们指出这一点。 Javascript 有“对象”但没有类。人们所说的“类”实际上是一个对象。 尽管 ES6 类主要是语法糖,但任何想要将它们视为不真实的人都必须小心不要使用也将类排除在其他动态语言中的参数。 Javascript 类已经变得和 python 类一样真实。【参考方案5】:

在这里收听 Douglas Crockford 的演讲:http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-2

他在演讲中直接回答了你的问题:

该语言最具争议的特性是它的继承方式,这与几乎所有其他现代语言完全不同。大多数语言都使用类——我称它们为“经典语言”——JavaScript 没有。 JavaScript 是免费的。它使用原型。对于那些受过经典训练的人来说,他们会说:嗯,这是有缺陷的。你没有课,你怎么能完成任何事情?你怎么能相信你的程序结构会起作用?他们永远不会超越这一点。但事实证明……

【讨论】:

视频托管在 YouTube youtube.com/watch?v=RO1Wnu-xKoY【参考方案6】:

当我想到类时,我想到了类型以及类允许我定义新类型这一事实。在 js 中你不能创建新类型。你可以用原型做各种花哨的 oo 东西,但一切仍然是一个对象这一事实真正击中了 js 的无类本质。我认为人们在谈论 js 时使用“类”术语会混淆 js 作为原型语言与 js 作为经典语言,甚至比丑陋的 new 运算符更容易混淆。总之,js是面向对象的,并不意味着类需要存在。

【讨论】:

【参考方案7】:

要添加其他答案,javascript 没有类,尽管我开始看到将其描述为类之类的语句,但我相信这只会混淆问题。

JavaScript 有原型,而不是类,但它们完成相同的事情,原型是定义对象的对象,因此会造成混淆。

原型是私有内部状态的表示,例如,类将在 Java 中管理。 JavaScript 不像在 java 中那样将内部状态放在一个类中并呈现用于操作行为的接口,而是公开数据结构供 JavaScript 程序直接操作。

这是我找到的关于该主题的最佳描述,Prototypes are not Classes。

【讨论】:

【参考方案8】:

Javascript 是一种面向对象的编程语言,但在 2015 年,已经引入了 6 个 ECMA 脚本类,现在可以像 Java 等其他基于类的语言一样使用它们。当然,正如用户 codemagician 在他/她的评论中指出的那样,在 js 和 java 或其他“基于类”的编程语言中类的工作方式之间存在一些深刻的差异。

尽管如此,现在在 js 编程中可以使用以下示例代码:

class Animal  
  constructor(name) 
    this.name = name;
  


class Dog extends Animal 
  speak() 
    console.log(this.name + ' barks.');
  

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

这与经典的基于类的语言有一些共同点。 问题仍然是目前才刚刚开始的这项新技术的浏览器支持。所以在产品上使用它仍然不好。但我毫不怀疑这个问题会很快得到解决。

因此问题仍然存在,如果 js 是因为这些新功能的实现而成为一种基于类的编程语言,还是仍然是一种面向对象原型的编程语言。

【讨论】:

@Bhargav Rao 嗨。 Tnx 的评论。我并不是要争论,但问题是“JavaScript 有类吗?”我说“2015 年在 ECMA 脚本 6 中引入了 js 中的类”这个恕我直言,对这个问题给出了更新的答案......不是吗?同时,我的回应试图与其他开发人员“交流”他们对这种新的 EC6 情况的看法。可能是我错了,在这种情况下,我很抱歉我的错误。 我可以谦虚地问为什么要投反对票,这样我就可以从自己的错误中吸取教训吗?提前 Tnx。 我没有投反对票。我猜是因为flag。通常他们是罪魁祸首。等一两天。其他领域专家会看到您的帖子并相应地投票。不要太担心这些突然的反对票。 @Bhargav Rao Ah 无论如何,我没有说那是你投反对票:我并不是要指责任何人,我只是在谈论一般只是希望得到解释以改善我的行为进入堆栈溢出以对我自己和这个很棒的社区中的其他人都有帮助:我会慢慢来,我还是新手,;-) 您的回答具有误导性。说“现在像 Java 等其他基于类的语言一样使用它们是正确的”是不正确的。 Java 是一种基于 OO 类的语言。类的实例在每个创建的实例上制作副本属性。 JS 中的“类”只不过是连接到其他对象(OLOO)的对象的语法糖——这是 JS 所基于的基本模型。 OLOO 模型将始终使用原型链来提供“继承”(实际上是委托),从来没有真正的“实例”属性的副本。 “类”不像真正的 OO 语言那样是静态的。【参考方案9】:

虽然 JavaScript 在 ES6 之前没有类,但类行为可以在 ES5 中通过密封对象来实现(从而使对象不可扩展)。在密封对象中,不能添加新的属性和方法,并且属性是不可配置的。仍然可以设置和读取属性 values。我说类,因为有一个警告。密封对象的方法定义仍然可以修改。这是因为属性值仍然可以设置,除非您将所有方法属性更改为不可写——此时您已经使用 ES5 非常接近地重现了类行为。

【讨论】:

【参考方案10】:

简单来说 - 是的。你所需要的只是 Babel.js 转译器,因为除了 Chrome 浏览器之外所有浏览器都不支持它。 JavaScript 类是一种函数。类是用 class 关键字声明的。我们使用函数表达式语法来初始化一个函数,使用类表达式语法来初始化一个类。

这里是一个使用函数的 JavaScript 类的例子:

class Rectangle 
  constructor(height, width) 
    this.height = height;
    this.width = width;
  
  // Getter
  get area() 
    return this.calcArea();
  
  // Method
  calcArea() 
    return this.height * this.width;
  


const square = new Rectangle(10, 10);

console.log(square.area); // 100

【讨论】:

【参考方案11】:

来自 You-Dont-Know-JS 本书https://github.com/getify/You-Dont-Know-JS

第 4 章:混合(向上)“类”对象

...

JS 有一些类似类的句法元素(比如 new 和 instanceof) 有一段时间了,最​​近在 ES6 中,一些 添加,例如 class 关键字。

但这是否意味着 JavaScript 实际上有类? 简单明了: 没有

我不打算在这里复制和跳过其他部分,但鼓励阅读第 3 章第 4 章并运行示例。

https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch3.md

https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch4.md

【讨论】:

很好的参考! 固定链接:You Don't Know JS: this & Object Prototypes Chapter 3: ObjectsYou Don't Know JS: this & Object Prototypes Chapter 4: Mixing (Up) "Class" Objects【参考方案12】:

class Rectangle 
  constructor(height, width) 
    this.height = height;
    this.width = width;
  
  // Getter
  get area() 
    return this.calcArea();
  
  // Method
  calcArea() 
    return this.height * this.width;
  


const square = new Rectangle(10, 10);

console.log(square.area); // 100

【讨论】:

以上是关于JavaScript 有类吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 Javascript 更新 Wordpress 编辑器中的默认类吗?

OOP in Javascript

我可以在条件 [ngCLASS] 下编写 CSS 类吗

JavaScript原型链的理解

实现javascript下的模块组织

实现javascript下的模块组织