简体   繁体   English

如何从 JavaScript 类方法引用函数

[英]How to reference a function from JavaScript class method

I use SWFAddress for deep linking my site ( link to SWFAddress ).我使用 SWFAddress 深层链接我的网站(链接到 SWFAddress )。 I like to break code into classes so I have a main structure similar to this:我喜欢将代码分解成类,所以我有一个类似于这样的主要结构:

function SomeClass() {
    // This adds the this.handleChange() function to the
    // SWFAddress event listener
    this.initializeSWFA = function() {
        // SWFAddress variable is instantiated in SWFAddress javascript file
        // so I can use it here
        SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange);
    }

    // SWFAddress is supposed to call this function
    this.handleChange = function(evt) {
    // Some code here
    }

}

// Instantiate the SomeClass
var someVar = new SomeClass();
someVar.initializeSWFA();

This line does not work here:此行在此处不起作用:

SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange);

I tried changing it to:我尝试将其更改为:

SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange());

or

var self = this;
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, self.handleChange);

And these don't work either.而这些也不起作用。

So how do I reference a JavaScript function from a class in a situation like this?那么在这种情况下如何从类中引用 JavaScript 函数呢?

If the function handleChange would be outside of the class I can write the function's name.如果函数handleChange在类之外,我可以写出函数的名称。


First, thank you for all the answers.首先,谢谢大家的回答。 I am still trying to figure how this all works in JavaScript.我仍在尝试弄清楚这一切在 JavaScript 中是如何工作的。 I am not used to the object oriented model like here in JavaScript.我不习惯 JavaScript 中像这里这样的面向对象模型。

This is the solution for now.这是目前的解决方案。 I still can't figure out how to do this nicely in JavaScript, but this solution works.我仍然无法弄清楚如何在 JavaScript 中很好地做到这一点,但这个解决方案有效。 I tried to implement the solution suggested by ehudokai (thank you), however I was not able to make it work.我尝试实施 ehudokai 建议的解决方案(谢谢),但是我无法使其工作。

function SomeClass() {
    // This adds the this.handleChange() function to the
    // SWFAddress event listener
    this.initializeSWFA = function() {
        // SWFAddress variable is instantiated in SWFAddress javascript file
        // so I can use it here
        SWFAddress.addEventListener(SWFAddressEvent.CHANGE, someFunc);
    }

    // SWFAddress suppose to call this function
    this.handleChange= function(evt) {
    // Some code here
    }

}

// Instantiate the SomeClass
var someVar = new SomeClass();

function someFunc(evt) {
    someVar.handleChange(evt);
}

someVar.initializeSWFA();

I don't like this because this involves defining one extra function, so it takes extra space if anybody figures out how to add a method to SWFAddress EventListener from a JavaScript object.我不喜欢这样,因为这涉及定义一个额外的函数,因此如果有人想出如何从 JavaScript 对象向 SWFAddress EventListener 添加方法,则需要额外的空间。 Please help me out.请帮帮我。

Your class structure is perfectly valid.你的类结构是完全有效的。 However, if your handleChange() function uses the this keyword, expecting someVar , then that is where your problem lies.但是,如果您的handleChange()函数使用this关键字,期望someVar ,那么这就是您的问题所在。

This is what happens:这是发生的事情:

  1. SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange); correctly references the handler function within the class.正确引用类中的处理程序函数。 SWFAddress caches that function to some variable f until the event is dispatched. SWFAddress 将该函数缓存到某个变量f直到事件被调度。
  2. When the event is dispatched, SWFAddress calls f .调度事件时,SWFAddress 调用f While the reference to the function is preserved, the reference to the context, or this , is not.虽然对函数的引用被保留,但对上下文或this的引用不是。 Therefore this defaults to window .因此this默认为window

To get around this, you simply need to use an anonymous function that captures the variables within the class scope.为了解决这个问题,您只需要使用一个匿名函数来捕获类范围内的变量。 You can call the handler with the correct context from within this anonymous function:您可以在此匿名函数中使用正确的上下文调用处理程序:

function SomeClass() {
    this.initializeSWFA = function() {
        // Save a reference to the object here
        var me = this;

        // Wrap handler in anonymous function
        SWFAddress.addEventListener(SWFAddressEvent.CHANGE, function (evt) {
            me.handleChange(evt);
        });
    }

    // SWFAddress suppose to call this function
    this.handleChange= function(evt) {
    // Some code here
    }

}

##An explanation of this , as requested by the OP:## ## this的解释,根据 OP 的要求:##

The this keyword can be explained in different ways: take a read of firstly this article about scope , and then this article about object-oriented JavaScript . this关键字可以用不同的方式解释:首先阅读这篇关于 scope 的文章,然后阅读这篇关于面向对象的 JavaScript 的文章

I'd like to throw in my quick reasoning too, which you may find helpful.我也想加入我的快速推理,你可能会发现它有帮助。 Remember that JavaScript doesn't have "classes" as languages such as Java do.请记住,JavaScript 没有像 Java 这样的语言那样具有“类”。 In those languages, a "method" of a class belongs only to that class (or could be inherited).在这些语言中,一个类的“方法”只属于那个类(或者可以被继承)。 In JavaScript however, there are only objects, and object properties, which can happen to functions.然而,在 JavaScript 中,只有对象和对象属性可以发生在函数中。 These functions are free agents -- they don't belong to one object or another, just like strings or numbers.这些函数是自由代理——它们不属于一个或另一个对象,就像字符串或数字一样。 For example:例如:

var a = {
    myMethod: function () {...}
};

var b = {};
b.myMethod = a.myMethod;

In this case, which object does myMethod belong to?在这种情况下, myMethod属于哪个对象? There is no answer;没有答案; it could be either a or b .它可以是ab Therefore a.myMethod is simply a reference to a function, disassociated from the "context", or parent object.因此a.myMethod只是对函数的引用,与“上下文”或父对象分离。 Therefore this has no meaning unless it is called explicitly using a.myMethod() or b.myMethod() , and thus defaults to window when called in any other way.因此this是没有意义的,除非它是使用被称为显式a.myMethod()b.myMethod()因此缺省window以任何其他方式调用时。 It is for the same reason that there is no such thing as a parent or super keyword in JavaScript.出于同样的原因,JavaScript 中没有parentsuper关键字这样的东西。

I think the best thing to do is to stop thinking of SomeClass as a class .我认为最好的办法是停止将 SomeClass 视为一个

JavaScript doesn't have classes. JavaScript 没有类。 It uses prototypical inheritance.它使用原型继承。 Which I won't go too deeply into here.我不会在这里深入讨论。 Essentially, it means you just have objects.本质上,这意味着您只有对象。 And if you want to create another object like the first one, you use the Object.prototype attribute to do that.如果你想像第一个一样创建另一个对象,你可以使用 Object.prototype 属性来做到这一点。

So if you want to do what you're trying to (assuming that SWFAddress works like most JavaScript), do the following.因此,如果您想做您想做的事情(假设 SWFAddress 像大多数 JavaScript 一样工作),请执行以下操作。

var someVar = {  // (Using object notation)
    initializeSWFA : function(){
        SWFAddress.addEventListener(SWFAddressEvent.CHANG, this.handleChange);
    },
    handleChange : function(){
        // Your code here
    }
}

At this point you can call someVar directly:此时可以直接调用 someVar :

someVar.initializeSWFA();

If instead you want to create an object that you can inherit other objects from try the following.如果您想创建一个可以继承其他对象的对象,请尝试以下操作。

var baseObject = function(){};
baseObject.prototype.handleChange = function(){
    // Your code here
}
baseObject.prototype.initializeSWFA = function(){
    SWFAddress.addEventListener(SWFAddressEvent.CHANGE, this.handleChange);
}

var someVar = new baseObject();
someVar.initializeSWFA();

The new operator simply creates a new object that inherits the .prototype of the object specified. new运算符只是创建一个新对象,该对象继承了指定对象的.prototype

I'm afraid I can't pinpoint your problem, but I would say that it has something to do with your use of SWFAddress .恐怕我无法查明您的问题,但我想说这与您使用SWFAddress The way you're structuring SomeClass and its methods is completely valid, contrary to what some other answers here are stating.您构建SomeClass及其方法的方式是完全有效的,这与这里的其他一些答案所陈述的相反。

Further clarification to miki's (now deleted) question from another answer, regarding how this works:进一步澄清三木(现已删除)从另一个答案的问题,关于如何this工作:

There are two cases for how this behaves; this行为有两种情况; regular functions and functions invoked with the new -operator.常规函数和用new -operator 调用的函数。

For regular function invokations, this refers to the object to the left of the dot (loosely speaking): For example, when writing someVar.initializeSWFA() , this will refer to someVar .对于常规函数调用, this指的是点左侧的对象(松散地说):例如,在编写someVar.initializeSWFA()this将指的是someVar When calling a function without the dot, this will refer to the global object.调用不带点的函数时, this将引用全局对象。 A function can be assigned from one object to another and hence this will be shifted, like this:一个函数可以从一个对象分配给另一个对象,因此this将被转移,如下所示:

var someVar = new SomeClass();
var anotherVar = {};
anotherVar.aNewNameForTheSameFunction = someVar.initializeSWFA;
anotherVar.aNewNameForTheSameFunction(); // Inside of this call to initializeSWFA, "this" will be "anotherVar"

Then we also have the case when invoked with the new -operator.然后我们也有使用new -operator 调用时的情况。 In that case, new will create a new object for you and this will refer to that object.在这种情况下, new将为您创建一个新对象, this将引用该对象。

There are also ways to invoke a function with an explicitly set this , by using the call -function:还有一些方法可以通过使用call -function 来调用显式设置this的函数:

var someVar = new SomeClass();
var aNumber = 5;
someVar.initializeSWFA.call(aNumber, arg1, arg2, ..., argN);

That will call the function initializeSWFA with aNumber as this and also pass it the parameters arg1 , arg2 , etc. Note that someVar is taken out of the equation in that case.这将使用aNumber作为this调用函数 initializeSWFA 并将参数arg1arg2等传递给它。请注意,在这种情况下, someVar被从等式中取出。

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

相关问题 如何从 javascript 中的方法引用中检索 class? - How can I retrieve a class from a method reference in javascript? 如何在Javascript中的函数中引用数组方法 - How to reference an array method within a function in Javascript 有没有办法从 Javascript class 方法中引用“当前类” - Is there a way to reference "the current class" from a Javascript class method JavaScript:使用“ this”的函数调用。 不引用类中的方法 - JavaScript: call of function with 'this.' does not reference to method in class 如何从 JavaScript 函数获取对已被另一个类实例化的 JavaScript 类的类属性的引用? - How do I get a reference from a JavaScript function to a class property of a JavaScript class that has been instantiated by another class? 如何从通用JavaScript引用React类 - How to reference a React class from generic javascript javascript:如何从事件引用类 - javascript: How to reference a class from event 从jQuery函数引用Javascript“类”方法 - Refering to Javascript “Class” method from jQuery function javascript如何引用方法? - how to reference a method javascript? 如何在函数中的javascript中创建2` this`引用 - How to create 2 `this` reference in javascript from within a function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM