【问题标题】:Javascript sub prototypingJavascript子原型
【发布时间】:2014-02-07 01:32:33
【问题描述】:

我有一个关于子原型的问题。

例如,我想做类似的事情:

var Foo = function() { this.Bar.prototype.Foo = this.Baz.prototype.Foo = this };
Foo.prototype.is = "foo";
Foo.prototype.Iam = function() { return this.is };

Foo.prototype.Bar = function() {};
Foo.prototype.Bar.prototype.is = "bar";
Foo.prototype.Bar.prototype.Iam = function() { return this.Foo.is + this.is };

Foo.prototype.Baz = function() {};
Foo.prototype.Baz.prototype.is = "baz";
Foo.prototype.Baz.prototype.Iam = function() { return this.Foo.is + this.is };

var foo = new Foo();
var bar = new foo.Bar();
var baz = new foo.Baz();

console.log(foo.Iam()); // output: foo
console.log(bar.Iam()); // output: foobar
console.log(baz.Iam()); // output: foobaz

为了访问 Bar 和 Baz 中的 Foo 对象,我使用 this.Bar.prototype.Foo = this.Baz.prototype.Foo = this 扩展了 Bar 和 Baz 的原型。

我的问题是,是否存在一种更简单的方法来执行此操作并访问 Bar 和 Baz 中的主要对象 Foo,或者这是常见的方法吗?我想这样做的原因是创建一个主对象var x = new Foo(),并且所有子对象都可以访问主对象。

【问题讨论】:

  • 您当前的方法似乎相当不错 - 每个类大约 1 条语句将其混合在一起。
  • 这种“子原型设计”是一种实际被某些人使用的模式吗?
  • 我看不出有任何理由对作为函数构造函数的 Bar 或 Baz 进行原型设计。我写下了我的变体以在 Foo 中包含 Bar 和 Baz

标签: javascript prototype


【解决方案1】:

我还没有看到使用太多的子原型。我发现只有这样:

var Foo = function() {};
Foo.prototype.is = "foo";
Foo.prototype.Iam = function() { return this.is };

Foo.prototype.Bar = function() {};
Foo.prototype.Bar.prototype.foo = new Foo();
Foo.prototype.Bar.prototype.is = "bar";
Foo.prototype.Bar.prototype.Iam = function() { return this.foo.is + this.is };

Foo.prototype.Baz = function() {};
Foo.prototype.Baz.prototype.foo = new Foo();
Foo.prototype.Baz.prototype.is = "baz";
Foo.prototype.Baz.prototype.Iam = function() { return this.foo.is + this.is };

var foo = new Foo();
var bar = new foo.Bar();
var baz = new foo.Baz();

console.log(foo.Iam()); // output: foo
console.log(bar.Iam()); // output: foobar
console.log(baz.Iam()); // output: foobaz

【讨论】:

    【解决方案2】:
    Foo.prototype.Bar = function() {};
    Foo.prototype.Bar.prototype.foo = new Foo();
    

    是的,这正是我大多数时候发现的,但如果我这样做,那么对 Foo() 的更改就会丢失。

    在上面的示例中,我可以将“全局”参数设置为 Foo(),这些参数可从 Bar() 和 Baz() 访问。示例:

    var extend = function(a, b) {
        var n;
        for (n in b) {
            a[n] = b[n];
        }
    };
    
    var Foo = function(o) {
        extend(this, o);
        this.Bar.prototype.Foo = this.Baz.prototype.Foo = this;
    };
    
    Foo.prototype.is = "foo";
    Foo.prototype.Iam = function() { return this.is };
    Foo.prototype.greeting = "hello, I am";
    
    Foo.prototype.Bar = function() {};
    Foo.prototype.Bar.prototype.is = "bar";
    Foo.prototype.Bar.prototype.Iam = function() { return this.Foo.greeting +" "+ this.Foo.is + this.is };
    
    Foo.prototype.Baz = function() {};
    Foo.prototype.Baz.prototype.is = "baz";
    Foo.prototype.Baz.prototype.Iam = function() { return this.Foo.is + this.is };
    
    var foo = new Foo({ greeting: "hi my friend, I am" });
    var bar = new foo.Bar();
    console.log(bar.Iam());
    
    //output is: hi my friend, I am foobar
    

    我将问候语设置为可从所有子函数访问的 Foo()。这样做的原因是对象存在不同的“全局”参数。如果在 Foo() 上更改了“全局”参数,那么它应该会影响 Bar() 和 Baz()。

    我真的不知道这是否是正确的方法,因为我刚开始学习 Javascript。我乐于接受新想法。

    问候, 强尼

    【讨论】:

      【解决方案3】:

      也许这就是你要找的东西:

      var extend = function(a, b) {
          var n;
          for (n in b) {
              a[n] = b[n];
          }
      };
      
      var Foo = function(o) {
          extend(this, o);
          var foo = this;
      
          this.Bar = function() {};
          this.Bar.prototype.is = "bar";
          this.Bar.prototype.Iam = function() { return foo.is + this.is };
      
          this.Baz = function() {};
          this.Baz.prototype.is = "baz";
          this.Baz.prototype.Iam = function() { return foo.is + this.is };
      };
      Foo.prototype.is = "foo";
      Foo.prototype.Iam = function() { return this.is };
      
      var foo = new Foo({ is: "foo2" });
      var bar = new foo.Bar();
      var baz = new foo.Baz();
      
      console.log(foo.Iam()); // output: foo2
      console.log(bar.Iam()); // output: foo2bar
      console.log(baz.Iam()); // output: foo2baz
      

      【讨论】:

        【解决方案4】:

        Foo 只有一个实例,因此您可以将 foo 声明为对象字面量:

        var foo = {
          is:"foo",
          Iam:function(){return this.is}
        };
        
        foo.Bar = function() {};
        foo.Bar.prototype.is = "bar";
        
        foo.Baz = function() {};
        foo.Baz.prototype.is = "baz";
        
        foo.Bar.prototype.Iam = foo.Baz.prototype.Iam 
          = function() { return foo.is + this.is };
        
        var bar = new foo.Bar();
        var baz = new foo.Baz();
        
        console.log(foo.Iam()); // output: foo
        console.log(bar.Iam()); // output: foobar
        console.log(baz.Iam()); // output: foobaz
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-01
          • 2014-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-16
          相关资源
          最近更新 更多