在JavaScript对象中实现setter和getter

在JavaScript对象中实现setter和getter,javascript,getter-setter,Javascript,Getter Setter,我想在本地服务器上实现setter和getter javascript变量。下面是一个示例函数: function someThing() { var someLocalvariable = ''; } // with this function I want to // return value of someLocalvariable // also if it is possible to implement // setter in this way. someThing.p

我想在本地服务器上实现setter和getter javascript变量。下面是一个示例函数:

function someThing() {
   var someLocalvariable = '';
}

// with this function I want to 
// return value of someLocalvariable
// also if it is possible to implement
// setter in this way. 
someThing.prototype.getLocalVar = function() {

}
我希望变量是“真正”私有的。我不会的 要使用类似的方法: someThing.prototype.sometlocalvariable=

或将函数附加到如下内容()中:

function someThing() {
      var someLocalvariable = '';
   this.getLocalvariable = function() {
      return someLocalvariable;
   }
}
function Field(val){ var value = val; this.getValue = function(){ return value; }; this.setValue = function(val){ value = val; }; } var field = new Field("test"); field.value // => undefined field.setValue("test2") field.getValue()
我将非常感谢您的指导和帮助。

道格拉斯·克罗克福德(Douglas Crockford)曾写过一篇关于用JavaScript实现私有成员的文章,内容如下:

function someThing() {
      var someLocalvariable = '';
   this.getLocalvariable = function() {
      return someLocalvariable;
   }
}
function Field(val){ var value = val; this.getValue = function(){ return value; }; this.setValue = function(val){ value = val; }; } var field = new Field("test"); field.value // => undefined field.setValue("test2") field.getValue() 功能字段(val){ var值=val; this.getValue=函数(){ 返回值; }; this.setValue=函数(val){ 值=val; }; } var字段=新字段(“测试”); 字段值 //=>未定义 字段设置值(“test2”) field.getValue()
Check ref:

您不想做的最后一个示例不起作用(它有语法错误),(它已被修复),但我认为您可能指的是通常的方法,即在构造函数中创建getter和setter闭包(如下所示)

不幸的是,如果您想要真正的私有变量,这几乎是您唯一的选择。没有其他方法可以获得真正私有的、特定于实例的变量。但是,请参见下面的“黑客”

以下是通常做法的正确版本(我想你说过你不想要,但为了完整性):

和大多数人一样,我第一次看到这种模式是在上个月

这个选项有一个缺点:通过
SomeThing
构造函数创建的每个实例都有自己的两个函数。它们不能在实例之间共享。因此,如果你的应用程序中有成百上千的
某个
实例,那就需要从内存的角度来考虑。如果会有几百个或更少,这可能并不重要。(这些数字是从帽子里拿出来的,你不应该相信它们,当/如果出现某种问题时,你必须检查代码的内存使用情况;但是你明白了。)

黑客攻击:如果您的实例上已经有某种唯一标识符作为公共数据(或者您愿意添加一个,它也将是公共的),并且如果您愿意在实例的使用中添加相当多的复杂性,您可以拥有一个私有缓存,它保存只有代码才能访问的所有实例的数据,并通过对象的唯一标识符将密钥输入到该缓存中。这样(在本例中,我分配
id
值,但如果您有现有的唯一id,您可以使用它们):

工作原理如下:所有函数都是外部作用域函数中
cache
局部变量上的闭包。我们使用对象的唯一ID对其进行索引,该ID为我们提供了一个对象,我们将私有数据成员放在该对象上。当使用实例的代码使用它完成时,该代码必须调用
destroy
(这是此模式的一个主要缺点),因此我们通过删除
id
的属性从
缓存中删除私有数据对象

注意事项和费用:

  • 您仍然有一段公共数据,它是您的私有数据的密钥(
    id
    ,在上面)
  • SomeThing
    创建的实例的用户在处理完这些实例后,必须调用
    destroy
    。这是JavaScript垃圾处理工作方式的诅咒,但这是上述模式的一个要求,因为否则您最终会在
    缓存中生成cruft
    对象
  • (我不担心这一点)最终,如果你使用上面的自动
    id
    值,如果你的应用程序创建和销毁了很多这样的实例,那么这些值就会用完。但是JavaScript的数量确实上升了很多,如果这是一个问题,那就找一种不同的方法来分配ID,而不是像上面这样简单的不断增加的系统
我还没有在我的工作中使用上面的模式,但我希望它会有涉及数千个
实例的用例,因此不希望有每个实例的函数



旁注:在上面,我将
someThing
更改为
someThing
。在JavaScript中,标准做法是普通函数的名称以小写字母开头,构造函数的名称(与
new
一起使用)以大写字母开头。由于
某物
是要与
新的
一起使用的,所以我对其进行了限制。这只是一个惯例,但它是一个非常流行的惯例,当然,它在语言定义本身中使用(
Date
是一个构造函数,
setHours
是一个函数)。

这是不可能的。如果在someThing()中有一个局部变量,则附加到原型的函数无法读取其值(记住,它是私有的?)。上一个示例是这个问题的正常解决方案,为什么这还不够好?

在函数构造函数中使用Object.defineProperty()来定义getter和setter

要使某些值真正私有(外部不可见),请使用闭包, 可以找到更多信息

在下面的示例中,我们为属性
temperature
定义了一个getter和setter,其中内部“private”值存储在变量
var temperature

var-temperature
将永远无法从
Archiver()的外部看到/访问它,因为它是一个闭包

请注意,此模式在ES5上作为Object.defineProperty()工作。ES3不支持此模式

function Archiver() {
    var temperature = null;
    var archive = [];

    Object.defineProperty(this, 'temperature', {
        get: function () {
            console.log('get!');
            return temperature;
        },
        set: function (value) {
            temperature = value;
            archive.push({ val: temperature });
        }
    });

    this.getArchive = function () {
        return archive;
    };
}

var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]

尝试这两种方法来实现setter和getter

var address = {

            street : "No street",
            city : "No city",
            state : "No state",     

            get getAddress()
            {
                return (this.street+","+this.city+","+this.state);
            },

            set setAddress(theAddress)
            {
                var part = theAddress.toString().split(", ");
                this.street = part[0] || "";
                this.city = part[1] || "";
                this.state = part[2] || "";
            }
        };


        address.setAddress = "27 Sus Road, Pune, MH";
        console.log(address.getAddress);


        //Other setter and getter

        function Square(side)
        {
            this._side = side;


        };

        Square.prototype = {

            set setSide(side){ 
                this._side = side;
            },

            get getSide(){ 
                return this._side;
            },

            get getArea(){ 
                return (this._side * this._side);
            }               
        };


        var mySquare = new Square(10);

        mySquare.setSide = 15;

        console.log("Area of square is "+mySquare.getArea+" with side "+mySquare.getSide);
第一种方法

var address = {

            street : "No street",
            city : "No city",
            state : "No state",     

            get getAddress()
            {
                return (this.street+","+this.city+","+this.state);
            },

            set setAddress(theAddress)
            {
                var part = theAddress.toString().split(", ");
                this.street = part[0] || "";
                this.city = part[1] || "";
                this.state = part[2] || "";
            }
        };


        address.setAddress = "27 Sus Road, Pune, MH";
        console.log(address.getAddress);
第二种方法

function Square(side)
        {
            this._side = side;


        };

        Square.prototype = {

            set setSide(side){ 
                this._side = side;
            },

            get getSide(){ 
                return this._side;
            },

            get getArea(){ 
                return (this._side * this._side);
            }               
        };


        var mySquare = new Square(10);

        mySquare.setSide = 15;

        console.log("Area of square is "+mySquare.getArea+" with side "+mySquare.getSide);

他已经知道这一点了,因为这是他不想做的事情的一个例子。@Thor84no:你说的例子实际上不是上面提到的,但我认为你是对的
function Square(side)
        {
            this._side = side;


        };

        Square.prototype = {

            set setSide(side){ 
                this._side = side;
            },

            get getSide(){ 
                return this._side;
            },

            get getArea(){ 
                return (this._side * this._side);
            }               
        };


        var mySquare = new Square(10);

        mySquare.setSide = 15;

        console.log("Area of square is "+mySquare.getArea+" with side "+mySquare.getSide);