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

时间:2012-12-07 14:55:54

标签: javascript

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

但是,我的方法与通常的方法不同,因为我没有将函数用作类。

这是创建对象的示例:

var objectTest = {
    someVar: 5,
    someMethod: function () {...}
};

这就是我想要的。但是,所有其他类实现都有不同的方法。所有这些都最终具有类的功能。


编辑:(澄清)

通常的做法:

  • 使用函数作为类。
  • 使用“new className()”创建新函数并将它们用作对象。

我的方法:

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

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

但我想知道我的方法是否有任何我看不到的缺点,或者我正在做的事情被称为别的东西。

欢迎任何帮助或批评。

3 个答案:

答案 0 :(得分:1)

与使用原型相比,您的方法存在这些缺点:

  • 为对象的每个值定义一个新函数:这会减慢对象的创建速度,这会占用无用的内存
  • 您不能像使用原型
  • 那样定义继承

所以你并没有真正定义一个类,因为只有当实例共享相同的行为但只有一个对象时才有意义。

另一方面,当你只想要一个“实例”时,你所做的就完全没问题了。

MDN提出good guide on prototypal inheritance


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

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 

答案 1 :(得分:0)

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

如果我们有这个:

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

var b = new Foo();
alert(b.bar); "bar"

我们使用Foo函数作为构造函数创建一个新对象。在创建对象时放置一些逻辑很方便。


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

Foo

所以现在function Foo() { this.bar = "bar"; } Foo.prototype.alertBar = function() { alert(this.bar); } var b = new Foo(); b.alertBar(); 对象会自动继承b方法,即使它没有在对象上明确定义。


绝对没有要求使用函数作为构造函数。如您所知,您可以使用文字语法来创建单个对象。

您也可以在不使用构造函数的情况下设置继承。假设您想要一些应该从一组值继承的对象。您可以使用alertBar完成此操作。

Object.create

现在,如果我们使用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"

答案 2 :(得分:0)

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

以下是关于将此范围界定到模块级别的精彩帖子: http://weblogs.asp.net/dwahlin/archive/2011/08/02/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-module-pattern.aspx

原型级别: http://weblogs.asp.net/dwahlin/archive/2011/08/03/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-prototype-pattern.aspx