6

我正在开发一个在 javascript 中创建类的实用程序。它有效,问题是如何定义私有属性。

这是代码

var OO = {

    Class:function(){

        var len = arguments.length;
        var data = arguments[len-1];



        var Klass;
        if (data.constructor === Object){
            Klass = function (){};

        } else {
            Klass = data.constructor;
            delete data.constructor;                
        }



        OO.extend(Klass.prototype,data); //Classic Extend Method


        return Klass;


    },
//Simple extend method, just what I need in this case
    extend: function(target, source){
            var prop;
            for (prop in source)
                target[prop] = source [prop];

    }
}

这就是它的工作原理

// first create a class
var person = OO.Class ({
constructor: function (name, age) {
this.name = name;
this.age = age;
},

name:'',
age:'',

getName: function () {
return this.name;
},

getAge: function () {
return this.age;
}

});

这是实例

var one = new Person ('josh', 22);

问题是:

one.age / / returns 22
one.name / / returns josh

我需要的是这些属性只能通过getName()和getAge()等方法访问

EDIT1:添加了扩展功能

4

4 回答 4

1

闭包是由构造函数参数创建的,所以这就是您需要做的所有事情(编辑 AlienWebguy 的代码):

var Person = function(name, age){

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

    this.getAge = function() {
        return age;
    };

};

var john = new Person('johnathan', 33);

document.writeln(john.name);        // undefined
document.writeln(john.age);         // undefined
document.writeln(john.getName());   // johnathan
document.writeln(john.getAge());    // 33
于 2012-09-07T04:27:38.897 回答
0

更新1:

这是工作原型。它的工作原理除了

1.) 将构造值传递给私有成员。

 Dummy values do work however.

测试小提琴:

http://jsfiddle.net/UWRHP/11/

于 2012-09-06T22:52:38.563 回答
-1

作为对象接口一部分的任何变量(即this.xthis.y)都将是公共的。您将无法强制通过 getter 访问这些变量的外部访问。

所以,只要你有这样的代码:

getAge: function () {
    return this.age;
}

...你不能阻止这一点:

var one = new Person ('josh', 22);
console.log(one.age);

查看 Douglas Crockford 的文章Private Members in JavaScript

于 2012-09-06T22:48:17.560 回答
-1

如果您不想像@AlienWebguy 建议的那样使事情变得过于复杂(并完全放弃到目前为止所做的事情),那么您甚至不需要该.io成员-最终与.nameand.age属性一样暴露:

john.io.set('name', 'Johnny'); // still exposed!

归根结底,对象和and属性.io一样暴露,所以这是一个复杂的解决方案,在封装和信息隐藏方面没有任何进展。(对不起,@AlienWebguy,这就是我的感觉).name.age

如果您尝试使用经典的继承范例并完全放弃传统的 JavaScript OOP,那么请放弃传统的函数作为构造函数范例并忘记this在构造函数中使用引用:

// first create a constructor
var Person = function(arg0, arg1) {

    var that = {};

    // private variables

    var age = arg0;
    var name = arg1;

    // public methods

    that.getName = function() {
        return name;
    };

    that.getAge = function() {
        return age;
    };

    that.setAge = function(a) {
        age = a;
    };

    return that;

};

var john = new Person('johnathan', 33);

console.log(john.name);        // undefined
console.log(john.getName());   // 'johnathan'
console.log(john.age);        // undefined
console.log(john.getAge());   // 33
john.setAge(28);
console.log(john.getAge());   // 28
john.setName("Richard");      // Error - setName is not a function

这是道格拉斯·克罗克福德的寄生继承的一个例子……但没有“继承”部分。关键是,实例变量agename是私有的,但由于 JavaScript 的函数变量作用域而保留在范围内,因此对象的方法仍然可以操作它们。

您还会注意到该name变量没有设置器,因此这种技术合法地允许您控制对name变量的访问 - 没有隐藏this.namethis.io不允许操纵变量;它完全是私人的。

于 2012-09-07T00:22:56.137 回答