如何向这个Javascript对象字面量片段添加私有变量?

15

在 MDC 上找到这个,但如果我想要添加一个私有变量到

var dataset = {
    tables:{
        customers:{
            cols:[ /*here*/ ],
            rows:[ /*here*/ ]
        },
        orders:{
            cols:[ /*here*/ ],
            rows:[ /*here*/ ]
        }
    },
    relations:{
        0:{
            parent:'customers', 
            child:'orders', 
            keyparent:'custid', 
            keychild:'orderid',
            onetomany:true
        }
    }
}
我对JavaScript中的面向对象编程理解是,如果存在这样的项目,我可以访问dataset.tables.customers.cols[0]。
但是,如果我想把一个私有变量放到customers里面,那该怎么做呢?
添加 var index = 0; 将导致运行时错误。
3个回答

26

没有函数参与,你无法拥有“私有”变量。在JavaScript中,函数是引入新作用域的唯一方式。

但不要担心,您可以在正确的位置添加函数来获得对象的这种功能。

var dataset = {
  tables: {
    customers:(function(){
      var privateVar = 'foo';
      return { 
        cols:[ /*here*/ ],
        rows:[ /*here*/ ]
      }
    }()),
    orders:{
      cols:[ /*here*/ ],
      rows:[ /*here*/ ]
    }
  },
  relations: [{
    parent:'customers', 
    child:'orders', 
    keyparent:'custid', 
    keychild:'orderid',
    onetomany:true
  }]
};

但这并没有太多的用处。这依然只是一堆字面上的对象。这些类型的“私有”变量没有任何意义,因为没有方法-没有任何真正读取或在我们通过添加函数(闭包)创建的范围内使用变量的东西。

但如果我们有一个方法,那么它可能会开始变得有用。

var dataset = {
  tables: {
    customers:(function(){
      var privateVar = 'foo';
      return { 
        cols:[ /*here*/ ],
        rows:[ /*here*/ ],
        getPrivateVar: function()
        {
          return privateVar;
        }
      };
    }()),
    orders:{
      cols:[ /*here*/ ],
      rows:[ /*here*/ ]
    }
  },
  relations: [{
    parent:'customers', 
    child:'orders', 
    keyparent:'custid', 
    keychild:'orderid',
    onetomany:true
  }]
};

alert( dataset.tables.customers.getPrivateVar() );

10

JavaScript没有像更严格的语言那样的访问控制。你可以使用闭包模拟对象数据的私有访问,但是你的示例是一个对象字面量 - 一个简单的数据结构,而不是一个构造对象。

这要取决于您想要对该对象做什么 - “私有”成员的常规技术意味着它们只能通过成员函数访问,并需要使用构造函数创建对象。字面量语法用于具有公共数据和函数的数据结构或轻量级对象。

使用私有闭包模式的问题在于字面量内的字段处于公共范围,但闭包提供的隐私是因为变量在函数中定义,因此具有本地作用域。你可以创建一个克隆字面量并添加私有字段的函数,或者添加一个具有私有数据的公共字段。您还可以将闭包作为成员添加到对象中,因此创建方法私有的私有字段,而不是对象私有字段。

dataset = {
    secretCounter: ( 
      function () {
      var c = 0;
      return function () { return ++c; }
    })(),      
   ...

所以dataset.secretCounter()有一个仅限于该函数的私有变量c


哦!我觉得你让我回到了正轨。数据结构不能持有私有成员,因为它们只声明数据(一切都是公开的!),但如果我将其重写为静态类/单例(var obj = function(){}();),我就能够这样做。这正确吗?谢谢 :) - Adam Asham

4

Javascript中的私有变量是通过在闭包内使用var关键字来实现的。只有特权方法和属性才能访问它。以下是实现方式:

function dataset()
{
var private_stuff = 10; // private
this.foo = new function() { alert(private_stuff); } // priviliged
return {
    tables:{
        customers:{
                cols:[  ],
                rows:[  ]
        },
        orders:{
                cols:[  ],
                rows:[  ]
        }
    },
    relations:{
        0:{
                parent:'customers', 
                child:'orders', 
                keyparent:'custid', 
                keychild:'orderid',
                onetomany:true
        }
    }
}; // public
}

var d = new dataset;
alert(d.foo());

2
var d = new dataset(); 或者是 var d = dataset(); - pkario

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