为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

牛魔王的故事 2019-07-11 15:44:08
从原型定义函数访问私有成员变量是否有任何方法使“私有”变量(那些在构造函数中定义的变量)可用于原型定义的方法?TestClass = function(){     var privateField = "hello";     this.nonProtoHello = function(){alert(privateField)};};TestClass.prototype.prototypeHello = function(){alert(privateField)};这样做是可行的:t.nonProtoHello()但这并不是:t.prototypeHello()我习惯于在构造函数中定义我的方法,但出于以下几个原因,我不这么做了。
查看完整描述

3 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

当我读到这篇文章时,这听起来像是一个艰巨的挑战,所以我决定想出一个办法。我想出的是疯狂但它完全有效。


首先,我尝试在直接函数中定义类,这样您就可以访问该函数的一些私有属性。这可以让您获得一些私有数据,但是,如果您试图设置私有数据,您很快就会发现所有对象都将共享相同的值。


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 prototype

console.log(a.private); // undefined


// getPrivate() is only created once and instanceof still works

console.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 Name


var b = new PrivateNamespaceClass();

console.log(b.getPrivateName()); // Default Name


console.log(a.setPrivateName("A"));

console.log(b.setPrivateName("B"));

console.log(a.getPrivateName()); // A

console.log(b.getPrivateName()); // B


// private objects are not accessible outside the PrivateNamespaceClass function

console.log(a.p);


// the prototype functions are not re-created for each instance

// and instanceof still works

console.log(a.getPrivateName === b.getPrivateName);

console.log(a instanceof PrivateNamespaceClass);

console.log(b instanceof PrivateNamespaceClass);

我希望任何看到错误的人都能给我一些反馈。


查看完整回答
反对 回复 2019-07-11
  • 3 回答
  • 0 关注
  • 434 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信