javascript - 命名空间,OOP JS,我这样做对吗?

标签 javascript oop namespaces

我的问题是 objInfo()。如何通过传入变量返回对象?我正在尝试为我的代码命名空间并使用私有(private)/公共(public)变量。

额外的问题:否则您会如何改进代码?

// Namespace all my code
var bab = new function() {

    // Declare cat object
    function cat()
    {
      this.eyes = 2;
      this.legs = 4;
      this.diet = 'carnivore';

      return true;
    }

    // Declare lion object
    function lion()
    {
      this.mane = true;
      this.origin = 'Africa';
      this.diet = 'people'; // has priority over cat's diet

      return true;
    }

    // Make lion a subclass of cat
    lion.prototype = new cat();

    // Create an instance of class lion
    var simba = new lion();

    // Share diet publicly
    this.objInfo = function(name) {
        return name; // simba works, name doesn't
    };

};

alert(bab.objInfo('simba').diet);

注意:来源是从各个地方采样的

最佳答案

除了命名空间之外,我不清楚您要做什么,但我在下面的分隔符下包含了各种代码审查。更多高层评论优先。

这里有几个问题。首先,您几乎从不想要编写 new function() { }。这是一种非常先进的技术,但很容易出错(而且任何维护代码的人都很容易产生误解)。下面是获得相同效果(加上一些其他好处)的另一种不太容易混淆的方法的示例。

这是一个命名空间模块的示例,它提供了两个“类”,CatLion(我将它们设置为初始上限,因为这是通常的约定:初始上限关于构造函数和非构造函数的初始小写,只是为了便于阅读代码):

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 称为您想要的任何其他名称 — pubsp 等等。它等同于 this 在您的 new function() { } 函数的最外层,但不那么困惑。)

但是仅仅替换 Lion 上的原型(prototype)有点简单。当您开始进行子类化时,您还需要考虑其他几件事情。 Here's a blog post详细介绍了构建类的相当完整的方法,包括子类化、调用父类(super class)函数等。

就按字符串查找内容而言,您可以在任何对象上使用括号表示法:

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);

关于javascript - 命名空间,OOP JS,我这样做对吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3742737/

相关文章:

javascript - 如何使用 ExpressJS 从 jQuery ajax post 获取数据

oop - 联合类型/扩展接口(interface)

java - 使用 OO 观察者模式而不更新从中发起更改的对象

c# - 两个VS2008 C#类库项目是否可以共享一个命名空间?

javascript - 打印href中js函数的结果

javascript - React Native - 如何执行非常柔和的振动?

PHP 命名空间奇数文件夹以 "t","s","n"结尾

django - 基于请求命名空间解析 URL

javascript - 当我使用 AJAX 时,Firefox 会忽略 Cache-Control no-store, no-cache

java - 基本的面向对象编程