How to extend Obect.prototype correctly?

后端 未结 2 1762
孤街浪徒
孤街浪徒 2021-01-15 18:56

I\'m writing a JavaScript Library that offers the function tablify(anything);, which is able to represent any Array or Object as an HTML Table.

Now I\'

相关标签:
2条回答
  • 2021-01-15 19:14

    The problem is that once you get into your newly-added method on the prototype, the original primitive value has already been converted. For example:

    "foo".tablify();
    

    In that call, before the function is called, the string primitive is converted into a String instance. In other words, it behaves as if you had written:

    new String("foo").tablify();
    

    I suppose you could use the Object.prototype.toString function to tell the difference:

    function  tablify(obj) {
        if (typeof obj === "object") {
          var sig = {}.toString.call(obj);
          if (/ (String|Number|Boolean)\]$/.test(sig)) {
            // treat as primitive
          }
          else {
            // object
          }
        }
        // ...
    }
    

    You won't be able to tell if the boxed primitive was implicitly created or not, but that probably doesn't really matter for what your code does anyway.

    0 讨论(0)
  • 2021-01-15 19:22

    Why is typeof always returning "object"?

    Because in sloppy mode, the this context always is supposed to be an object. When you call a function or pass undefined or null, you get the global object, when you call a method the context will get casted to an object.

    Use strict mode for your tablify method and it will work!

    Is it a good thing for a JS-API to provide this sort of functionality (extending Arrays/Objects with .tablify();)?

    Yes. No.. Many people will frown to use your script when you want to share it. See Why is extending native objects a bad practice? for a detailed discussion.

    At least you've properly used non-enumerable properties - but I would recommend to use them on Array.prototype as well, too many people abuse for in enumerations.

    How is it possible to distinguish between "normal" objects, numbers, functions,... ?

    typeof seems fine.

    Is it possible to only extend "normal" objects? (forbid (42).tablify();, "string".tablify(); ...)

    Not really. All primitive wrappers inherit from Object.prototype.

    Whats the name for those "normal" objects? How should I call them?

    Just "objects". Or "plain objects" if you want (distinguishes them from arrays, built-ins, host objects).

    0 讨论(0)
提交回复
热议问题