【问题标题】:Getters and setters on prototype原型上的 getter 和 setter
【发布时间】:2013-12-06 14:49:32
【问题描述】:

考虑以下一点点 JavaScript:(我不担心向后兼容性,我不想使用任何很快就会被弃用的东西)。

  var Person = (function () {
            var _age,
                _name;
            function age(num) {
                if (!num) {
                    return _age;
                }
                else {
                    _age = num;
                }
            }
            function name(val) {
                if (!val) {
                    return _age;
                }
                else {
                    _name = val;
                }
            }
            return {
                age: age,
                name: name
            }
        })();
        console.log(Person.age()); //undefined
        Person.age(100);
        console.log(Person.age()); //100

(不确定这会有多大用处,如果我想做一些多态的东西,这里的原型仍然是 Object。)

对比(iffy内部的构造函数,闭包允许name和val访问_name和_val

  var Person = (function () {
            var _age,
                _name;
            function Person(options) {
                _age = options.age;
                _name = options.name;
            }
            Person.prototype.age = function (val) {
                if (!val) {
                    return _age;
                }
                else {
                    _age = val;
                }
            }
            var test = new Person({ age: 100, name: 'jon' });
            console.log(test.age());//100
           //if I want to do with Person objects outside of this script I should
           //return something
        })();

(这允许我正在寻找的标准属性样式(空参数返回一个值,传递一个参数将设置该值

function Person(age, name) {
        //i don't want to add get and set methods to each instance of Person
        }
        Person.prototype.age = function (num) {
            if (!num) {
                //what to return if nothing is passed to age?
                return //what?
            }
            else {
                //x = num
                //what would x be?
            }
        }

我需要能够基于原型多态地执行一些操作。最后一个代码 sn-p 是最容易阅读的,但它不提供我正在寻找的 get/set 简洁性。第一个代码 sn-p 可以很好地让我 Object.create 但它有 Object 作为原型。如果我想要像obj.test() 这样的get/set 方法来get 和obj.test(100) 来设置,我怎样才能实现向原型添加方法而不是在构造函数本身内部?

【问题讨论】:

  • 您的第二个示例不适用于多个实例
  • 为什么要在原型上使用 setter 和 getter?在构造函数中创建它们很好。
  • @Bergi 将它们放在原型上没有真正的优势吗?我的印象是这是最佳实践?还是仅用于方法而不是属性?
  • 好吧,特定于实例的属性(例如想要使用特定于实例的变量范围来实现私有性的 getter/setter 方法)需要进入构造函数。使用原型只是可以在实例之间共享的属性(值和方法)的最佳实践。
  • @Bergi 很高兴知道,因为我觉得我不得不尝试在原型上硬设置 get/set。我只是不想偷懒,但这让事情变得容易了 100 倍。 :)

标签: javascript jquery constructor


【解决方案1】:

与您的问题没有直接关系,但由于您在标题中提到了“getter and setter”,我想我可以用 ES5 getter 和 setter 来补充答案:

function Person(age, name) {
  this.name = name;
  this.age  = age;
};

Object.defineProperty(Person.prototype, "age", {
  get: function() {
    return this._age;
  },

  // Added a few things to demonstrate additional logic on the setter
  set: function(num) {
    num = parseInt(num, 10);
    if(num > 0) {
      this._age = num;
    }
  }
});

然后,它可以透明地使用,就像它是一个普通的属性:

var person = new Person(20, "Jane Doe");
person.age; // => 20

person.age = 15;
person.age; // => 15

person.age = "20";
person.age; // => 20 (number)

person.age = -2;
person.age; // => 20

适用于任何最新的浏览器,并且 IE >= 9。

【讨论】:

  • 这是我真正想要的。 +1
【解决方案2】:

您必须将其作为公共属性存储在您的实例上。常用的约定是使用_ 作为私有成员。

这是一个适合你的实现。

function Person(age, name) {
    this.age(age);
}
Person.prototype.age = function (num) {
    if (!num) {
        return this._age;
    }
    else {
        this._age = num;
    }
}

【讨论】:

  • 这里的sn-p在哪个代码里?原型上的函数不能访问构造函数中的变量,不是吗?
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多