3

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

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

这是创建对象的示例:

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

这真的是我想要的。但是,所有其他类的实现都有不同的方法。所有这些最终都具有作为类的函数。


编辑:(澄清)

通常的做法:

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

我的做法:

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

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

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

欢迎任何帮助或批评。

4

3 回答 3

1

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

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

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

另一方面,当您只想要一个“实例”时,您所做的一切都很好。

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 
于 2012-12-07T14:58:06.833 回答
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

于 2012-12-07T15:05:41.280 回答
0

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

如果我们有这个:

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

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

我们使用该Foo函数作为构造函数创建了一个新对象。在对象的创建中加入一些逻辑很方便。


它还允许您设置继承的值。通过向 的.prototype对象添加属性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传递,那么新对象将继承自.basebase

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"
于 2012-12-07T15:03:55.513 回答