在其方法中使用with访问包含对象?

时间:2013-06-11 00:56:09

标签: javascript

在下面的代码段中,对象文字包含属性,其中一个属性是需要访问对象文字的方法。

然而,b.c。它仅用作事件处理程序回调,this始终指向触发事件的元素。

我需要访问包含对象。

否则,我被迫将函数放入一个看似奇怪的函数中。

/***************************************************************************************************
**MSimMenu - simple drop down menu
*/


    NS.parsel({
        Name: 'MSimMenu',
        E: {
            hold_name:         '#hold_name',
            wrap_bottom:       '#wrap_bottom'
        },
        A: {
            time_out_id:        null,
            TIME_DELAY:         1000
        },

        // in mouseout this points to the element that triggered the event
        // need access to containing object

        mouse_out: function () {
            this.A.time_out_id = NS.setTimeout(this.hideBottom, this.A.TIME_DELAY);
        },
        init: function () {
            var self = this;

            // tempoaray fix - function in function seems odd

            function mouse_out() {
                self.A.time_out_id = NS.setTimeout(self.hideBottom, self.A.TIME_DELAY);
            }

            self.E.hold_name.addEventListener("mouseover", function () {
                NS.clearTimeout(self.A.time_out_id);
                self.showBottom();
            }, false);
            self.E.wrap_bottom.addEventListener("mouseover", function () {
                NS.clearTimeout(self.A.time_out_id);
            }, false);
            self.E.wrap_bottom.addEventListener("mouseout", mouse_out, false);
            self.E.hold_name.addEventListener("mouseout", mouse_out, false);
        },
        showBottom: function () {
            this.E.wrap_bottom.style.visibility = 'visible';
        },
        hideBottom: function () {
            this.E.wrap_bottom.style.visibility = 'hidden';
        }
    });

使用绑定的最终代码

NS.parsel({
    Name: 'MSimMenu',
    E: {
        hold_name:         '#hold_name',
        wrap_bottom:       '#wrap_bottom'
    },
    A: {
        time_out_id:        null,
        TIME_DELAY:         1000
    },
    init: function () {
        var self = this;
        self.E.hold_name.addEventListener("mouseover", function () {
            NS.clearTimeout(self.A.time_out_id);
            self.showBottom();
        }, false);
        self.E.wrap_bottom.addEventListener("mouseover", function () {
            NS.clearTimeout(self.A.time_out_id);
        }, false);
        self.E.wrap_bottom.addEventListener("mouseout", self.mouse_out.bind(self), false);
        self.E.hold_name.addEventListener("mouseout", self.mouse_out.bind(self), false);
    },
    mouse_out: function () {
        this.A.time_out_id = NS.setTimeout(this.hideBottom, this.A.TIME_DELAY);
    },
    showBottom: function () {
        this.E.wrap_bottom.style.visibility = 'visible';
    },
    hideBottom: function () {
        this.E.wrap_bottom.style.visibility = 'hidden';
    }
});

3 个答案:

答案 0 :(得分:2)

我见过很多人创建一个变量来分配对象,然后使用变量。

var that = {
    myfunc:function(){
        console.log(that)
    }
};
NS.parsel(that);

答案 1 :(得分:1)

有很多方法可以让你得到你想要的东西。

您可以做的一个技巧是不直接使用mouse_out函数,但提供一个辅助函数,如get_mouse_out(),它返回函数的绑定版本。

var myobject = {
   data:"Some data",
   _mouse_out: function() { console.log(this.data); }
   get_mouse_out: function() {
     var self = this;
     return function(){ return Function.apply(self._mouse_out,self,arguments); }
   }
}

//Example call back using function.
function do_callback(fn) { fn(); }

//This doesn't work.
do_callback( myobject._mouse_out);

//But this does
do_callback( myobject.get_mouse_out() );

编辑:改进版本内联_mouse_out并使用bind。

var myobject = {
   data:"Some data",
   get_mouse_out: function() {
     function _mouse_out() { console.log(this.data); }
     return _mouse_out.bind(this);
   }
}

//Example call back using function.
function do_callback(fn) { fn(); }

//But this does
do_callback( myobject.get_mouse_out() );

如果您愿意在使用init之前将mouse_out作为设置进行调用,则可以执行此操作。

var myobject = {
   data:"Some data",
   init: function() {
     function _mouse_out() { console.log(this.data); }
     this.mouse_out = _mouse_out.bind(this);
   }
}

myobject.init();
fn( myobject.mouse_out );

最后,Shanimals的一个很好的变体以类似的方式工作,但提供了封装。

 NS.parcel( (function(){
    var myobj = {};
    myobj.data = "Some data";
    myobj.mouse_out = function(){ console.log(myobj.data); }
    return myobj;
  })() 
 );

答案 2 :(得分:1)

我实际上喜欢将大部分逻辑移到init方法中。提供良好的封装,并提供一种简单的方法来声明公共和私有方法/变量。例如:

NS.parsel({
  init: function() {

    var self = this;

    //public instance variable
    self.Name = 'MSimMenu';

    //private instance variables
    var A = {
      time_out_id:        null,
      TIME_DELAY:         1000
    };
    var E = {
        hold_name:         '#hold_name',
        wrap_bottom:       '#wrap_bottom'
    };

    //public instance method
    self.showBottom = function () {
        E.wrap_bottom.style.visibility = 'visible';
    };

    //private instance method
    E.wrap_bottom.addEventListener("mouseout", mouse_out, false);
    function mouse_out() {
      A.time_out_id = NS.setTimeout(self.hideBottom, A.TIME_DELAY);
    }
  }
});