【问题标题】:Javascript * is not a function (prototype function)Javascript * 不是函数(原型函数)
【发布时间】:2016-10-13 05:48:28
【问题描述】:

来自 C++ 背景,尝试使用没有显式类型的 OO 语言不仅仅是头疼。

所以我有一个网页的动态元素,这些元素是由对象“控制”的,因为我需要管理大量的东西才能让它工作。元素只是对象本身内部数据的视觉输出,这就是我真正需要的。

除了我需要对象在单击时执行内部功能。到目前为止,这似乎是我头痛的最大原因。

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"

我得到的错误是 Firefox 控制台面板中的“file.checkState is not a function”。

我还是 javascript 的新手,但是在进行了一些调试之后,我发现它明确地是 onClick(this) 函数导致了所有错误。当与其他东西一起使用时,onClick 函数可以完美运行,但由于某种原因,this 关键字似乎实际上并未发送对 fileObject 的引用,因为所有检查都显示file 在内部时为undefined onClick 范围的。

我尝试执行此操作的方式是否存在根本性错误,或者我只是错过了有助于使该 sn-p 工作的步骤(或添加一些我不需要的东西)。

【问题讨论】:

  • 类似:this 何时变为 undefined
  • 好的,那我只是使用 this 错误,但这仍然不能解决我的问题。我只需要一个干净的方法来传递对将在当前范围内持续存在的函数的引用。我该怎么做?
  • this.element.click 不是设置事件监听器的方法。
  • @torazaburo 我不确定你的意思是什么,因为它完全符合我的预期:单击元素时运行一个函数。

标签: javascript function object prototype undefined


【解决方案1】:

所以你知道,你最初的问题实际上并不是处理动作,而是倾听它。 click 将触发合成点击事件,而不是一一列举。

你想要... .element.addEventListener("click", callback); 说,你面临第二个问题,紧随其后。 我将保留您编写的示例代码,以免混淆问题...

但是当你看到click( ) 时知道我的意思是用addEventListener 订阅,如果element 确实意味着浏览器DOM 元素。如果它不是标准浏览器元素,也不是您自己的 API,则忽略前面的部分,继续。

this 在函数调用时(而不是定义时)动态绑定。

上面范围内最近的函数是您传递给.click( ... )的回调函数。

这与this 完全不同,您的意思是在回调之外。 点左侧的内容是该特定调用期间的 this 上下文。

不用说,click() 不知道将this 绑定到回调的左侧。

解决方案(或众多解决方案之一)是使用词法范围和/或闭包来保留您所指的对象的值。

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


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

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

【讨论】:

  • 不确定onClick 参数在clickHandler 函数中的用途,但删除它终于解决了我的问题!我不能感谢你!现在我对闭包以及如何绕过this 的内在限制有了更多了解!
  • 啊,抱歉,它本来是一个通用绑定。关闭的不是参数,而是实现。 clickHandler(onClick, fileObject) 关键是你现在有一种通用的方式来记住值并在它们上应用特定的函数,懒惰地(通过传入一个记住两者的函数,并在调用时运行一个在另一个之上)。
  • 这更有意义。我只是不确定那是什么。再说一次,我真的不能责怪你,因为我非常怀疑你在发布 sn-p 之前能够测试任何东西。哈哈。幸运的是,我仍然可以自己阅读。无论如何,再次感谢您帮助我了解这种不太面向对象的面向对象语言。大声笑。
  • 确实如此。我在我的手机上,所以我很高兴你能。更重要的是,当您删除它时它会起作用,因为该参数恰好与外部存在的名称相同,在函数的词法范围内,否则它会被抛出。但是,当您开始编写与环境无关的函数式 JS 时,词法作用域和高阶函数(那些在其他函数内部构造并返回,并包含闭包引用)是一笔巨大的交易。
【解决方案2】:

来自 c++ 的 Javascript 处理 this 的方式看起来有点疯狂,看起来在这里你需要告诉函数你已经定义了 this 是什么 - 就像这样:

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

【讨论】:

  • 我担心将事件设置为this.element 的方式。好像not standard
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-04
  • 2014-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 2018-05-25
相关资源
最近更新 更多