在javascript中使用原型时设置函数名(用于日志记录)
Setting function name (for logging) when using prototype in javascript
我使用原型在javascript中定义对象。
例如
Listerly.prototype.init = function() {
this.storage = new ListerlyStorage();
this.mainView = new ListerlyMainView();
}
一切都很好,但我也试图使用以下非常简单的日志记录方法来限制我的控制台日志记录:
Listerly.prototype.log = function(message) {
if (this.loggingEnabled) {
if (arguments && arguments.callee && arguments.callee.caller) {
var methodName = arguments.callee.caller.name;
console.log("Method name: "+ methodName);
if (this.logMethods["*"] || this.logMethods[methodName]) {
if (methodName) console.log(methodName + ":" + message);
else console.log(message);
}
} else {
console.log(message);
}
}
};
问题是使用原型定义的函数没有函数名,因此arguments.callee.caller.name
为空。
有什么干净的方法可以设置函数名吗?我试着在完成后迭代原型,并在每个函数上设置.name
字段,但这似乎不起作用。
有一个丑陋的解决方法,这样做会污染全局命名空间:
function listerly_finishedLoadingUser(user) {
this.user = user;
this.mainView.setUser(user);
}
Listerly.prototype.finishedLoadingUser = listerly_finishedLoadingUser;
希望有更干净的方式吗?
name
属性是特殊的,在大多数JavaScript实现中不能更改其值。
自定义函数名称是ECMAScript 6讨论的一部分,请参阅strawman提案和最终提案。
在ES6兼容的浏览器中,即使使用原型函数,也应该获得预期的函数名称:
Listerly.prototype.finishedLoadingUser = function() { }
console.log(Listerly.prototype.finishedLoadingUser.name);
// prints "finishedLoadingUser"
如果你正在寻找一个适用于所有浏览器的解决方案,你可以使用谷歌的Traceur编译器将ES6源代码转换为ES5。
或者,您可以使用不同的属性来存储您的自定义函数名称:
// in the logger
var methodName = arguments.callee.caller.name ||
arguments.calee.caller.myCustomName;
// in the property iterator
for (var key in obj) {
obj[key].myCustomName = key;
}
函数名称/标识符在函数表达式中是可选的:
Listerly.prototype.finishedLoadingUser =
function listerly_prototype_finishedLoadingUser (user) {
// …
};
在严格模式下,可以使用函数中的函数名进行递归,其中禁止使用arguments.callee
。
请注意,在旧的(borken)JScript版本中,标识符也可以在函数之外使用,因此要明智地选择它。此外,标识符长度可能存在(未指定)限制。
您使用的(只读)name
属性目前只是一个事实上的标准。在不可用的情况下,您可以从函数序列化中获得函数名,也就是说,将Function
实例转换为字符串并提取标识符部分(就像我在JSX:object.js中所做的那样):
/**
* Returns the name of a function
*
* @param {Function|String} aFunction
* @return {string}
* The name of a function if it has one; the empty string otherwise.
*/
getFunctionName: function (aFunction) {
/* Return the empty string for null or undefined */
return (aFunction != null
&& typeof aFunction.name != "undefined" && aFunction.name)
|| (String(aFunction).match(/^'s*function's+([A-Za-z_]'w*)/) || [, ""])[1];
},
通常,函数序列化是不可靠的
还要注意,arguments
对象和Function
实例的caller
属性是专有的。
- 将函数的上下文应用于javascript变量
- keyup事件处理程序更改焦点不适用于快速键入
- JQueryhide()不适用于Mozzilla,但适用于Chrome
- JavaScript数组排序(函数)用于对表行进行排序,而不是排序
- PHP中的setcookie仅适用于localhost
- 包括用于facebook评论框的JavaScript SDK
- 如何检测用于WebGL的专用或集成显卡
- ng更改事件不适用于Dropdown
- 用于搜索的聚合物嵌套绑定
- jQuery表单添加不适用于下拉列表
- 有问题与承诺角度.控制台日志不适用于 HTTP 请求
- 用于处理呈现的 html 表单的更改日志的插件
- Kibana - 用于查找内容并从日志中显示附近记录的仪表板
- 用于单元测试和运行基于浏览器的 Web 应用程序的 Javascript 日志记录设置
- 用于打包移动应用程序(Android、iOS)的Javascript错误日志记录/报告/跟踪器
- 我可以用javascript扩展控制台对象(用于重新路由日志记录)吗
- 用于客户端日志记录的脚本或工具
- 如何访问用于量角器测试的 chromedriver 日志
- 在javascript中使用原型时设置函数名(用于日志记录)
- 如何在TypeScript中获得源代码中的实际行#(用于自定义日志记录)