javascript - 如何正确扩展 Object.prototype?

标签 javascript prototype-programming

我正在编写一个提供函数 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/

相关文章:

javascript - 指定在检查 Google Recaptcha 时要执行的某些函数,因为我不是使用 javascript 的机器人

javascript - 单击时 ionic 显示全屏图像

javascript - 阻塞事件循环

javascript - 如何在 JavaScript 中获取完全准确的值?

javascript - React-Native Flatlist 会在状态发生变化时重新渲染图像

javascript - 使用 this 和 prototype 在 JavaScript 中定义类的方法有什么区别?

Javascript原型(prototype)和修改原始对象

javascript - JavaScript 中有没有一种方法可以实例化不一定是函数的对象?

javascript - 属于 JavaScript 对象原型(prototype)的回调函数可以访问对象成员吗?

Javascript:是否可以将新函数注入(inject)到基础 'class/object' 中,该函数将在所有子 -'classes/objects' 中可用?