如何使“未定义不是函数”错误更有用?

Posted

技术标签:

【中文标题】如何使“未定义不是函数”错误更有用?【英文标题】:How can "undefined is not a function" errors be made more useful? 【发布时间】:2014-03-24 02:20:30 【问题描述】:

考虑这段 javascript 代码:

var x = new date()

// "ReferenceError: date is not defined" - useful error, hints at a typo ('D'ate)

var x = new MyClass.foo()

// "TypeError: undefined is not a function" - bad error, no hint it might be 'F'oo

错误本身是正确的,因为MyClass 没有foo 方法,所以MyClass.foo 确实返回undefined,而new 不喜欢那样。问题是这根本没有暗示用户可能拼错了方法名称。现实生活中的例子:

new Meteor.collection('foo')  // instead of:
new Meteor.Collection('foo')  // c and C look alike with many fonts at small size

是否有一种可移植 方法来检测对象没有方法之前 new 自动将undefined 传递给它? __noSuchMethod__ 正是我正在寻找的,但它看起来像是一个非标准扩展。看起来像 IE doesn't support it 和 V8 refused to implement it。 Chromium 团队也doesn't care much about implementing Proxy support。

看起来对 Node 的 Proxy 有一些支持(参见 this 和 this)和 shim 的形式(“用于即将推出的 ECMAScript Reflect API 的 polyfill” em> 但请参阅下面的 mpm 的 cmets。

相关问题(这归结为什么):

catch attempted access to non-existent property Object.watch for all properties JavaScript getter for all properties

【问题讨论】:

在未来的某个时候,您将能够使用proxies for that。 shim 不模拟 Proxie,不可能模拟代理,它模拟 Reflect api,只是为了清楚,不要给人们错误的想法。你不能 shim 代理。 "是否有可移植的方式" 不在 ES5 中,不在没有和谐标志的 V8 中(启用代理)。除非您启用实验性功能,否则答案是否定的。 ES5 中不存在代理对象。通过启用它们,您可以在 Chrome 中已有代理,但这是一项实验性功能。你不需要 shim 。它们在 Firefox 中不受标志支持,但你不能 shim 代理这是不可能的。自述文件说“更新”不是从无到有创建临时。对于阅读您的问题的人来说,重要的是他们不会被误导认为 lib 可以为他们提供代理。这既不正确也不可能。 无论是否使用 new 运算符,都会引发错误。将调用应用于非函数是原因。 new 操作符只是简单地创建一个新的空对象,将函数实例的 this 关键字绑定到新对象,并将对象的原型设置为存储在函数中的原型。如果您收到此错误,甚至不确定您是否弄乱了变量或属性命名,但很有可能;初始化可能出现问题。 JSHint 也可以帮助您找出问题所在,恕我直言,您正在解决一个不需要解决的问题。 【参考方案1】:

这个问题过了一年多,V8大概改了错误信息

var MyClass = function() 
  this.Foo = function()  console.log("Foo"); 


new MyClass().foo();

今天产生这个错误

Uncaught TypeError: (intermediate value).foo 不是函数

与命名对象一起使用

var mc = new MyClass();
mc.foo();

它更有用

未捕获的类型错误:mc.foo 不是函数

在对象名称中与拼写错误一起使用也很有用:

new myClass().foo();

Uncaught ReferenceError: myClass is not defined

【讨论】:

以上是关于如何使“未定义不是函数”错误更有用?的主要内容,如果未能解决你的问题,请参考以下文章

自定义模块:未捕获类型错误:未定义不是函数

Bourbon Refills Navigation JavaScript 错误:未捕获类型错误:未定义不是函数

Backbone.js 视图是不是需要 jQuery 或 Zepto? (或者:为啥我会收到“未捕获的类型错误:未定义不是函数”?)

Javascript未定义,不是函数错误

“未捕获的类型错误:未定义不是函数”- 初学者 Backbone.js 应用程序

Javascript:将画布另存为图像 ==>“未捕获的类型错误:未定义不是函数”