【问题标题】:Object vs Class vs Function对象 vs 类 vs 函数
【发布时间】: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'

当然,类有方法和属性并且可以被实例化——但是,我可以对任何旧函数做同样的事情——或者不?

【问题讨论】:

  • 类现在在许多 post node.js Javascript 库等中很常见。说 Javascript 中没有类 不再正确。现在有类,浏览器实现还没有很好地支持这些类(还没有),但是在 NPM 和 Node.js 时代,类在很大程度上是语言向前发展的核心概念(这只是我当时欣赏的仅供参考在这里写第一条评论是正确的)。

标签: javascript class oop


【解决方案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 中的文字值被视为原语。例如文字true3.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!~');
        }
    };
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 2012-09-27
    • 1970-01-01
    • 2013-03-09
    相关资源
    最近更新 更多