Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Javascript原型中,有没有任何方法可以在不浪费内存的情况下利用信息隐藏?_Javascript_Oop_Private Members_Privileged Functions - Fatal编程技术网

在Javascript原型中,有没有任何方法可以在不浪费内存的情况下利用信息隐藏?

在Javascript原型中,有没有任何方法可以在不浪费内存的情况下利用信息隐藏?,javascript,oop,private-members,privileged-functions,Javascript,Oop,Private Members,Privileged Functions,我跟在后面,我在挣扎。我正在尝试优化这段代码 function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secre

我跟在后面,我在挣扎。我正在尝试优化这段代码

function Container(param) {

    function dec() {
        if (secret > 0) {
            secret -= 1;
            return true;
        } else {
            return false;
        }
    }

    this.member = param;
    var secret = 3;
    var that = this;

    this.service = function () {
        return dec() ? that.member : null;
    };
}
通过在构造函数之外定义函数,这样就不会在每次创建新实例时创建新的函数对象

我仍然不知道如何为那些他称之为私人方法的人做到这一点(非常感谢任何帮助)。对于那些他称之为特权方法的人,我正试图这样做:

function Container(param) {

    function dec() {
        if (secret > 0) {
            secret -= 1;
            return true;
        } else {
            return false;
        }
    }

    this.member = param;
    var secret = 3;
    var that = this;
}
Container.prototype.service = function() {
    return dec() ? that.member : null; 
};
但如果我像这样测试它

d1 = new Container("content");
d1.service();
我得到这个错误:

ReferenceError: dec is not defined

这是否意味着不能利用Crockford使用的私有/特权方法的优势,并通过将类的所有实例链接到同一个函数对象来优化内存使用?我希望你能证明我错了

如果您不想在每次调用
Container
时创建一个新的
dec
,您可以在定义
Container
时将
Container
放入一个iLife中定义
dec
,然后从iLife返回实际的
Container
构造函数,因此,
dec
只能从
容器内部引用。要封装
秘密
,请使用实例索引的
映射
,而不是在构造函数中使用普通的
var秘密
,以便(共享的)
dec
服务
函数可以查看和使用映射

实际上,正如注释所指出的,最好使用WeakMap,以便在对实例进行GC处理后,可以对实例的关联机密进行垃圾收集:

const容器=(()=>{
const secretsByInstance=new WeakMap();
函数dec(实例){
const secret=secretsByInstance.get(实例);
如果(机密>0){
secretsByInstance.set(实例,secret-1);
返回true;
}否则{
返回false;
}
}
函数容器(param){
secretsByInstance.set(这个,3);
this.member=param;
}
Container.prototype.service=函数(){
return dec(this)?this.member:空;
};
返回容器;
})();
d1=新容器(“内容物”);
console.log(d1.service());
console.log(d1.service());
console.log(d1.service());

console.log(d1.service())你不能这样做,想法是在构造函数的作用域中隐藏值。“没有办法使用私有/特权方法”——没有“私有”/“特权方法”“在JS中,编造术语弊大于利。重点不是真正使用编造术语,而是信息隐藏概念提供的设计优势。如果你停止使用这些术语,那么你将能够自己回答问题。这里的“隐藏”功能只能通过闭包来实现。如果你没有访问闭包/函数的权限,你就不能调用它。那么,如果没有内存浪费,真的没有办法使用类似私有方法的东西吗?
WeakMap
可能是一个更好的选择。这看起来真的很聪明!只有一个疑问:
secretsByInstance
为什么由实例定义,如果它的声明方式与
dec
基本相同?@mememe在构造函数中,我们将WeakMap的当前实例的值设置为3。WeakMap可以包含任意数量的键值对,例如,对于
d1=新容器(“content1”)中的
d1
d2
;d2=新容器(“内容物2”)。因此,我们需要预先定义数据结构,所有函数都可以看到它,然后我们需要将实例的
secret
放入数据结构中,当实例created@memememe是的,看看如何使用IIFE定义
容器
——这意味着
secretsByInstance
dec
,而
容器
构造函数和
服务
方法都只定义了一次,而不是重复定义。然后,当使用
新容器创建实例并使用时,这些不同的函数/数据结构会被使用(但不会重新创建)@mememe是的,这就是