吸气剂在 JavaScript 中不起作用

Getters are not working in JavaScript

我想弄清楚 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 ) 它抛出错误 "Cannot read property 'split' of undefined".

可能导致问题的原因是什么?看起来 'this' 在 get 函数中不可见,但据我所知应该如此。谢谢!

fullName 没有 getter 所以它 return undefined

得到

作为 属性 的 getter 的函数,如果没有 getter,则为未定义。函数 return 将用作 属性.

的值

默认为未定义

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

您不需要为 fullName 使用 setter,因为直接赋值即可。

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>'
);

您的代码需要一些 issues/changes:

  1. this.fullName.split(" ")[0]; => 将尝试调用 getFullName,因为 fullName 被定义为 属性。由于您尚未定义 getFullName 这会导致错误
  2. 假设您继续为 fullName 定义一个 getter:

    获取:函数(){ return this.fullName; }

    这将引发计算溢出,因为 this.fullName 最终递归调用 getFullName()

  3. 正确的使用方法是(当然更新设置器来做一些有用的事情):

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