我正在编写一个提供函数 tablify(anything);
的 JavaScript 库,它能够将任何数组或对象表示为 HTML 表。
现在我正在尝试扩展 Array 和 Object 原型(prototype)以便像这样使用它:
var arr = ["a", "b", "c"];
var obj = {"A": "a", "B": "b", "C": "c"};
arr.tablify();
obj.tablify();
这是我的方法:
Array.prototype.tablify = function() {
return tablify(this);
}
Object.defineProperty(Object.prototype, 'tablify', {
value: function () {
return tablify(this);
},
writable: true,
configurable: true,
enumerable: false
});
问题是,JavaScript 中的一切都是对象,因此不仅可以转换像 {a: 1, b: 2}
这样的文字,还可以转换其他所有内容。
这没什么大不了的,因为我的 tablify()
也可以处理原始类型,但是当我扩展 Object.prototype 时,typeof anything
总是返回“object”
我再也无法区分类型了:
function tablify(object) {
if (object instanceof Array) {
return ArrayToTable(object);
}
//This is always true if I extend Object.prototype:
if (typeof object === "object") { //only for "normal" objects like "{a: 1, b: 2, c: [],...}"
return ObjectToTable(object);
}
return PrimitiveToTable(object); //strings, numbers, functions, ...
}
- 为什么
typeof
总是返回"object"
? - JS-API 提供这种功能(使用“.tablify();”扩展数组/对象)是件好事吗?
- 如何区分“普通”对象、数字、函数……?
- 是否可以只扩展“普通”对象?
(禁止
(42).tablify();
,"string".tablify();
...) - 那些“正常”对象的名称是什么?我应该如何称呼他们?
最佳答案
Why is
typeof
always returning"object"
?
因为在草率模式下,this
context总是应该是一个对象。当您调用一个函数或传递 undefined 或 null 时,您将获得全局对象,当您调用一个方法时,上下文将被转换为一个对象。
使用strict mode对于您的 tablify
方法,它将起作用!
Is it a good thing for a JS-API to provide this sort of functionality (extending Arrays/Objects with
.tablify();
)?
Yes. No. .当您想要共享脚本时,许多人会皱眉使用您的脚本。参见 Why is extending native objects a bad practice?进行详细讨论。
至少你有 properly used non-enumerable properties - 但我建议在 Array.prototype
上也使用它们,太多人滥用 for in
枚举。
How is it possible to distinguish between "normal" objects, numbers, functions,... ?
typeof
看起来不错。
Is it possible to only extend "normal" objects? (forbid (42).tablify();, "string".tablify(); ...)
不是真的。所有原始包装器都继承自 Object.prototype
。
Whats the name for those "normal" objects? How should I call them?
只是“对象”。如果需要,也可以是“普通对象”(将它们与数组、内置对象、宿主对象区分开来)。
关于javascript - 如何正确扩展 Object.prototype?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28304581/