如何在Javascript对象(类)中使用setter和getter?

3
以下脚本无法运行。应该如何正确操作?
function AnObject () {
    get this.apple = () {
        return this.apple + "GET";
    }
    set this.apple = ( newValue ) {
        return newValue + "SET";
    }
}

var obj = new AnObject();
obj.apple = "Lemon";
console.log( obj.apple ); // LemonSETGET

有什么问题吗?你从未在“set”方法中设置值。 - tymeJV
4个回答

5
你可以使用 Object.defineProperties() 方法:
function AnObject() {
  Object.defineProperties(this, {
    apple: {
      get: function() {
        return this._apple + " GET";
      },
      set: function(value) {
        this._apple = value;
      },
      configurable: true, writable: true
    }
  });
 }

请注意,如果您想直接在对象中保留值,请小心使用不同的属性名称。否则,您可以使用构造函数的闭包:
function AnObject() {
  var theApple;

  Object.defineProperties(this, {
    apple: {
      get: function() {
        return theApple + " GET";
      },
      set: function(value) {
        theApple = value;
      },
      configurable: true, writable: true
    }
  });
 }

3

补充Pointy的观点,

你可以将获取器和设置器作为语言特性使用,只需将它们放置在对象字面量内部。

通过以下方式,您可以将原始构造函数转换为工厂,并使用基于实例的获取器和设置器:

function makeAnObject () {
    var hiddenApple = "Granny Smith";
    return {
      get apple () { return hiddenApple; },
      set apple (ignore) { return hiddenApple; }
    };
}

var thing = makeAnObject();
thing.apple;
thing.apple = "Crab Apple";

请记住,依赖于getter/setter的方法在老旧浏览器(IE8是个大问题)上会直接崩溃,如果这种方式被使用。
而且,在defineProperties中使用它们可以避免IE8的崩溃(因为它不再是语言结构)......但是,它实际上并没有添加getter/setter(即使使用了将该方法添加到Object而不仅仅是DOM元素的polyfill),因此,会有错误行为,要么是由于语法错误,要么是由于与其他浏览器完全不同的操作方式。
这可能现在对您不适用,希望永远不会出现......我们中的一些人仍然生活在那个可怕的现实中。

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Mark
是的,它确实如此。然而,IE8是Windows XP上的最后一个IE版本。那些有大量开放式软件盗版的地方(例如:中国),仍然有很多人在运行IE8(奇怪的世界;为一些世界上最好的智能手机编写仅限移动站点,但如果您想要桌面站点,则必须兼容IE8)。还有一些公司仍未将工作电脑升级到Windows 7/8/10,并锁定了浏览器。如果您能承受您的网站完全崩溃并且无法使用(或测试IE LTE 8并将其发送到browsehappy.com),那就去做吧。 - Norguard
有很多很棒的新功能。当你知道你的访问者是谁,而且那1%不值得关注(或者告诉他们在旧的iPod Touch上会有更好的体验)时,没有理由不使用它们,但当它占到10%的付费客户等时,你就没有这个选择了。还有一些polyfills和构建工具可以帮助在IE6-8中运行花哨的新功能;但是这些工具不能在某些更低级别的语言特性(代理、弱映射、getter/setter)上100%地工作,因此一些更好的功能被闲置,以便大多数人可以使用。 - Norguard

1
class User {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }


  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }


  set fullName(newValue) {
    [this.firstName, this.lastName] = newValue.split(' ');
  }



};

let user = new User("AAAA", "BBBB");
alert( user.fullName ); 
user.fullName = "CCCC DDDD";
alert( user.fullName ); 

0

JS中没有setter和getter

但是你可以模拟它们

function AnObject () {
    var apple = '';
    this.get = function() {
        return apple + "GET";
    }
    this.set = function( newValue ) {
        apple = newValue + "SET";
    }
}

var obj = new AnObject();
obj.set("Lemon");
console.log( obj.get() ); // LemonSETGET

2
有。它们只需要IE9+,并且在Object Literals(或defineProperties)中定义。此外,它们不掩盖属性,如果您想保存并检索某些内容,则需要引用不同的属性/变量。 - Norguard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接