我需要对Youtube的iFrame API进行钩子,以将结果播放器分配给全局变量(我无法触摸实际调用API的代码)。
API的调用方式如下:
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
我想做的是这样的:
YT.OldPlayer = YT.Player
YT.Player = function() {
window.YTPlayer = new YT.OldPlayer(arguments)
return window.YTPlayer
}
YT.Player.prototype = YT.OldPlayer.prototype
但是由于某种原因,对new YT.Player()
的调用在我进行了修改后会导致原始调用无法调用的错误。我知道正在调用新的构造函数,但是对YT.OldPlayer()
的调用中的某些内容会导致错误,因为window.YTPlayer
是未定义的。我在做什么错了?
答案 0 :(得分:2)
这可能不是您要寻找的答案,而是PSA:
我在做什么错了?
我认为这里的主要问题是您尝试monkey-patch的外部库功能。
这不是一个好主意,不仅因为它可能无法按您认为的那样起作用,而且还因为将来可能会在没有任何警告的情况下中断。
您正在修改库可能在内部使用的功能上的功能。
库中可能还有其他功能可以进行假设并取决于此功能的特定行为,除非您阅读了整个库,否则您没有太多的可见性。
即使有效,图书馆也可能随时更改其假设,而不会发出警告。
请记住,您可能不会测试该功能的所有用例,并且库的作者对内部功能的工作方式不做任何承诺。他们可以更改其代码以使用或停止使用所涉及的功能,更改功能工作原理的内部方式等,而无需真正地公布更改。几乎可以肯定,这将以不可预见的方式破坏您的代码,因此您应尽可能远离这种模式。
结论:如果可以的话,找到一种解决问题的方法而又不触及您无法控制的库的内部结构,这将为您省去很多麻烦。
如果您仍然绝对需要这样做,那么您的问题似乎在于,您正在将参数作为类似于数组的对象传递,而这并不是在调用构造函数时得到的。
如果可以使用ES6 rest parameters和spread syntax,则可以执行以下操作:
YT.OldPlayer = YT.Player
YT.Player = function(...args) {
window.YTPlayer = new YT.OldPlayer(...args)
return window.YTPlayer
}
YT.Player.prototype = YT.OldPlayer.prototype
例如,如果您need to support IE且没有任何转换设置,则无法使用任何一种,则需要找到解决方法:
YT.OldPlayer = YT.Player
YT.Player = function() {
window.YTPlayer = new (YT.OldPlayer.bind.apply(YT,arguments))
return window.YTPlayer
}
YT.Player.prototype = YT.OldPlayer.prototype
答案 1 :(得分:0)
尝试应用参数:window.YTPlayer = new YT.OldPlayer.apply(this, arguments)
答案 2 :(得分:0)
我最终得到的解决方案是
YT.OldPlayer = YT.Player
YT.Player = function() {
window.YTPlayer = new YT.OldPlayer(...arguments)
return window.YTPlayer
}
YT.Player.prototype = YT.OldPlayer.prototype