简体   繁体   中英

Javascript * is not a function (prototype function)

Coming from a C++ background, trying to work with an OO language that doesn't have explicit typing is a little more than a headache.

So I have dynamic elements for a webpage that are "controlled" by objects since there are tons of stuff I need to manage on each for it to work. The element is just the visual output of the data inside of the object itself, that's all I really need it for.

Except that I need the object to perform an internal function when it's clicked. That seems to be the biggest source of my headache thus far.

Javascript:

function onClick(file) //The external onClick function I use to try to get it to call from. 
{
    file.state = INUSE;
    file.checkState();
}

function fileObject () { //The file object itself
    this.element;
    this.newElement();         
    //initialize stuff for the object
}

fileObject.prototype.newElement = function() { //creates a new element and sets its event listener
    this.element.click(function() {onClick(this)});
}

fileObject.prototype.checkState = function() {/*does stuff*/} //apparently this is "not a function"

The error I get exactly is "file.checkState is not a function" from Firefox's console panel.

I'm still new to javascript, but after doing some debugging, I've come to find out that it's explicitly the onClick(this) function that is causing all of the errors. When used with something else, the onClick function works perfectly, but for some reason, the this keyword doesn't appear to actually be sending the reference to the fileObject since all checks show file being undefined when inside of the onClick scope.

Is there something fundamentally wrong about the way I'm trying to do this or am I just missing a step (or adding something that I don't need) that will help get this snippet working.

So you know, your initial problem isn't actually handling the action, but listening to it. click will trigger a synthetic click event, rather than liste for one.

You want ... .element.addEventListener("click", callback); that said, you face a second problem, immediately thereafter. I will leave my example code as you've written it to not confuse the matter...

But when you see click( ) know that I mean subscribing with addEventListener , if element really does mean a browser DOM element. If it's not a standard browser element, and your own API, then ignore the previous portion, and carry on.

this is dynamically bound at the invocation time of the function (not at definition time).

The nearest function, scoped above, is your callback function that you are passing into .click( ... ) .

Which is entirely different than the this which you mean outside of the callback. Whatever is on the left-hand side of the dot is the this context for the duration of that particular invocation.

Needless to say, click() doesn't know enough to bind the this you mean, to the left-hand side of your callback.

The solution (or one of many) is to use lexical scoping and/or closure to retain the value of the object you mean.

// easy but messier
var fileObject = this;
... .click(function () { onClick(fileObject); });


// Cleaner with thunks:
function clickHandler (onClick, obj) {
  return function () { onClick(obj); };
}

... .click(clickHandler(this));

从C ++专程前来的Javascript处理this会显得有点疯狂,它看起来像在这里你需要告诉你的功能定义了什么this是-就像这样:

this.element.click(function() {onClick(this)}.bind(this));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM