Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中销毁对象及其绑定_Javascript_Javascript Events - Fatal编程技术网

在javascript中销毁对象及其绑定

在javascript中销毁对象及其绑定,javascript,javascript-events,Javascript,Javascript Events,我有一个javascript类 (function() { this.testObject = function() { /*options*/ this.options = arguments[0]; }; /*make object*/ testObject.prototype.make = function(){ this.targetElement = document.getElementById('t

我有一个javascript类

(function() {
    this.testObject = function() {
        /*options*/
        this.options = arguments[0];
    };

    /*make object*/
    testObject.prototype.make = function(){

        this.targetElement = document.getElementById('testDiv');

        this.targetElement.addEventListener('mousedown', function(e){
            ...
        });
        this.targetElement.addEventListener('mouseup', function(e){
            ...
        });
        this.targetElement.addEventListener('mousemove', function(e){
            ...
        });

    };
}());

var test; // I need this to be global
function callObject(){
    test = new testObject({...});
    test.make();
}
此对象绑定一些事件。实例化也在另一个函数中。这是因为我遇到了向DOM添加新元素的情况,所以对每个新元素调用
callObject()
,为其绑定事件

但是我认为这里有一个性能问题,当我多次调用
callObject
时,它会变慢。我不知道究竟是什么问题


<如何删除一个对象及其所有绑定事件?

有一些事情要考虑。首先,也是最重要的,事件侦听器具有匿名函数。当您为侦听器提供anon函数时,无法解除其绑定。因此,请继续为这些应用程序创建实际功能。然后您可以调用
removeEventListener
,调用方式与调用
addEvent…
相同,它将分离这些侦听器

我通常做的是创建一个
destroy
函数,该函数删除所有侦听器并将所有全局变量设置为
null
。然后,您可以随时调用destroy函数

> var test; // I need this to be global
> function callObject(){
>     test = new testObject({...});
>     test.make();
> }
在上面,test将只引用testObject的最后一个实例

您使用的模式意味着原型链上的每个函数都有一个外部IIFE执行上下文的闭包,make方法添加的每个侦听器也是如此。如果您不需要闭包,那么这是低效的。如果不是,那么在这里使用IIFE是不合适的,考虑使用一种标准的方法(它是约定给构造函数以大写字母开头的名称):

正如其他地方所指出的,使用函数表达式添加侦听器后很难删除它们。上述模式还意味着每个实例都有自己的函数副本。解决这两个问题的另一种方法是使用引用。您可以将它们添加为构造函数的属性,这样它们就不会创建额外的全局变量,也不需要另一个对象,例如

TestObject.mousedown = function (e){ ... };
TestObject.mouseup   = function (e){ ... };

TestObject.prototype.make = function(){
    var TO = TestObject;
    this.targetElement = document.getElementById('testDiv');
    this.targetElement.addEventListener('mousedown', TO.mousedown, false);
    this.targetElement.addEventListener('mouseup',  TO.mouseup, false);
    ...
};

这避免了许多闭包和不必要的函数副本,意味着可以按名称删除侦听器。您可能希望将测试全局化为一个对象或数组,这样您就可以保留对TestObject所有实例的引用,而不仅仅是最后一个实例的引用。

只要您不使用
var
声明变量,您就可以调用delete将其从全局(窗口)对象中删除。使用IIFE来声明变量是毫无意义的。IIFE用于避免使用全局变量,但这会从IIFE中创建全局对象的属性。它有一个没有好处的iFIs的缺点,考虑使用一个简单的函数声明。“当你给它一个ANON函数时,你不能解除绑定器”,你可以,用它自己的一个克隆来替换这个节点,它将删除ADDeVistListEnter添加的所有侦听器。不过有点不对劲……我想。。。但考虑到有一种完全有效且长期受支持的删除侦听器的方法,我不明白您为什么要这样做。似乎只是在推广糟糕且低效的代码。谢谢,但如果类本身有默认的事件脚本呢?例如,应为此类的每个对象运行的默认
mouseup
事件。我希望它是干燥的。这就是上面所说的。TestObject.mouseup有一个实例,每个targetElement都附带一个对它的引用。顺便说一句,ECMAScript中没有类。下一个版本(ed 6)引入了类,它们与上面的不同,因此将新创建的对象和使用原型创建的对象称为“类”将变得非常混乱。
TestObject.mousedown = function (e){ ... };
TestObject.mouseup   = function (e){ ... };

TestObject.prototype.make = function(){
    var TO = TestObject;
    this.targetElement = document.getElementById('testDiv');
    this.targetElement.addEventListener('mousedown', TO.mousedown, false);
    this.targetElement.addEventListener('mouseup',  TO.mouseup, false);
    ...
};