Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Javascript创建类getter/setter的最佳方法?_Javascript_Oop_Getter Setter - Fatal编程技术网

用Javascript创建类getter/setter的最佳方法?

用Javascript创建类getter/setter的最佳方法?,javascript,oop,getter-setter,Javascript,Oop,Getter Setter,来自C#/PHP,我希望对使用Javascript创建的类(函数)拥有完整的getter/setter 然而,在我遇到的许多Javascript代码中,没有使用getter和setter,而是使用简单的公共变量 我很高兴看到关于getter和setter的文章,但是一些评论指出一些浏览器“不支持getter和setter”,这让我很困惑,因为它们不是Javascript的“特性”,而是一个使用基本Javascript语法的简单模式。这篇文章也是在2007年写的,所以现在可能已经过时了 Javas

来自C#/PHP,我希望对使用Javascript创建的类(函数)拥有完整的getter/setter

然而,在我遇到的许多Javascript代码中,没有使用getter和setter,而是使用简单的公共变量

我很高兴看到关于getter和setter的文章,但是一些评论指出一些浏览器“不支持getter和setter”,这让我很困惑,因为它们不是Javascript的“特性”,而是一个使用基本Javascript语法的简单模式。这篇文章也是在2007年写的,所以现在可能已经过时了

Javascript中getter和setter的当前状态是什么?它们是否真的得到了当今所有浏览器的“支持”(无论这意味着什么)?它们是Javascript的有用编程模式还是Javascript类(作为函数)使用公共变量更好?有没有比下面更好的方法来实现它们

$(document).ready(function() {
    var module = new Module('idcode');
    module.set_id_code('new idcode');
    module.set_title('new title');
    $('body').html(module.get_id_code()+': '+module.get_title());
});

function Module(id_code, title) {
    var id_code = id_code;
    var title = title;

    //id_code
    this.get_id_code = function() {
        return id_code;
    }
    this.set_id_code = function(value) {
        id_code = value;
    }

    //title
    this.get_title = function() {
        return title;
    }
    this.set_title = function(value) {
        title = value;
    }
}

getter和setter不是特性,而是不支持属性语法的语言的“设计模式”(本例中的代码膨胀)

因为Javascript不需要getter和setter,所以您不想编写它们。使用您可以使用的语言功能,在一种语言中效果很好的习惯用法在另一种语言中效果不太好

我最喜欢的一句话来自Python社区:

我们都是成年人

当讨论为什么不需要私有变量和信息隐藏时

报价可以找到

了解该语言为您提供了什么,并接受其文化和规则。

如何:

function Module(id_code, title) {
    var id_code = id_code;
    var title = title;

    var privateProps = {};

    this.setProperty = function(name, value) {
      // here you could e.g. log something
      privateProps[name] = value;
    }

    this.getProperty = function(name) {
      return privateProps[name];
    }
}

这里的getter和setter方法作用于私有对象,该私有对象用于存储无法从任何其他方法访问的属性。例如,您可以实现一个setter(或getter),它记录或执行ajax或其他任何操作,只要属性被修改(getter/setter方法的目的之一)。

我认为您没有抓住要点。(或者其他回答者可能没有抓住要点。)ECMAScript提供了一种“幕后”getter/setter机制,以便

x.foo = 3;
y = x.foo;
真的翻译成(某种程度上)

其中,
PutValue
GetValue
是未命名的,不能直接访问setter函数和属性getter函数。(参见,第8.7.1.和8.7.2节)第三版似乎没有明确定义用户如何设置自定义getter和setter函数。Mozilla的Javascript实现过去和现在都是如此,例如(这是使用Javascript 1.8的版本):

语法是(或至少到目前为止是)特定于浏览器的。至少根据调查,Internet Explorer尤其缺乏

ECMAScript标准的第5版似乎确实在这一机制上实现了标准化。看


编辑:也许出于您的目的,有一个更实际的例子:

function makePrivateObject()
{
   var state = 0;
   var out = {};
   out.__defineSetter__("foo", function(x) {});
   // prevent foo from being assigned directly
   out.__defineGetter__("foo", function() { return state; });
   out.count = function() { return state++; }
   return out;
}

js>x = makePrivateObject()
[object Object]
js>x.foo
0
js>x.foo = 33
33
js>x.foo
0
js>x.count()
0
js>x.count()
1
js>x.count()
2
js>x.foo
3

Firefox、Safari、Chrome和Opera(但不是IE)都有相同的非标准内置机制。ECMAScript 5包含一种不同的语法,现在是,将来也将成为标准。IE8已经有了这个特性,但只在DOM节点上,而不是在常规的本机JavaScript对象上。这就是语法的样子:

var obj = {};

Object.defineProperty(obj, "value", {
    get: function () {
        return this.val;
    },
    set: function(val) {
        this.val = val;
    }
});

实际上,您可以在javascript中定义setter和getter,而不仅仅是模仿它们。我认为它适用于除IE8及以下版本之外的所有浏览器

$(document).ready(function() {
  var module = new Module('idcode');
  module.id = 'new idcode';
  module.title = 'new title';
  $('body').html(module.id + ': ' + module.title);
});

function Module(id, title) {
  return {
    id_code: id_code,
    _title: title,

    get id() {
      return id_code;
    },
    set id(value) {
      id_code = value;
    },

    get title() {
      return _title;
    },
    set title(value) {
      title = value;
    }
  }
};
我喜欢这样:

//  Module
var Module = function() {

    // prive getter/setter value
    var __value;

    // private getter/setter method
    var _value = function() {
        if(!arguments.length) return __value;
        else __value = arguments[0];
    };

    // output/public     
    return {
        value: _value
    };
}

我喜欢的一种可靠的语义方式是使用和。例如,我创建了以下对象:

var myComplexObject={
更改日志:{},
日志:函数(名称,val){
console.log(“将“+name+”设置为“+val”);
如果(!this.changelog[名称])
this.changelog[name]=[];
this.changelog[name].push(val);
},
设置o(val){
这个.log(“o”,val);
},
得到o(){
log(“你永远不会知道真正的值!”);
返回42;
}
}
在这里,无论何时读取或修改
o
的值,行为都是定制的。以以下代码行及其控制台输出为例:

myComplexObject.o=“氧气”;
将氧设置为氧气
然后,在本例中,尝试读取值会导致以下结果:

var read=myComplexObject.o;
console.log(读取);
你永远不会知道真正的价值!
42
在此示例中,将记录您设置的每个新值:

myComplexObject.o=“哦,不!”;
log(myComplexObject.changelog.o);
将o设置为哦不!
[“氧气”,“哦,不!”]

确切地说,我不希望代码膨胀,但我希望像在PHP和C#等其他语言中一样,将对类的公共访问和私有访问分开。PHP有uuu get和uu set魔术方法,而C有其“属性语法”,可以在不使用臃肿语法的情况下实现分离。Javascript中有这样的功能吗?上面的代码是否在IE 7/8/9中工作,但没有提供任何有用的功能。setProperty和getProperty是公共函数,因此这只是增加了一个间接级别。它没有添加调用私有getter和setter函数的功能。它添加了除了通过getter和setter方法之外无法访问的属性,就像公共getter和setter方法用于修改其他语言中的私有成员一样。这是一个演示——这些方法也可以做其他事情。这很公平——但要么在代码中添加一个钩子来实现,要么在代码中添加一个注释来修改行为。是的,这对资深javascript程序员来说是显而易见的,但对初学者来说并非如此。@Jason s-补充了一些解释。这可能是内部处理它们的方式,但从技术上讲,如果我无法控制对它们的访问,它们仍然是“公共变量”。getter和setter对我来说的优点是,我可以确定,例如,“Salary”属性只能在内部更改,或者,当它被更改时,(a)更改被记录,(b)事件被触发,等等,除非我有getter/setter访问
$(document).ready(function() {
  var module = new Module('idcode');
  module.id = 'new idcode';
  module.title = 'new title';
  $('body').html(module.id + ': ' + module.title);
});

function Module(id, title) {
  return {
    id_code: id_code,
    _title: title,

    get id() {
      return id_code;
    },
    set id(value) {
      id_code = value;
    },

    get title() {
      return _title;
    },
    set title(value) {
      title = value;
    }
  }
};
//  Module
var Module = function() {

    // prive getter/setter value
    var __value;

    // private getter/setter method
    var _value = function() {
        if(!arguments.length) return __value;
        else __value = arguments[0];
    };

    // output/public     
    return {
        value: _value
    };
}