在javascript对象中调用私有方法

时间:2011-08-10 19:52:59

标签: javascript closures javascript-objects

这是我的javascript:

function namespace(nameSpaceString){
    var parts = nameSpaceString.split(".");
    var parent = window;
    var currentParent = '';

    for(var i=0, len=parts.length; i<len;i++){
        currentParent = parts[i];
        parent[currentParent] = parent[currentParent] || {};
        parent = parent[currentParent];
    }

    return parent;
}
abc = namespace('ns.abc');

abc.common = function(){
    var arr = [];

    setArr = function(v){
        if(v){
            arr.push(v);
        }
    }
    getArr = function(){
        return arr;
    }

    registerArr = function(ns){
        if(ns){
            for(var obj in ns){
                if(obj.hasOwnProperty(getName)){
                    setArr(obj.getName());
                }
            }
        }
    }
    return{
      setArr : setArr,
      getArr : getArr,
      registerArr : registerArr
   }
}

abc.form = function() {
var salutation = "Hi";
var name = '';

getSalutation = function(){
    return salutation;
}
getName = function(){
    return name;
}
setSalutation = function(s){
    salutation = s;
}
setName = function(n){
    name = n;
}

return{
    getSalutation:getSalutation,
    setSalutation:setSalutation,
    getName : getName,
    setName : setName
    }
}

persons = namespace('ns.abc.persons');
persons.Dave = new abc.form();

persons.Dave.setName("Dave");

persons.Mitchell = new abc.form();

persons.Mitchell.setName('Mitchell');
persons.Mitchell.setSalutation('Howdy');

alert(persons.Mitchell.getSalutation()+":"+persons.Mitchell.getName());
commonObj = new abc.common();

commonObj.registerArr(persons);
alert("Registration:"+commonObj.getArr())

commonObj.setArr(persons.Dave.getName());
commonObj.setArr(persons.Mitchell.getName());
alert("Setter Methods:"+commonObj.getArr());

这里通过setter方法设置的Arr in Common工作正常。但是当我尝试通过调用setter方法来实现相同的另一个成员函数 - 同一个对象的“registerArr”时,它什么都不返回。

如何在其他成员函数中使用setter方法?

2 个答案:

答案 0 :(得分:2)

您需要使用var声明包含函数的变量。

由于你没有声明它们,变量变成了全局变量。

因此,registerArr将始终使用最后创建的实例中的函数,因为这是全局变量中的内容。

此外,您还在滥用for ... in循环 obj遍历对象中每个属性的 要迭代数组,请使用普通的for循环。

答案 1 :(得分:0)

for..in循环有两个问题:

  1. obj指的是而不是值。使用ns[obj]
  2. 获取价值
  3. .hasOwnProperty()的参数需要是一个字符串。添加引号。
  4. 以下是更正后的循环:

    for (var obj in ns) {
        if (ns[obj].hasOwnProperty("getName")) {
            setArr(ns[obj].getName());
        }
    }
    

    这是一个有效的jsFiddle:http://jsfiddle.net/UdyYv/10/

    除此之外,你的jsFiddle还有一些其他问题导致它失败,在运行时抛出错误。您需要声明namespace.abcnamespace.abc.person

    原来是红鲱鱼。 因为您使用abc.common关键字实例化new的实例,abc.common需要指定方法,而不是返回对象。删除return语句并替换为:

    this.setArr = setArr;
    this.getArr = getArr;
    this.registerArr = registerArr;
    

    如果您不想使用此方法,则不应使用new关键字对其进行实例化。而只是称之为:

    commonObj = abc.common();
    

    <击>