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
精彩评论