2

我正在 JS 中处理一个相当复杂的对象,但遇到了问题:

我有以下(删节)代码:

var LocationSelector;

LocationSelector = function(container) {
  this.selectors = {
    container: container,
    city_name: container.find('input.city_name'),
    city_id: container.find('input.city_id')
  };
  return this.initialize();
};

LocationSelector.prototype = {
  initialize: function() {
    return this.city.checkStatus();
  },
  city: {
    status: null,
    message: null,
    id: null,
    checkStatus: function() {
      if (LocationSelector.selectors.city_name.val() && LocationSelector.selectors.city_id.val()) {
        return LocationSelector.city.setStatus('success');
      }
    },
    setStatus: function(status) {
      return alert(status);
    }
  }
};

两个问题:

1) 子对象函数内部this不再引用根对象。如果我写出来,似乎我可以参考父母LocationSelector.object.method( args ),但要输入的内容很多。有没有办法定义返回父对象的快捷方式?

2) 在某些情况下,我需要每页有几个 this 实例,所以对我来说很重要的是,我可以在selectors实例化新对象时设置各种实例,然后在原型中引用实例选择器。LocationSelector在子对象方法中引用父对象(即)是否可行?JS 如何知道要保留当前活动对象的存储属性?

基本上,我正在尝试实现一个类,而我对 JS 完全陌生,并不真正知道如何去做。因此,感谢任何帮助或建议。谢谢!

4

3 回答 3

6

你目前的方法有很多问题。这是更接近你想要的东西,虽然我不明白为什么LocationSelector实例有一个city成员。

function LocationSelector(container) {
  this.selectors = {
    container: container,
    city_name: container.find("input.city_name"),
    city_id: container.find("input.city_id")
  };

  this.city = new City(this);
  this.city.checkStatus();
}

function City(locationSelector) {
  this.status = null;
  this.message = null;
  this.id = null;
  this.locationSelector = locationSelector;
}

City.prototype.checkStatus = function () {
  if (this.locationSelector.selectors.city_name.val() && this.locationSelector.selectors.city_id.val()) {
    this.setStatus("success");
  }
};

City.prototype.setStatus = function () {
  alert("status");
};

注意事项:

  1. 数据属性在实例上,而不是原型上。只有方法在原型上。
  2. City显然是它自己的类,所以你应该把它变成一个。在您的代码中,一个城市在 的所有实例之间共享LocationSelector,因为它放在原型上。在此代码中,它在LocationSelector构造函数中被分配为实例属性。
  3. 您不能LocationSelector.selectors像在示例中那样引用。LocationSelector.selectors将用于“静态”属性,它LocationSelector没有。相反,您需要参考selectors特定实例的属性;在本例中,该实例由 给出this.locationSelector
  4. 第 2 点和第 3 点说明了一个重要事实:“子”City实例在没有具体实例的情况下无法引用“父”LocationSelector类的属性。

这是对我来说更有意义的代码版本,删除了LocationSelector具有city属性的部分(它不使用)。

function LocationSelectors(container) {
  this.city_name = container.find("input.city_name");
  this.city_id = container.find("input.city_id");
}

function City(locationSelectors) {
  this.locationSelector = locationSelector;
}

City.prototype.checkStatus = function () {
  if (this.locationSelectors.city_name.val() && this.locationSelectors.city_id.val()) {
    this.setStatus("success");
  }
};

City.prototype.setStatus = function () {
  alert("status");
};

function checkCityStatus(container) {
  var locationSelectors = new LocationSelectors(container);
  var city = new City(locationSelectors);

  city.checkStatus();
}

我给你留下了Crockford 的“Private Members in JavaScript”的链接,它谈到了在 JavaScript 中做 OO。还有其他可能更好的解释,但至少那个会让你走上正确的轨道。

于 2012-04-23T04:55:21.080 回答
2

阅读闭包,我很肯定你会找到你需要的东西。

这是您要完成的工作的一个简单示例:

function MyCoolObject(name){
   var self_myCoolObject = this;
   this.name = name;
   this.popAlertWithNameInFiveSeconds = function(){
       setTimeout(function(){
         alert('Incorrect reference to name "this.name" returns ' + this.name);
         alert('Correct reference to name "self_myCoolObject.name" returns ' + self_myCoolObject.name);
       },5000)
   }
}

//TO TEST
var MyObj = new MyCoolObject('MySuperCoolName')
MyObj.popAlertWithNameInFiveSeconds();
于 2012-04-23T04:40:14.367 回答
0

这是我拥有的一段 JS 代码。在我进入点击处理程序之前,我SlideShow通过调用来引用对象 () var parent = this。然后在以后的嵌套函数中,您可以确保您通过使用调用正确的范围parent.function()

/* Slide Show object */
function SlideShow(parentContainerId) {

    this.BEGINNING  = 'Beginning';
    this.END        = 'End of list';
    this.FIRSTINDEX = 0;

    this.length     = jQuery(parentContainerId + ' img').length;
    this.container  = jQuery(parentContainerId);
    this.imgs       = jQuery(parentContainerId + ' img');
    this.index      = this.FIRSTINDEX;
    this.status     = 'beginning';           // beginning, end



    this.init = function() {
        // get it started
        this.moveTo(this.FIRSTINDEX);
        this.process();

        // ****GET OBJECT SCOPE*****
        var parent      = this;

        // set up click listener
        this.container.find('img').click(function(e) {
            var item_width = jQuery(this).width();
            var x_click_ps = e.clientX - jQuery(this).offset().left;
            var x_diff     = x_click_ps / item_width;




            console.log(this);
            if (x_diff < .5) {
                parent.moveByIncrement(-1)
                parent.process();
            } else {
                parent.moveByIncrement(1);
                parent.process();
            }

        });
    }


.
.
.
}
于 2014-08-06T21:17:27.923 回答