为什么函数用于javascript中的类?

为什么函数用于javascript中的类?,javascript,Javascript,我正在开发一个小型库,根据用户提供的规范构建对象。它们可以具有继承性和更多的类特性 但是,我的方法不同于通常的方法,因为我不使用函数作为类 这是一个已创建对象的示例: var objectTest = { someVar: 5, someMethod: function () {...} }; 这才是我真正想要的。但是,所有其他类实现都有不同的方法。所有这些函数都以类的形式结束 编辑:(澄清) 通常做法: 将函数用作类 使用“new className()”创建新函数并将其

我正在开发一个小型库,根据用户提供的规范构建对象。它们可以具有继承性和更多的类特性

但是,我的方法不同于通常的方法,因为我不使用函数作为类

这是一个已创建对象的示例:

var objectTest = {
    someVar: 5,
    someMethod: function () {...}
};
这才是我真正想要的。但是,所有其他类实现都有不同的方法。所有这些函数都以类的形式结束


编辑:(澄清)

通常做法:

  • 将函数用作类
  • 使用“new className()”创建新函数并将其用作对象
我的做法:

  • 使用库指定基值/方法以及它们如何相互继承
  • 使用“myLib.Create('className')”创建新对象并将其用作对象

我能理解它背后的原因,使用原型可能更符合逻辑

但是我想知道我的方法是否有我看不到的缺点,或者我正在做的是什么叫做其他的东西


欢迎任何帮助或批评。

与使用原型相比,您的方法有以下缺点:

  • 为对象的每个值定义一个新函数:这会减慢对象的创建速度,并占用无用的内存
  • 您不能像使用prototype那样定义继承
因此,您并不是真正定义一个类,因为只有当存在共享相同行为的实例,但只有一个对象时,类才有意义

另一方面,当您只需要一个“实例”时,您所做的是非常好的

MDN提出了一个解决方案


为什么我说为每个实例定义一个新函数:

var obj1 = {
    someVar: 5,
    someMethod: function () {console.log(this.someVar)}
};
var obj2 = {
    someVar: 5,
    someMethod: function () {console.log(this.someVar)}
};
console.log(obj1.someMethod==obj2.someMethod); // logs false
虽然原型的使用不会复制该功能:

function MyClass(avar){
    this.someVar = avar;
}
MyClass.prototype.someMethod = function(){
    console.log(this.someVar);
};
var obj1 = new MyClass();
var obj2 = new MyClass();
console.log(obj1.someMethod==obj2.someMethod); // logs true 

JavaScript只允许将函数用作对象的构造函数

如果我们有:

function Foo() {
    this.bar = "bar";
}

var b = new Foo();
alert(b.bar); "bar"
我们使用
Foo
函数作为构造函数创建了一个新对象。在对象的创建中加入一些逻辑是很方便的


它还允许您设置继承的值。通过向
Foo
.prototype
对象添加属性,您创建的新对象将继承这些属性

function Foo() {
    this.bar = "bar";
}
Foo.prototype.alertBar = function() {
    alert(this.bar);
}

var b = new Foo();
b.alertBar();
因此,现在
b
对象自动继承
alertBar
方法,即使它没有在对象上明确定义


绝对不需要将函数用作构造函数。如您所知,您可以只使用文字语法来创建单个对象

您还可以设置继承,而无需使用构造函数。假设您希望某些对象都从一组值继承。您可以使用
对象来完成此操作。创建

var base = {
    foo: "bar"
};
现在,如果我们使用
Object.create
创建新对象,并且如果我们将
base
作为第一个参数传递,那么新对象将从
base
继承

var a = Object.create(base);
var b = Object.create(base);
var c = Object.create(base);

a.foo; // "bar"
b.foo; // "bar"
因此,您可以看到,我们可以在不使用构造函数的情况下创建对象,但仍然可以获得原型继承的好处


最后,您可以将函数与普通对象结合起来创建新对象,而无需将函数实际用作典型的构造函数。要做到这一点,您只需要让函数返回一个使用文本语法创建的对象

var fooMaker = (function() {

    var getBar = function() {
        return this.bar;
    };

    return function fooMaker() {

        return {
            bar: "bar",
            getBar: getBar
        };
    };
})();
var f = fooMaker();

f.getBar(); // "bar"

您看到用于类概念的函数的原因是作用域。JavaScript是函数作用域,因此对于包含(即没有命名空间或类型名冲突等),函数是捕获作用域的一种方法。在JavaScript中的对象定义上,所有内容基本上都是公共集合的一部分。如果这是你需要的行为,那么你的方法是好的。如果您需要保护任何变量或方法以使其私有,或者将服务范围限定到一个唯一的命名空间以避免冲突或允许扩展,那么您需要了解函数和闭包,并将它们作为类周围的服务来实现

下面是一篇关于将此范围扩展到模块级别的精彩文章:

以及原型级别:

javascript中的所有内容都是对象,“基于类的javascript”只是一个类似类的界面,用于管理对象。不,我没有为对象的每个值定义新函数。它们是字符串/数字/布尔值或其他类型。你从哪里得到这个主意的?在生成此对象之前,继承是在内部完成的。@jsnoob:请参见编辑,了解我为什么说每次定义一个新函数。我理解你的意思,你说得对,它们没有指向同一个函数。FWIW,“速度和内存”参数有点像是在转移注意力。我曾经编写过有数千个对象的游戏,只使用模块模式跟踪数百个DOM元素,没有任何原型继承,即使在IE6上,游戏也运行良好。普通对象是相当轻量级的。通常,页面上DOM对象的数量会降低速度。你用
document.createElement
,而不是构造函数来创建它们。你给你的对象添加了重复的函数吗?你混淆了作用域(和闭包)和继承链(在javascript中通常称为“上下文”,你似乎称为“原型级别”)。它们是完全不同的东西,最好不要混淆它们。