除了命名空间之外,我不清楚您要做什么,但我在下面的分隔符下包含了各种代码审查。首先是更多高级 cmets。
这里有几个问题。首先,你几乎从不想写new function() { }。这是一种非常先进的技术,很容易出错(对于任何对代码进行维护的人来说都很容易误解)。下面是获得相同效果(以及其他一些好处)的另一种不太容易混淆的方法的示例。
这是一个命名空间模块的示例,它提供了两个“类”,Cat 和 Lion(我将它们设置为初始上限,因为这是通常的约定:构造函数的初始大写和非构造函数,只是为了方便代码阅读):
var Animals = (function() {
var publics = {};
// A Cat
publics.Cat = Cat;
function Cat() {
this.eyes = 2;
this.legs = 4;
this.diet = 'carnivore';
}
// A Lion
publics.Lion = Lion;
function Lion() {
this.mane = true;
this.origin = 'Africa';
this.diet = 'people'; // has priority over cat's diet
}
Lion.prototype = new Cat();
// Return our public symbols
return publics;
})();
// Usage
var l = new Animals.Lion();
alert(l.eyes); // alerts "2" (inherited from Cat)
alert(l.diet); // alerts "people" (overridden by Lion)
(当然,你可以调用publics 任何你想要的东西——pubs、p 等等。它相当于this 在你的new function() { } 函数的最外层,但不那么混乱.)
但是仅仅替换Lion 上的原型有点简单。当您开始进行子类化时,您还需要考虑其他几件事。 Here's a blog post 详细介绍了一种相当完整的构建类的方法,包括子类化、调用超类函数等。
就按字符串查找内容而言,您可以在任何对象上使用方括号表示法:
var obj = {};
obj.foo = 42;
alert(obj["foo"]); // alerts "42" by retrieving the property "foo" from `obj`
var x = "f" + "o" + "o";
alert(obj[x]); // alerts "42" by retrieving the property "foo" from `obj`
代码审查如下。
这是一个代码审查:
// Namespace all my code
// [TJC] Use the (function() { ... })(); mechanism described above rather than
// `new function() { ... }`, which is fairly confusing to the reader and troublesome
// to use inside inner functions (see below)
var bab = new function() {
// Declare cat object
// [TJC] Convention is to use initial caps for constructor functions,
// e.g. "Cat" not "cat"
function cat()
{
this.eyes = 2;
this.legs = 4;
this.diet = 'carnivore';
// [TJC] Don't return anything out of constructor functions
return true;
}
// Declare lion object
// [TJC] "Lion" rather than "lion" would be more conventional
function lion()
{
this.mane = true;
this.origin = 'Africa';
this.diet = 'people'; // has priority over cat's diet
// [TJC] Don't return anything out of constructor functions
return true;
}
// Make lion a subclass of cat
// [TJC] There are several other things you want to consider in
// addition to replacing the prototype
lion.prototype = new cat();
// Create an instance of class lion
// [TJC] From your usage below, it looks like you
// want to be able to look up "simba" using a string
// later. So use the below rather than this commented-out
// line:
//var simba = new lion();
var instances = {}; // [TJC]
instances.simba = new lion(); // [TJC]
// Share diet publicly
// [TJC] You don't need a function for this at all, just
// expose "instances" directly. But if you want it:
this.objInfo = function(name) {
// [TJC] To look up something by name using a string,
// use brackets:
//return name; // simba works, name doesn't
return instances[name]; // [TJC]
};
};
alert(bab.objInfo('simba').diet);