开发者

Should every object have a method 'addEventListener'?

I needed a function to generate a pseudo-random integer between m and n, and so I thought, "I know, I'll extend Math with a randrange method, similar to Python's".

Math.constructor.prototype.rand = function rand(min, max) {
    return min + Math.floor(Math.random() * (max + 1 - min));
};

This seems to work, but when I put it into my integrated code, I experienced multiple problems with error messages like "[that function] has no method 'addEventListener'".

The gist of my question is this: Is there something fundamentally wrong with the way I've extended Math here? Should that function have such a method, and if not, why is jwplayer asking for it?

I've attached much more detail below, but if you're already bored and want to start postulating answers, you can skip t开发者_开发知识库he rest.


When I went to test the integrated code I saw this error:

jwplayer.js:1 Uncaught TypeError: Object function rand(min, max) {
        return min + Math.floor(Math.random() * (max + 1 - min));
    } has no method 'addEventListener'
jwplayer.js:1 a.plugins.pluginloader.load
jwplayer.js:1 a.embed
jwplayer.js:1 b.api.setup
script.js:155 (anonymous function)
jquery-1.6.4.js:660 jQuery.extend.each
jquery-1.6.4.js:274 jQuery.fn.jQuery.each
script.js:150 jQuery.click.window.Modernizr.input.required
jquery-1.6.4.js:1016 jQuery.extend._Deferred.deferred.resolveWith
jquery-1.6.4.js:437 jQuery.extend.ready
jquery-1.6.4.js:923 DOMContentLoaded

Here's a snippet from script.js that the above refers to:

// Setup the video player:
$("video").each(function (i, e) {
    // Switching out ids like this is a horrible hack,
    // but apparently it's the only way jwplayer will load.
    var oldId = $(e).attr('id');
    $(e).attr("id", "tmpVideoSetup");
    jwplayer("tmpVideoSetup").setup({
        flashplayer: window.CDN + "/js/libs/mediaplayer-5.7-licensed/player.swf",
        levels: [
            // TODO: set this up to dynamically choose the videos to play.
            { file: window.CDN + "/videos/LK_About.mp4" },
            { file: window.CDN + "/videos/LK_About.wmv" }
        ]
    });
    $(e).attr("id", oldId);
});

When I remove the video-loading code, everything else behaves as expected.


Why attach it to Math at all? And if you're going to, what's wrong with Math.rand = ...?

The Math Object isn't supposed to be extended in a prototypal manner, because it's a "static" type. You cannot instantiate it (i.e. call it with new). This is an exceptional case. All other types are "non-static". Although that shouldn't be surprising, Math is simply a collection of static methods. There is no need for any instantiation.

Math.constructor === Object (at least in chrome), so you're actually extending every object's prototype, and presumably the other library is enumerating over all object properties. For example:

Math.constructor.prototype.prop = 42;
k = {};
k.prop; // 42
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜