Using the variable “name” doesn't work with a JS object

后端 未结 4 1995
不知归路
不知归路 2020-11-21 06:11

The behaviour can be seen in this little snippet (execute it as a global script):

var name = {};
name.FirstName = \'Tom\';
alert(name.FirstName);


        
相关标签:
4条回答
  • 2020-11-21 06:42

    window.name has a special purpose, and is supposed to be a string. Chrome seems to explicitly cast it to a string, so var name = {}; actually ends up giving the global variable name (i.e. window.name) a value of "[object Object]". Since it's a primitive, properties (name.FirstName) won't "stick."

    To get around this issue, don't use name as a global variable.

    0 讨论(0)
  • 2020-11-21 06:47

    With ES6+, you could write your code as let name or const name. This won't assign it or try to override window.name. More on that here.

    let name = {};
    name.FirstName = 'Tom';
    alert(name.FirstName);

    0 讨论(0)
  • 2020-11-21 06:49

    Your name variable is actually window.name, because top-level variables declared with var are attached to the global object.

    The HTML5 spec requires that window.name is a DOMString. This means that the value of window.name can only be a sequence of characters, not an object.

    In Chrome, an attempt to use window.name to store anything except a primitive string will coerce the value to a primitive string. For example:

    window.name = {};
    window.name === "[object Object]"; // true
    

    You can avoid this problem by using a name variable that is not in the top-level scope:

    (function() {
        var name = {};
        // this `name` is not `window.name`
        // because we're not in the top-level scope
    
        console.log(name);
    })();
    
    0 讨论(0)
  • 2020-11-21 06:53

    window.name is used to set the name of the window, and since the window name can only be a string, anything you set to window.name is converted to a string. And strings, as primitive values, cannot have properties. The solution is to use a different variable name or a different scope.

    Alternatively, you can use window.name as you like if you have this code first. I don't recommend this at all, but, just as a proof of concept:

    (function () {
        var _name;
        window.__defineGetter__('name', function () {
            return _name;
        });
        window.__defineSetter__('name', function (v) {
            _name = v;
        });
    })();
    

    Additionally, you should use {} in place of new Object. Besides being more concise, it is also more efficient and more explicit.

    0 讨论(0)
提交回复
热议问题