猿问

从原型定义函数访问私有成员变量

从原型定义函数访问私有成员变量

是否有任何方法使“私有”变量(那些在构造函数中定义的变量)可用于原型定义的方法?

TestClass = function(){
    var privateField = "hello";
    this.nonProtoHello = function(){alert(privateField)};};TestClass.prototype.prototypeHello = function(){alert(privateField)};

这样做是可行的:

t.nonProtoHello()

但这并不是:

t.prototypeHello()

我习惯于在构造函数中定义我的方法,但出于以下几个原因,我不这么做了。


牛魔王的故事
浏览 435回答 3
3回答

慕盖茨4494581

当我读到这篇文章时,这听起来像是一个艰巨的挑战,所以我决定想出一个办法。我想出的是疯狂但它完全有效。首先,我尝试在直接函数中定义类,这样您就可以访问该函数的一些私有属性。这可以让您获得一些私有数据,但是,如果您试图设置私有数据,您很快就会发现所有对象都将共享相同的值。var SharedPrivateClass = (function() { // use immediate function    // our private data    var private = "Default";    // create the constructor    function SharedPrivateClass() {}    // add to the prototype    SharedPrivateClass.prototype.getPrivate = function() {        // It has access to private vars from the immediate function!        return private;    };    SharedPrivateClass.prototype.setPrivate = function(value) {        private = value;    };    return SharedPrivateClass;})();var a = new SharedPrivateClass();console.log("a:", a.getPrivate()); // "a: Default"var b = new SharedPrivateClass();console.log("b:", b.getPrivate()); // "b: Default"a.setPrivate("foo"); // a Sets private to "foo"console.log("a:", a.getPrivate()); // "a: foo"console.log("b:", b.getPrivate()); // oh no, b.getPrivate() is "foo"!console.log(a.hasOwnProperty("getPrivate")); // false. belongs to the prototypeconsole.log(a.private); // undefined// getPrivate() is only created once and instanceof still worksconsole.log(a.getPrivate === b.getPrivate);console.log(a instanceof SharedPrivateClass);console.log(b instanceof SharedPrivateClass);有很多情况下,这将是足够的,例如,如果您希望有常量的值,如事件名称,并在实例之间共享。但本质上,它们的作用就像私有的静态变量。如果您绝对需要从原型上定义的方法中访问私有命名空间中的变量,则可以尝试此模式。var PrivateNamespaceClass = (function() { // immediate function    var instance = 0, // counts the number of instances        defaultName = "Default Name",          p = []; // an array of private objects    // create the constructor    function PrivateNamespaceClass() {        // Increment the instance count and save it to the instance.         // This will become your key to your private space.        this.i = instance++;                 // Create a new object in the private space.        p[this.i] = {};        // Define properties or methods in the private space.        p[this.i].name = defaultName;                console.log("New instance " + this.i);            }    PrivateNamespaceClass.prototype.getPrivateName = function() {        // It has access to the private space and it's children!        return p[this.i].name;    };    PrivateNamespaceClass.prototype.setPrivateName = function(value) {        // Because you use the instance number assigned to the object (this.i)        // as a key, the values set will not change in other instances.        p[this.i].name = value;        return "Set " + p[this.i].name;    };    return PrivateNamespaceClass;})();var a = new PrivateNamespaceClass();console.log(a.getPrivateName()); // Default Namevar b = new PrivateNamespaceClass();console.log(b.getPrivateName()); // Default Nameconsole.log(a.setPrivateName("A"));console.log(b.setPrivateName("B"));console.log(a.getPrivateName()); // Aconsole.log(b.getPrivateName()); // B// private objects are not accessible outside the PrivateNamespaceClass functionconsole.log(a.p);// the prototype functions are not re-created for each instance// and instanceof still worksconsole.log(a.getPrivateName === b.getPrivateName);console.log(a instanceof PrivateNamespaceClass);console.log(b instanceof PrivateNamespaceClass);我希望任何看到错误的人都能给我一些反馈。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答