Reputation: 35850
I would like to know how someone would get an invalid formal parameters in a function without the arguments
object to as simulate not knowing the format of the parameter destructuring assignment. This is not an ECMAScript question and only pertains to JavaScript.
Your mySolution
cannot access arguments
or test
. You are provided with an args
array which contains the parameter names. You must return an object which has a property for every parameter which is the parameter that was passed to the function. In short, results[prop]
must === test[prop]
. Your solution shouldn't rely on bugs or security holes as they may not be present in the future. The solution to this problem of which I have in mind does not rely on any bugs.
(function () {
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// prohbit reference to arguments and the test object
var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
// put your solution here
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL")
}());
Here's one of the two possible solutions that I would have accepted:
(function () {
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// prohbit reference to arguments and the test object
var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
var i = args.length;
while (i--) {
results[args[i]] = eval("function::" + args[i]);
// function::[args[i]] won't work unless you eval() it
}
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL")
}());
The solution works by using the default function::
namespace in combination with eval()
scope.
For example: foo.function::bar
and foo.function::['bar']
are the same thing foo.bar
.
Upvotes: 5
Views: 2504
Reputation: 670
For 100 points
(function () {
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// prohbit reference to arguments and the test object
var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
// put your solution here
var getEscUnicode = function(str) {
var ret = "";
for(var j = 0; j < str.length; j++) {
var temp = parseInt(str.charCodeAt(j)).toString(16).toUpperCase();
for(var i=0; i < 5 - temp.length; i++) {
temp = "0" + temp;
}
ret = ret + "\\u" + temp;
}
return ret;
}
for(var i = 0; i < args.length; i++) {
results[args[i]] = eval(getEscUnicode(args[i]));
}
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL")
}());
Upvotes: 4
Reputation: 5369
(function () {
function mySolution ({ var, this, function, if, return, true }) {
// prohbit reference to arguments and the test object
var test = arguments = null, args = ['var', 'this', 'function', 'if', 'return','true'], results = {};
//LAME...
};
mySolution=function(a){var results=a;
//LAME...
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {} }, results = mySolution(test), pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop]) pass = false;
alert(pass ? "PASS" : "FAIL") }());
Upvotes: 0
Reputation: 670
Tried lots of ways. Kind of given up. But if you can't break the system, change the system. MY solution:
(function () {
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// prohbit reference to arguments and the test object
var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
// put your solution here
/********** MY SOLUTION STARTS ******************/
return null;
}
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// new function does not prohbit reference to arguments and the test object
//var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
for(var i =0; i < args.length; i++) {
results[args[i]] = arguments[0][args[i]];
}
/********** MY SOLUTION ENDS ******************/
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL")
}());
Upvotes: 0
Reputation: 7739
Attempt #3; again, tested PASS in FF 3.0.13
<html>
<head>
<title></title>
<script>
(function () {
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// prohbit reference to arguments and the test object
var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
// put your solution here
var o = mySolution[0];
for (var prop in o) {
results[prop] = o[prop];
}
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL")
}());
</script>
</head>
<body>
<!-- Put the body of your page below this line -->
<!-- Put the body of your page above this line -->
</body>
</html>
Upvotes: 0
Reputation: 7739
Aha! I found a better answer, this time. (I have to admit that I got the general idea from kangax's answer, though). Tested PASS in FF 3.0.13:
<html>
<head>
<title></title>
<script>
(function () {
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// prohbit reference to arguments and the test object
var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
// put your solution here
var o = eval('arguments', mySolution)[0];
for(var prop in o) {
results[prop] = o[prop];
}
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL")
}());
</script>
</head>
<body>
<!-- Put the body of your page below this line -->
<!-- Put the body of your page above this line -->
</body>
</html>
Upvotes: 0
Reputation: 7739
Tested PASS in FireFox 3.0.13! I "cheated", by altering the Object prototype:
<html>
<head>
<title></title>
<script>
(function () {
function mySolution ({
var,
this,
function,
if,
return,
true
}) {
// prohbit reference to arguments and the test object
var test = arguments = null,
args = ['var', 'this', 'function', 'if', 'return', 'true'],
results = {};
// put your solution here
Object.prototype._hasOwnProperty = Object.prototype.hasOwnProperty;
Object.prototype.hasOwnProperty =
function(prop) {
results[prop] = this[prop];
return this._hasOwnProperty(prop);
}
return results;
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL")
}());
</script>
</head>
<body>
<!-- Put the body of your page below this line -->
<!-- Put the body of your page above this line -->
</body>
</html>
Does this count? I guess it probably doesn't. =p
Upvotes: 2
Reputation: 39168
I can only think of one way to achieve this and even that one way relies on both - deprecated callee.caller
and an already fixed FF peculiarity of eval
being able to execute code in a context of a specified function.
What's interesting is that I think eval
was "fixed" before function({...}){}
extension was introduced, but I'm not totally sure.
I reduced test case slightly, but preserving an actual idea, of course.
I first tried accessing arguments
off of a caller itself, but it looks like <fn>.arguments
references same object as arguments
within function context; null
ing arguments object essentially destroyed object referred to by arguments
property as well.
I also thought about evaling stack string from an error object (to get test
values), but that would not solve anything, as test values are objects, not primitives.
(function () {
function mySolution () {
var test = arguments = null;
return eval('test', (function(){ return arguments.callee.caller; })());
};
var test = {
"var" : {},
"this" : {},
"function": {},
"if" : {},
"return" : {},
"true" : {}
},
results = mySolution(test),
pass = true;
for (var prop in test)
if (test.hasOwnProperty(prop))
if (results[prop] !== test[prop])
pass = false;
alert(pass ? "PASS" : "FAIL");
})();
Upvotes: 0