JavaScript 是面向对象的吗?

IT技术 javascript oop
2021-01-14 04:09:55

关于 JavaScript 是否是面向对象的语言一直存在一些问题。甚至声明,“仅仅因为一种语言有对象并不能使它成为面向对象。”

JavaScript 是面向对象的语言吗?

6个回答

IMO(这只是一种意见)面向对象语言关键特征是它将支持polymorphism几乎所有动态语言都这样做。

下一个特性是封装,这在 Javascript 中也很容易做到。

然而,在许多人的脑海中,继承(特别是实现继承)会在语言是否有资格被称为面向对象方面取得平衡。

Javascript 确实提供了一种相当简单的方法来通过原型设计继承实现,但这是以封装为代价的。

因此,如果您的面向对象标准是多态性、封装性和继承性的经典三人组,那么 Javascript 就不会通过。

编辑:提出补充问题“原型继承如何牺牲封装?” 考虑这个非原型方法的例子:-

function MyClass() {
    var _value = 1;
    this.getValue = function() { return _value; }
}

_value 属性是封装的,不能被外部代码直接修改。我们可能会向类添加一个 mutator,以完全由属于类的代码控制的方式对其进行修改。现在考虑对同一类的原型方法:-

function MyClass() {
  var _value = 1;
}
MyClass.prototype.getValue = function() { return _value; }

嗯,这是坏了。由于分配给 getValue 的函数不再在 _value 的范围内,因此无法访问它。我们需要将 _value 提升为 of 的属性,this但这将使其在为类编写的代码控制之外可访问,因此封装被破坏。

尽管如此,我仍然认为 Javascript 是面向对象的。为什么?因为给定一个OOD,我可以在 Javascript 中实现它。

原型继承如何牺牲封装?
2021-03-31 04:09:55
面向对象的更真实的定义将基于“消息传递”;在任何面向对象语言中,主要的设计方法是“对象将消息传递给其他对象”而不是“访问和修改字段”。方法调用是一种流行的消息传递形式。多态和继承不是 OO 的固有属性,它们只是由于静态类型的限制而必需的;封装是消息传递系统所固有的(因为您从不直接访问变量,您只是将消息发送给其他对象),但这不是 OO 的主要关注点。
2021-04-03 04:09:55
郑重声明,JavaScript 在这方面并不是独一无二的。Python 也没有强制封装的机制。Python 对象的所有成员实际上都是公共的,并且 Python 仅使用命名约定来指示成员应被视为“私有”。但是没有人质疑 Python 是否是一种面向对象的语言。
2021-04-05 04:09:55
封装需要在构造对象时创建的执行上下文中存储私有数据。添加到原型的成员无权访问此执行上下文,因此无法访问封装的数据。
2021-04-07 04:09:55
你是对的,C# 不是必需的,我没有抓住重点。然而,重点应该是这个。封装不等于信息隐藏。IH 是一个与封装相关的概念。信息隐藏是您编辑提示的内容。封装比这更具概念性。它指的是外部世界用来与对象交互的内容。这就是 Scott Koon 的问题。
2021-04-09 04:09:55

简短的回答是肯定的。想要查询更多的信息:

来自维基百科

JavaScript 在很大程度上是基于对象的。对象是关联数组,增加了原型(见下文)。对象属性名称是关联数组键:obj.x = 10 和 obj["x"] = 10 是等效的,点符号只是语法糖。可以在运行时添加、更改或删除属性及其值。对象的属性也可以通过 for...in 循环枚举。

另外,请参阅有关使用 Javascript 进行 OOP 的系列文章

Javascript 是一种多范式语言,支持过程式、面向对象(基于原型)和函数式编程风格。

这是一篇讨论如何在 Javascript 中执行 OO文章

语言不需要完全像 Java 那样面向对象。Javascript 中的一切都是对象;与 C++ 或更早的 Java 相比,后者在某种程度上被广泛认为是面向对象的,但仍然基于原语。多态性在 Javascript 中不是问题,因为它根本不关心类型。语法不直接支持的唯一核心 OO 特性是继承,但可以很容易地实现,无论程序员想要使用原型:是一个这样的例子。

我知道JavaScript有基本类型,但是我真的不认为他们通常意义上的这样,因为他们仍然充当状物体(除了那些明确表示“无”)。typeof("foo") 给你“字符串”而不是“对象”,是的,但字符串仍然有方法;"foo".substr(1) 有效。
2021-03-20 04:09:55
挑剔:Javascript 也有原始值,它们不是对象。未定义、空值、布尔值、数字和字符串,需具体说明。
2021-03-26 04:09:55
哈,我不是要煽动战争,只是与一种几乎被普遍认为是面向对象的语言进行比较。也许我应该澄清一下。
2021-03-30 04:09:55
@InternetFriend - typeof(null) = 'object', boolean, number 和 string 都是扩展对象的类,undefined 从来不是一个值,根据定义,它是没有值的,它本身被定义为一个属性
2021-03-31 04:09:55
我删除了我的评论,因为它不再相关。请散开,这里没什么可看的:)
2021-04-09 04:09:55

是和否。

正如 Douglas Crockford 所说,JavaScript 是“世界上最容易被误解的编程语言”他有一些关于 JavaScript 的很棒的文章,我强烈建议您阅读有关 JavaScript 到底是什么的文章它与 LISP 的共同点比 C++ 多。

特别是这篇文章与这个问题有关:javascript.crockford.com/prototypal.html
2021-04-01 04:09:55