JavaScript variable inside class is always undefined

风格不统一 提交于 2019-12-25 14:06:51

问题


I have a JavaScript class like this:

Dog = (function() {
    var name;

    function setName(_name) {
        name = _name;
    }

    return {
        setName: setName,
        name: name
    };
})();

When I run:

Dog.setName('Hero');

Dog.name is always undefined.

I am certainly missing something about JS scoping, but what?


回答1:


You are returning an object where name property has a value of name at that point in time (which is undefined). The name property of the returned object is not somehow dynamically updated when the name variable inside the IIFE is updated.

There are many ways to handle what you appear to be wanting to do. Here's one:

Dog = (function() {
    var name;

    function setName(_name) {
        name = _name;
    }

    return Object.defineProperties({}, {
      setName: { value: setName },
      name:    { get: function() { return name; } }
    });

})();

This keeps name as a private variable, which can only be set via setName, but provides a getter property for obtaining its value.

The alternative proposed in another answer is equivalent, just a different way of writing it:

return {
  setName:  function(n) { name = n; },
  get name: function() { return name; }
};

Minor point, but in this particular context you don't need parentheses around your IIFE:

Dog = function() { }();

will work fine.




回答2:


This happens because you assume that setting name in the object retains a reference to the original name variable. Instead, you want to assign it to the current object (which, you might as well ignore the private variable altogether).

Dog = {
  name: '',
  setName: function(n) {
    this.name = n;
  }
};

However, if you want to keep name private then you create a getter for it instead.

var Dog = (function() {
  var name;

  return {
    setName: function(n) {
      name = n;
    },
    get name: function() {
      return name;
    }
  };
})();



回答3:


The easy way to fix this is:

Dog = (function() {

var dog = {
    setName: setName,
    name: name
};

function setName(_name) {
    dog.name = _name;
}

return dog;
}

In your code, you were setting the wrong name variable.

var name;

function setName(_name) {
    name = _name;
}

In this function, setName is setting the internal variable name and not the property name. In JavaScript, strings are immutable, so when you change it, it creates a new string, and doesn't update the existing one.




回答4:


This might be a better pattern for you. You're using the very old ES3 style constructor.

(function(exports) {

  function Dog(name) {
    this.name = name;
  }

  Dog.prototype.speak = function() {
    return "woof";
  };

  // other functions ...

  exports.Dog = Dog;
})(window);

var d = new Dog('Hero');
console.log(d.name); // "Hero"

You might want to look into ES6 classes too

class Dog {
  constructor(name) {
    this.name = name;
  }
}

let d = new Dog('Hero'); 
console.log(d.name); // "Hero"



回答5:


Sounds like you want to make a constructor... Check this sample:

function Dog(prop) {
        this.name = prop.name;
        this.color = prop.color;
    }
    var myDog = new Dog({
        name:'Sam',
        color: 'brown'
    });
    alert()
    console.log('my dog\'s name is: '+myDog.name);
    console.log('my dog\'s color is: '+myDog.color);

you can try it here: http://jsfiddle.net/leojavier/ahs16jos/

I hope this helps man...




回答6:


Use the 'this' keyword.

Dog = (function() {
    var name;

    function setName(_name) {
        this.name = _name;
    }

    return {
        setName: setName,
        name: name
    };
})();
Dog.setName('Hero');
alert(Dog.name);


来源:https://stackoverflow.com/questions/32258237/javascript-variable-inside-class-is-always-undefined

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!