Why does an unexecuted eval have an effect on behavior in some browsers?

前端 未结 3 1165
死守一世寂寞
死守一世寂寞 2020-12-24 14:02

Let\'s suppose I have these two functions:

function change(args) {
    args[0] = \"changed\";
    return \" => \";
}
function f(x) {
    return [x, change         


        
3条回答
  •  不思量自难忘°
    2020-12-24 14:13

    Just playing around, I found that you remove the f. from the f.arguments value in the array, and just use arguments, the behavior is the same no matter what comes after the return:

    function f(x) {
        return [x, change(arguments), x];
    }
    function g(x) {
        return [x, change(arguments), x];
        eval("");
    }
    function h(x) {
        return [x, change(arguments), x];
        arguments;
    }
    

    In all three cases using x = "original", the output is:

    ["original", " => ", "changed"]
    ["original", " => ", "changed"] 
    ["original", " => ", "changed"]
    

    In this case, values are modified by change() as if the arguments array is passed by reference. To keep "original" unchanged, I might suggest converting the arguments object to an actual array first (thus passing arguments' elements by value):

    function h(x) {
        var argsByValue = Array.prototype.slice.call(arguments, 0);
        return [x, change(argsByValue), x];
    }
    

    In the above example, x will remain "original" before and after change(), because a copy of x was modified, not the original.

    I'm still not sure what the effects of having eval(""); or arguments; are, but your question is still interesting, as are the results.

    What's really strange is that this even affects putting the change() in its own function scope with a copy of the function arguments

    function f(x) {
        return ((function(args) {             
            return [x, change(args), x];
        })(f.arguments));
        // the presence of the line below still alters the behavior
        arguments; 
    }
    

    It seems that a reference to f.arguments still holds in this case. Weird stuff.

    UPDATES

    From MDN:

    The arguments object is a local variable available within all functions; arguments as a property of Function can no longer be used.

    Seems like, at least for Firefox, you shouldn't be using arguments as a property (e.g. function foo() { var bar = foo.arguments; }), though they don't say why.

提交回复
热议问题