Getter无法使用JavaScript

时间:2015-06-30 19:05:14

标签: javascript getter-setter

我试图弄清楚JavaScript中的getter和setter是什么。 这是我的对象

  function User(fullName) {
        this.fullName = fullName;

        Object.defineProperties(this,{

            firstName :{
                get: function(){
                    return this.fullName.split(" ")[0];
                },
                set :function(value){
                    this.firstName = value;
                }
            },
            lastName:{
                get: function(){
                    this.lastName = this.fullName.split(" ")[1];
                },
                set: function(value){
                    this.lastName = value;
                }
            },
            fullName :{
                set: function(value){
                    this.fullName = value;
                }
            }
        });
}

然后创建一个新用户:

var user = new User("New User");

但是当我试图获得像

这样的firstName属性时

alert( user.firstName )     它会抛出一个错误"无法读取属性' split'未定义"。

可能导致什么问题?它看起来像这个'在get函数中是不可见的,但据我所知它应该。谢谢!

3 个答案:

答案 0 :(得分:1)

您不需要fullName的设置器,因为直接分配将起作用。

function User(fullName) {
  this.fullName = fullName || '';

  Object.defineProperties(this, {
    firstName: {
      get: function() {
        return this.fullName.split(" ")[0];
      },
      set: function(value) {
        this.firstName = value; // NOTE: This will throw an error
      }
    },
    lastName: {
      get: function() {
        return this.fullName.split(" ")[1];
      },
      set: function(value) {
        this.lastName = value; // NOTE: This will throw an error
      }
    }
  });
}

var joe = new User('John Doe');
var jane = new User('Jane Dane');
jane.fullName = 'Jane Doe';
document.write(
  '<pre>' + joe.firstName + '</pre>' +
  '<pre>' + jane.lastName + '</pre>'
);

但是,如上面的代码注释中所述,您无法将this上的属性设置为与具有setter的已定义属性相同的名称。例如:

// defining `firstName`
firstName: {
  ...
  set: function(value) {
    this.firstName = value; // NOTE: This will throw an error
  }

此操作将导致递归堆栈错误,因为它会不断尝试更新firstName,因为this.firstName是一个setter。

为避免这种情况,您可以在构造函数中使用本地范围的变量,并执行以下操作:

function User(fullName) {
  var firstName;
  var lastName;

  Object.defineProperties(this, {
    firstName: {
      get: function() {
        return firstName;
      },
      set: function(value) {
        return (firstName = value);
      }
    },
    lastName: {
      get: function() {
        return lastName;
      },
      set: function(value) {
        return (lastName = value);
      }
    },
    fullName: {
      get: function() {
        return firstName + ' ' + lastName;
      },
      set: function(value) {
        var names = value && value.split(' ');
        firstName = names[0];
        lastName = names[1];
      }
    }
  });
  
  if (fullName) {
    this.fullName = fullName;
  }
}

var joe = new User('John Doe');
var jane = new User('Jane Dane');
jane.lastName = 'Doe';
document.write(
  '<pre>' + joe.firstName + '</pre>' +
  '<pre>' + jane.lastName + '</pre>'
);

答案 1 :(得分:1)

Some issues/changes needed to your code:

  1. this.fullName.split(" ")[0]; => will try to invoke the getFullName since fullName is defined as a property. Since you have not defined getFullName this results in an error
  2. Say you go ahead and define a getter for fullName:

    get: function() { return this.fullName; }

    This will throw a stackoverflow since this.fullName ends up recursively calling getFullName()

  3. The right way to use it would be (of course update the setters to do something useful):

function User(fullName) {
    this.fullName = fullName;
    Object.defineProperties(this, {

        firstName: {
            get: function () {
                return this.fullName.split(" ")[0];
            },
            set: function (value) {
                this.firstName = value;
            }
        },
        lastName: {
            get: function () {
                return this.fullName.split(" ")[1];
            },
            set: function (value) {
                this.lastName = value;
            }
        }
    });
}
var user = new User("New User");
alert( user.firstName );

答案 2 :(得分:0)

fullName没有getter,因此返回undefined

获取

一个函数,用作属性的getter,如果没有getter,则为undefined。函数return将用作property的值。

默认为未定义

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description