Partial Solution Notes:
Please note that the code snippets below show only "some alternatives that may or may not provide sufficient access." This is due to the fact that they do not fix the values (objects-objects) inside the constructor, but only transfer the values inside.
A “complete solution” can also wrap the Player constructor and use a property or other mechanism to “remember” objects created for different input values; Alternatively, he could remember the order in which the object was created. This could then be used to transfer the Match and then retrieve the created Players from the shared repository after starting the Match constructor, however, this data remains as an exercise. The player wrap code may use the code below (assuming Player is a global / available property).
An exact query is not possible given the above context.
Variables (real variables, not properties) can only be accessed from the area in which they are declared, or from the nested area, because they are allowed using visibility chains. This also includes the use of eval . Although this may seem like a limitation, it also ensures that area chains (and their variables) cannot be deleted externally if they are not open.
However, consider this fun approach that takes advantage of the fact that an explicit object can be return ed from the constructor:
var oldMatch = Match // note this form, else above would be pre-clobbered Match = function Match (playerRed, playerBlue) { var m = new oldMatch(playerRed, playerBlue) // either "inject" method here, or save in object for later m.myPlayerRed = playerRed m.myPlayerBlue = playerBlue return m }
Of course, this will break things like new Match(...) instanceof Match .
Happy coding.
Update:
Below is the modification above to work with "completing the constructor in the new constructor, and then set the prototypes to equal," as described in the link in the message. The trick is to "steal" a global property name. I also changed the code to keep oldMatch "private" to avoid pollution.
// note this form, else Match property would be pre-clobbered Match = (function (oldMatch) { function Match (playerRed, playerBlue) { oldMatch.call(this, playerRed, playerBlue); // either "inject" method here, or save in object for later this.myPlayerRed = playerRed this.myPlayerBlue = playerBlue } Match.prototype = oldMatch.prototype return Match })(Match)
Unlike the first code snippet, this should work with new Match(...) instanceof Match , but it can still break depending on the specific assumptions made in the methods of the Match object.
An example of how to invert ("extract") data from the Player constructor:
// original -- remember this method will only work // if Player is used as a property (and not itself a closure'd variable) function Player (name) { this.name = name } Player = (function (oldPlayer) { function Player (name) { oldPlayer.call(this, name) var fn = arguments.callee fn.recent = fn.recent || [] fn.recent.push([name, this]) } Player.prototype = oldPlayer.prototype return Player })(Player) var p1 = new Player("fred"); var p2 = new Player("barney"); alert("instanceof check? " + p1 instanceof Player) alert("name check? " + ("barney" == p2.name)) alert(Player.recent.join(",")) Player.recent = [] // reset