简体   繁体   English

Javascript:在该对象中调用对象方法

[英]Javascript: Calling object methods within that object

What is the best design pattern for achieving the following (which doesn't work)? 实现以下目标的最佳设计模式是什么(不起作用)?

var obj = (function() {

  // code defining private variables and methods

  var _obj = {
    property: value,
    method1: function() {
      // do stuff
    },
    method2: function() {
      // use property
      var prop = _obj.property; // obviously doesn't work
      // call method1
      obj.method1(); // "obj" not finished being defined yet!
    }
  };

  // obviously now I could do...
  var prop = _obj.property;

  return _obj;

})();

// and I could now do...
obj.method1();

A variation which I think should work is 我认为应该有的变化是

var obj = (function() {

  var property = value,
      method1 = function() {
        // do stuff
      },
      method2 = function() {
        // use property
        var prop = property;
        // call method1
        method1();
      },
      _obj = {
        property: property,
        method1: method1,
        method2: method2
      };

  return _obj;

})();

Similarly, how does it work for objects meant to be created with the new operator? 同样,它如何用于使用new运算符创建的对象? Within the constructor function itself you can write this.method() . 在构造函数本身中,您可以编写this.method() But what if you want to keep the constructor small, only defining those things which will likely be customized upon creation, and then defining the rest in the prototype? 但是如果你想保持构造函数很小,只定义那些可能在创建时自定义的东西,然后在原型中定义其余的东西呢? (This seems to be the common pattern.) Can the properties / methods within the prototype interact in any way? (这似乎是常见的模式。)原型中的属性/方法可以以任何方式进行交互吗?

var MyObj = function(name) {
  this.name = name;
};

var obj = new MyObj('Bob');

MyObj.prototype = {
  called_often: function() {
    // lots more code than just the following
    return document.getElementById('someID').value;
  },

  global_default: 'value', // can be changed, so need to pull value when run

  does_stuff: function(value) {
    var str = global_default + value, // can't access global_default on its own
        input = MyObj.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
        name = this.name; // 'this' used in the prototype doesn't work
                          // even within a created object
    return name + input + str;
  }
};

I'm sure there's better ways to achieve my result whenever I run into this problem. 我确信每当遇到这个问题时,有更好的方法来实现我的结果。 This code isn't situation specific and just illustrates the general problem. 此代码不是特定于具体情况,只是说明了一般问题。 So you won't be able to give me an alternative for those specific situations I run into. 因此,您无法为我遇到的特定情况提供替代方案。 But maybe you can help my overall thinking. 但也许你可以帮我整体思考。

Well, from your first example: 好吧,从你的第一个例子:

var _obj = {
    property: value,
    method1: function() {
      // do stuff
    },
    method2: function() {
      // use property
      var prop = this.property; 
      // call method1
      this.method1(); 
    }
  };

That's what the this value is for. 这就是this值的用途。

Now, what you cannot do is refer to a property of an "under construction" object from elsewhere in the object literal syntax. 现在,您不能做的是从对象文字语法中的其他地方引用“正在构建”对象的属性。 (It's hard to give an example because it's just not syntactically possible.) In cases where you want to do that, you do need one or more separate assignment statements. (很难给出一个例子,因为它在语法上是不可能的。)如果你想这样做,你需要一个或多个单独的赋值语句。

Guess what? 你猜怎么着? You are making simple stuff complex. 你正在制作复杂的简单东西。 Pointy's answer is good, but the prototype way is better for several reasons. Pointy的答案很好,但由于几个原因原型方法更好。 That's why I am describing (rather, making corrections in) the last method. 这就是我在最后一种方法中描述(而不是纠正)的原因。 Check this fiddle . 检查这个小提琴

var MyObj = function(name) {
  this.name = name;
};

MyObj.prototype = {
  called_often: function() {
    // lots more code than just the following
    return 'VALUE'; //document.getElementById('someID').value;
  },

  global_default: 'value', // can be changed, so need to pull value when run

  does_stuff: function(value) {
    var str = this.global_default + value, // can't access global_default on its own
        input = this.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
        name = this.name; // 'this' used in the prototype doesn't work
                          // even within a created object
    return name + input + str;
  }
};

var obj = new MyObj('Bob');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM