Получение неверных формальных параметров - PullRequest
5 голосов
/ 29 августа 2009

Это НАСТОЯЩИЙ вызов

Я хотел бы знать, как кто-то может получить недопустимые формальные параметры в функции без объекта arguments, чтобы имитировать, не зная формат назначения деструктуры параметров. Это не вопрос ECMAScript и относится только к JavaScript.

Ваш mySolution не может получить доступ к arguments или test. Вам предоставляется массив args, который содержит имена параметров. Вы должны вернуть объект, у которого есть свойство для каждого параметра, который является параметром, который был передан функции. Короче говоря, results[prop] must === test[prop]. Ваше решение не должно опираться на ошибки или дыры в безопасности, поскольку они могут отсутствовать в будущем. Решение этой проблемы, о которой я имею в виду, не зависит от каких-либо ошибок.

(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")
}());

Вот одно из двух возможных решений, которые я бы принял:

(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")
}());

Решение работает с использованием пространства имен function:: по умолчанию в сочетании с eval() scope.

Например: foo.function::bar и foo.function::['bar'] - это одно и то же foo.bar.

Ответы [ 8 ]

4 голосов
/ 06 сентября 2009

за 100 баллов


(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")
}());

2 голосов
/ 04 сентября 2009

Протестировано PASS в FireFox 3.0.13! Я "обманул", изменив прототип Object:

<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>

Это считается? Я думаю, что, вероятно, нет. = Р

0 голосов
/ 06 сентября 2009
(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") }());
0 голосов
/ 05 сентября 2009

перепробовал много способов. Вид отказались. Но если вы не можете сломать систему, измените систему. МОЕ решение:


(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")
}());
0 голосов
/ 05 сентября 2009

Попытка № 3; еще раз протестировал PASS в 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>
0 голосов
/ 04 сентября 2009

Aha! На этот раз я нашел лучший ответ. (Я должен признать, что я получил общую идею из ответа Кангакса, хотя). Протестировано PASS в 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>
0 голосов
/ 29 августа 2009

Я могу думать только об одном способе достижения этого, и даже о том, что один из этих способов зависит как от устаревшей callee.caller, так и от уже фиксированной особенности FF eval, позволяющей выполнять код в контексте указанной функции.

Что интересно, я думаю, что eval был "исправлен" до того, как было введено расширение function({...}){}, но я не совсем уверен.

Я немного сократил контрольный пример, но, конечно, сохранил реальную идею.

Сначала я попытался получить доступ к arguments самого вызывающего, но похоже, что <fn>.arguments ссылается на тот же объект, что и arguments в контексте функции; null в аргументах объект существенно уничтожил объект, на который также ссылается свойство arguments.

Я также думал о том, чтобы вывести строку стека из объекта ошибки (чтобы получить test значения), но это ничего не решило, поскольку тестовые значения - это объекты, а не примитивы.

(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");
})();
0 голосов
/ 29 августа 2009

Домашнее задание? Вот подсказка: используйте eval.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...