JavaScript属性访问器(javascript property accessors)

2019-06-28 00:23发布

在Javascript中,它似乎像使用属性访问器是不是所有的普通(不像其他面向对象的语言如Java为例)。

如果我有一个Person与一个名字对象,定义为

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

一个人的名字不会改变,但我希望能够在需要时访问它,这样我就可以这样做:

function Person(name) {
   var name = name;
   this.getName = function() {
      return name;
   }
}

即使是在一个动态语言,我想用干将的原则和setter方法应用于他们做静态类型的面向对象语言的相同方式(如封装,添加验证,限制出入等)

这个问题可能会封闭,主观的,但我很好奇,为什么这种行为不会出现更多的时候(例如,Java开发人员会发疯,如果一切公共)。

是否有一个“标准”的方式在JavaScript做到这一点? 我见过Object.defineProperty ,但并不是所有的浏览器都支持这一点。

Answer 1:

JavaScript有拦截,能够属性访问:

http://ejohn.org/blog/javascript-getters-and-setters/

恕我直言,这是一个更好的解决方案来执行比Java的更严格明确的干将统一接入的原则,但也是语言的简单性和灵活性的一部分(Groovy的例如允许类似拦截)。



Answer 2:

我知道我的关于这个问题的看法。

getter和setter是邪恶的。

等待! 真! 和我一起承担了一会儿,让我解释一下。

只需使用一种方法来获取和设置一个值..好..有点毫无意义。 它不保护,不是真的,和你投入的是你得到了什么。

在另一方面,我比较喜欢的是,在把信息的方法,然后获取信息回来。 但这里是魔法的一部分! 它是不一样的信息。 不能直接使用。

function Person(name) {
  this.getFullName = function() {return this.firstName + " " + this.lastName;};
  this.setBirthday = function(date) { this.birthday = date; };

  this.getAge = function() { /* Return age based on the birthday */ };
  this.isOfLegalDrinkingAge function() { /* do your math here too */ };
}

但大多数时候,我只是推搡中的静态数据和获取静态数据出来。 什么是隐藏它的getter和setter背后的意义呢?

作为一个次要原因,处理DOM和大多数主机对象,设置属性。 你不getter和setter玩。 不使用它们适合的什么JS程序员做“味”的其余部分。



Answer 3:

我认为答案是,在JavaScript中模拟类是不常见的做法,因为语言实际上是原型。

虽然可以创建类似的结构类(如你的例子),他们是不是真的像Java类,作为一个程序员,你最终的细微差别战斗。

但是,如果你拥抱的JavaScript的原型本质,你是不同的,但凝聚力和结构简单的语言奖励。

这是没有必要使用getter和setter与原型结构,你可以简单地通过设置,以及一个对象,将其设置为一个值,并得到它,称它作为一种价值。

JavaScript不强迫你写的代码结构,不这样做阻止你。 我认为,已经长大了周围的JavaScript的文化已经开发出了良好的编码风格,那是完全有效的,从我用任何其他语言不同。

我知道这个答案是不明确的,并且定论,但希望里面还有一些想法,帮助您找到您正在寻找的雁。



Answer 4:

我很抱歉,如果我不理解正确的问题,而是自我执行功能是使成员公共/私人的一种方式

var Person = function(){
  var _name = "Roger",
      self = { getName : function (){ return _name; }};
  return self;
}()

然后,您可以从任何地方访问Person.getName(),但不能设置_name。



Answer 5:

这是我用于本地字段:

TYPE_DEFAULT_VALUE= {
    number: 0,
    string: "",
    array: [],
    object: {},
};

typeOf = function (object) {
    if (typeof object === "number" && isNaN(object))
        return NaN;
    try {
        return Object.prototype.toString.call(object).slice(8, -1).toLowerCase();
    }
    catch(ex) {
        return "N/A";
    };
};

getAccessor = function(obj, key, type, defaultValue) {
    if (defaultValue === undefined) 
        defaultValue =  TYPE_DEFAULT_VALUE[type] === undefined ? null : TYPE_DEFAULT_VALUE[type];
    return {
        enumerable: true,
        configurable: true,
        get: function () {
            if (obj[key] === undefined) 
                obj[key] = defaultValue;
            return obj[key];
        },
        set: function (value) {
            if (typeOf(value) === type)
                obj[key] = value;
        },
    };
}

LocalFields = function (fields, object) {
    /**
    * field properties
    * { 
    *   type: [ required ] ( number | string | array | object | ... ),
    *   defaultValue: [ optional ]
    * }
    */
    if (! fields)
        throw "Too few parameters ...";
    if (! object) 
        object = this;

    var obj = this;
    var fieldsAccessor = {};
    for(key in fields){
        field = fields[key];
        fieldHandler = key[0].toUpperCase() + key.substr(1);
        if(! field.type)
            throw "Type not set for field: " + key;

        fieldsAccessor[fieldHandler] = getAccessor(obj, fieldHandler, field.type, field.defaultValue)
    }
    Object.defineProperties(object, fieldsAccessor);
}

现在,每一个类,我可以只调用是这样的:

Person = function(){
    new LocalFields({
        id:     { type: "number" },
        name:   { type: "string" },
    }, this);
}

然后像VS getter和setter你拨打:

var alex = new Person();
alex.Name = "Alex Ramsi";
console.clear();
console.info(alex.Name);


文章来源: javascript property accessors