对象 vs 类 vs 函数
Posted
技术标签:
【中文标题】对象 vs 类 vs 函数【英文标题】:Object vs Class vs Function 【发布时间】:2013-07-05 17:10:03 【问题描述】:我想知道 - javascript 对象、类和函数之间有什么区别? 我认为类和函数是对象的类型是否正确?
类和函数的区别是什么?还是它们真的是同一个东西,只是它们的术语会根据它们的使用方式而变化?
function func() alert('foo'); // a function
func(); // call the function - alerts 'foo'
var func2 = function () alert('hello'); // acts the same way as 'func' surely?
func2(); // alerts 'hello'
var Class = function() alert('bar'); ; // a class
var c = new Class(); // an istance of a class - alerts 'bar'
当然,类有方法和属性并且可以被实例化——但是,我可以对任何旧函数做同样的事情——或者不?
【问题讨论】:
类已在 ECMA 6 中引入:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 类现在在许多 post node.js Javascript 库等中很常见。说 Javascript 中没有类 不再正确。现在有类,浏览器实现还没有很好地支持这些类(还没有),但是在 NPM 和 Node.js 时代,类在很大程度上是语言向前发展的核心概念(这只是我当时欣赏的仅供参考在这里写第一条评论是正确的)。 【参考方案1】:JavaScript 没有类,函数实际上是 JavaScript 中的对象(一等公民)。 函数对象的唯一区别是它们是可调用的。
function func() alert('foo'); // a function
- 正确
func(); // call the function - alerts 'foo'
- 正确
var func2 = function () alert('foo'); // same as 'func' surely?
- 不,func2
是一个不同的对象,它在调用时显然做同样的事情。
var Class = function() alert('bar'); ;
- 这是一个没有名称存储在变量Class
中的函数。
var c = new Class();
- 调用存储在Class
中的函数,提供新的空对象作为this
并返回该对象。称为new functionA()
的函数应作为构造函数工作并准备一个新创建的对象(this
)。在你的情况下 - 构造函数对对象不做任何事情,只是提醒bar
。
【讨论】:
你应该澄清最后一句话。【参考方案2】:javascript 中没有类。但是,有一些方法可以让函数表现得像其他语言中的类。
这里给出了很好的解释3 way to define a class in js
另外,为OOP in Javascript找到了一个很好的参考
【讨论】:
从 ECMAScript 2015 开始,Javascript 中有有类 @Liam 是语法糖。它仍然是一个底层函数。 @NikitaShahov -- 这只是类在 javascript 中的实现方式,并不意味着没有类。甚至私人会员现在也即将成为现实。 (这是第 3 阶段的提案:github.com/tc39/proposal-private-methods)【参考方案3】:您现在必须知道,JavaScript 中没有类。相反,通过在函数调用前加上 new
关键字,可以使 JavaScript 中的函数表现得像构造函数。这被称为constructor pattern。
在 JavaScript 中,除了原始数据类型(布尔、数字和字符串)和 undefined
之外,一切都是对象。另一方面,null
实际上是一个对象引用,即使您起初可能不这么认为。这就是typeof null
返回"object"
的原因。
JavaScript 中的函数类似于 Lua 中的 functables(即它们是可调用对象)。因此,可以使用函数代替对象。同样,数组也是 JavaScript 中的对象。另一方面,对象可以被认为是关联数组。
然而,最重要的一点是 JavaScript 中没有类,因为 JavaScript 是一种原型面向对象的语言。这意味着 JavaScript 中的对象直接继承自其他对象。因此我们不需要类。我们所需要的只是一种创建和扩展对象的方法。
阅读以下主题以了解有关 JavaScript 中原型继承的更多信息:Benefits of prototypal inheritance over classical?
【讨论】:
@bits 恐怕你错了。您会看到 JavaScript 中有两种类型的布尔值,数字和字符串 - 基元和包装对象。 JavaScript 中的文字值被视为原语。例如文字true
、3.14
和"Hello World!"
都是原始数据类型。当您在它们上使用typeof
时,它们分别返回"boolean"
、"number"
和"string"
。然而,JavaScript 允许您将它们用作对象,并在需要时将它们强制转换为对象。因此,您可以执行"abc".slice(-1)
之类的操作。这就是我们在 JavaScript 中使用 valueOf
运算符的原因。
这个答案现在已经过时了
是的@DhavalJardosh
null 是原始值之一。它不是一个对象。 typeof null === "object" 简直就是 JS 近二十年来的一个 bug。
null 是原始值。【参考方案4】:
Object 是 JavaScript 中的基本类型,即所有用户定义的数据类型都以一种或另一种方式从 Object 继承。所以如果你定义了一个函数或者一个类[注意目前 JS 不支持类构造,但它在 ECMAScript 版本 6 中提出],它将隐式继承自 Object 类型。
类实际上用于将逻辑函数和属性封装到一种类型/实体中,您可以使用构造函数语法“新建”它。因此,如果您定义一个“客户”类,您可以多次实例化它,并且每个实例/对象可以有不同的值。如果您使用原型定义类级别的值,它们甚至可以共享这些值。
由于 JS 目前不支持类构造,因此函数实际上可以充当单独的方法,也可以充当其他函数或类型的容器。
我希望在 ECMAScript 6 中,我们可以清楚地区分这些结构,类似于我们在 C#、Java 等其他语言中的结构。
【讨论】:
【参考方案5】:JS 中的一个类:
function Animal()
// Private property
var alive=true;
// Private method
function fight() //...
// Public method which can access private variables
this.isAlive = function() return alive;
// Public property
this.name = "Joe";
// Public method
Animal.prototype.play = function() alert("Bow wow!");
// .. and so on
现在当你创建它的对象时
var obj = new Animal();
你可以期待这个对象的任何东西,就像你对其他语言的对象一样。只是实现它的努力,有点不同。您还应该查看inheritance in JS。
回到你的问题,我将它改写为:
Class : A representation of a set with common properties.
object : One from the set with the same properties.
var Class = function() alert('bar');; // A set of function which alert 'bar'
var object = new Class(); // One of the functions who alert's 'bar'.
【讨论】:
基于原型的编程不是“人们发现的一种模仿面向对象实践的方式”。它是一种面向对象编程的方式,早在 JavaScript 之前就发明了,并且是基于类的编程的替代方案。【参考方案6】:2015 年更新
JavaScript 中有一些类,它们只是在旧版浏览器上没有使用:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
它有构造函数、扩展等。
class Cat
constructor(name)
this.name = name;
speak()
console.log(this.name + ' makes a noise.');
class Lion extends Cat
speak()
super.speak();
console.log(this.name + ' roars.');
【讨论】:
我认为重要的是不要让新的类构造函数是最新 JavaScript 的一部分,因此仅受支持,它们只是一种新语法,它们实际上是函数,它们只是被设计为语法糖为了使代码更有条理,它们与函数构造函数没有任何不同。 这些仍然不是经典继承意义上的“类”,而只是用于连接链接到其他对象 (OLOO) 的对象的语法糖,以近似经典继承的行为。尽管关键字给了您这种错觉,但 JavaScript 中没有类。【参考方案7】:您还可以在 ES6 中获得如下所示的类:
//class
class Cat
//constructor
constructor()
this.name = 'Snowball';
//method
meow()
console.log('Hello, nyah! My name is ' + this.name + ' nyah!~');
;
【讨论】:
那个方法需要一个“函数”,不是吗? @sorak 不再,见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…以上是关于对象 vs 类 vs 函数的主要内容,如果未能解决你的问题,请参考以下文章