Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/422.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_Performance_Memory_Prototype_Factory - Fatal编程技术网

提高JavaScript中工厂模式的存储效率

提高JavaScript中工厂模式的存储效率,javascript,performance,memory,prototype,factory,Javascript,Performance,Memory,Prototype,Factory,JavaScript“对象”(实际上是一个映射)概念的简单性和灵活性一直吸引着我。因此,我宁愿完全避免“对象原型”(以及“类”,它们只是对象原型的语法糖)的概念,而选择工厂模式 我偶然看到这篇文章,指出与工厂模式相比,对象原型可以节省内存: “所有方法将在prototype对象中仅创建一次,并由所有实例共享” 假设我有一个网页,它多次调用以下函数来“实例化”许多AnglePointer对象: var AnglePointer = function() { var privateMembe

JavaScript“对象”(实际上是一个映射)概念的简单性和灵活性一直吸引着我。因此,我宁愿完全避免“对象原型”(以及“类”,它们只是对象原型的语法糖)的概念,而选择工厂模式

我偶然看到这篇文章,指出与工厂模式相比,对象原型可以节省内存:

“所有方法将在prototype对象中仅创建一次,并由所有实例共享”

假设我有一个网页,它多次调用以下函数来“实例化”许多AnglePointer对象:

var AnglePointer = function() {
    var privateMembers = {};
    privateMembers.angle = 0;

    var self = {};

    self.turn = function(degrees) {
        privateMembers.angle += degrees;
        while (privateMembers.angle > 359) {
            privateMembers.angle -= 360;
        }
        while (privateMembers.angle < 0) {
            privateMembers.angle += 360;
        }
    };

    return self;
};
var AnglePointer=function(){
var privateMembers={};
privateMembers.angle=0;
var self={};
自转=功能(度){
privateMembers.angle+=度;
while(privatembers.angle>359){
privateMembers.angle-=360;
}
while(privatembers.angle<0){
privateMembers.angle+=360;
}
};
回归自我;
};
我是否可以通过引入如下“共享”对象来提高内存效率

var AnglePointer = (function() {
    var sharedMembers = {};

    sharedMembers.turn = function(self, privateMembers, degrees) {
        privateMembers.angle += degrees;
        while (privateMembers.angle > 359) {
            privateMembers.angle -= 360;
        }
        while (privateMembers.angle < 0) {
            privateMembers.angle += 360;
        }
    };

    return function() {
        var privateMembers = {};
        privateMembers.angle = 0;

        var self = {};

        self.turn = function(degrees) {
            shared.turn(self, privateMembers, degrees);
        };

        return self;
    };
})();
var AnglePointer=(函数(){
var sharedMembers={};
sharedMembers.turn=函数(自身、私有成员、度){
privateMembers.angle+=度;
while(privatembers.angle>359){
privateMembers.angle-=360;
}
while(privatembers.angle<0){
privateMembers.angle+=360;
}
};
返回函数(){
var privateMembers={};
privateMembers.angle=0;
var self={};
自转=功能(度){
共享。旋转(自身、私人成员、学位);
};
回归自我;
};
})();
在第二个版本中,
turn
函数的实现在
sharedMembers
对象中,AnglePointer的每个“实例”只剩下一个调用共享函数的小单行函数。这将实现类似于对象原型的内存效率吗?或者每个实例的
turn
函数是否会像以前一样占用大量内存(尽管是单行函数)?如果是后者,对象原型如何避免这个问题

只有一个小的单行函数调用共享函数

这是基于一种错误的信念,即将为每个对象创建一个新函数。这是错误的。代码中的所有函数只解析一次,并且只存在一次。每次创建时都会创建一个新的闭包(规范称之为EnvironmentRecord)。如果函数不访问任何外部变量,则可以优化此闭包,使其内存效率更高(可能更快)

因此,你的“新模式”实际上让事情变得更糟(但只是一点点)。主要问题在于:

self.turn = function(degrees) {
   shared.turn(self, privateMembers, degrees);
};
这是无法优化的,因为函数使用来自其父范围的变量,因此必须创建一个闭包。因此,每个
turn
方法都必须有一个闭包,每个对象都必须保留一个对自己的closured
turn
的引用

私有成员可以通过符号非常准确地实现:

const angle = Symbol.for("angle");

function AnglePointer() {
  return {
   [angle]: 0,
   turn(degrees) {
     this[angle] = (this[angle] + degrees) % 360;
   },
  };
}

这里的
turn
可以共享,因为它不访问任何外部变量。

您对如何在对象原型中避免这个问题有什么见解吗?给定一个对象原型的实例,该实例如何调用共享函数并传递其自身的内部状态,而不将其包装到另一个函数中?@circuitsolar使用原型时,只有一个闭包(或者根本没有闭包)。把
this
想象成一个隐式参数,你可以只做
function-turn(this,degrees){/*…*/}
并把它称为
turn(someInstance,90)
这很有趣,人们经常会问这个新关键字在JavaScript中到底做了什么,我从未见过这样的例子——将其作为隐式参数传递给对象中定义的任何函数。所以有趣的是,解决这个问题的一个(乏味的)方法是将这个责任明确地写进代码中。AnglePointer可以将其turn函数定义为
turn(anglePointerInstance,degrees)
,任何时候外部代码实例化AnglePointer并需要转动它时,它都类似于
myInstance=AnglePointer();myInstance.turn(myInstance,45)