1

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

但是,bc 它仅用作事件处理程序回调,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';
    }
});
4

3 回答 3

2

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

var that = {
    myfunc:function(){
        console.log(that)
    }
};
NS.parsel(that);
于 2013-06-11T01:02:20.830 回答
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 并使用绑定。

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之前被称为 setup,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;
  })() 
 );
于 2013-06-11T01:04:06.723 回答
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);
    }
  }
});
于 2013-06-11T03:03:55.507 回答