【问题标题】:Object has no method 'apply'对象没有“应用”方法
【发布时间】:2012-07-26 09:27:47
【问题描述】:

我正在动态创建一些 DOM 元素,例如,

var anchorElement = jQuery('<a />',{text:property.text});
var liElement = jQuery('<li />',{"class":"navlink_"+i,id:"navlink_"+i});
anchorElement.on('click',property.fnctn);
liElement.append(anchorElement);
parentID.append(liElement);

property 是一个 JSON 对象。 property.text 是我要放入锚元素的文本。 (工作正常)

我想将点击事件处理程序附加到该锚元素。 需要绑定到该元素的函数在 JSON 中指定,我们可以像访问它一样访问它

property.fnctn

以下行应该将事件处理程序绑定到锚元素。

anchorElement.on('click',property.fnctn);

这不起作用,所以我尝试将其转换为类似字符串,

anchorElement.on('click',property.fnctn.toString());

没有成功...

当我单击此链接时,控制台中会记录错误

该对象没有“应用”方法。 什么原因……???

我可以通过像

这样的轻微工作来让它工作
anchorElement.attr('onclick',property.fnctn+"()");

以上语句有效,但我想知道为什么.on() API 不起作用。

谢谢 :) AÐitya。

【问题讨论】:

  • property.fnctn 的值是多少?
  • 它是一个字符串...我已经定义了一些函数,各个函数的名称在 property.fnctn 我正在迭代 JSON 数组,所以每次都有新值.. 这是JSON 结构 {"item1":{"text":"Wallet","fnctn":"walletClick"}}, {"item2":{"text":"Pay Some","fnctn":"paySomeoneClick"}} , {"item3":{"text":"支付账单","fnctn":"payBillsClick"}}
  • 一个包含什么的字符串?函数的名称还是函数的定义?
  • @AdityaParab:一个字符串?!不要使用字符串来连接事件处理程序,使用函数。
  • 函数名称...抱歉,我不知道 shift + enter 换行 :)

标签: javascript jquery


【解决方案1】:

更新

你说过property.actfn 是一个字符串"paySomeoneClick"。最好不要将字符串用于事件处理程序,而是使用 functions。如果你想调用在字符串中定义的函数paySomeoneClick,并且如果该函数是全局的,你可以这样做:

anchorElement.on('click',function(event) {
    return window[property.fnctn](event);
});

之所以有效,是因为全局函数是全局对象的属性,可通过浏览器上的window 获得,并且因为下面描述的括号符号。

如果函数位于您引用的对象上,则:

anchorElement.on('click',function(event) {
    return theObject[property.fnctn](event);
});

之所以有效,是因为在 JavaScript 中,您可以通过两种方式访问​​对象的属性:带有文字属性名称的点表示法(foo.bar 访问 foo 上的 bar 属性)和带有字符串属性名称的括号表示法( foo["bar"])。它们是等价的,当然除了括号中的符号,字符串可以是表达式的结果,包括来自像property.fnctn 这样的属性值。

但我建议您退后一步并进行一些重构,这样您就不会在字符串中传递函数名称。 有时这是正确的答案,但根据我的经验,并不经常。 :-)

原答案

(假设property.fnctn 是一个函数,而不是字符串。但可能对某些人有用...)

代码

anchorElement.on('click',property.fnctn);

会将函数附加到事件,但在调用函数期间,this 将引用 DOM 元素,而不是指向您的 property 对象。

要解决这个问题,请使用 jQuery 的 $.proxy:

anchorElement.on('click',$.proxy(property.fnctn, property));

...或 ES5 的 Function#bind:

anchorElement.on('click',property.fnctn.bind(property));

...或闭包:

anchorElement.on('click',function(event) {
    return property.fnctn(event);
});

更多阅读(在我的博客上):

【讨论】:

  • 谢谢 T.J!明白了...可能我需要与我的项目经理交谈以考虑重新设计这种方法... :) 好吧,有什么理由不使用字符串作为事件处理程序吗? (只是好奇)
  • @AdityaParab:重新使用字符串分配给click 处理程序,这不是一个好主意,因为它需要JavaScript 解析器启动并解析字符串,并且它掩盖了正在发生的事情。重新传递函数名称,它将 codedata 混为一谈,这通常(但不总是!)不太理想。如果你可以抽象一点,传递你的代码然后解释为“哦,这意味着我们应该调用这个函数”的信息,这通常是最好的。但是,当服务器代码正在向客户端代码发送消息时,仅传递函数名称可能会有真正的论据。最好的,
  • @T.J.Crowder 好的,谢谢您的回复.. 当然你可以删除它。你有什么参考可以帮助我吗?
猜你喜欢
  • 2012-04-15
  • 1970-01-01
  • 2019-04-01
  • 2012-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多