Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Duplicates_Encapsulation - Fatal编程技术网

如何在javascript中封装数据而不在每个对象实例中复制函数?

如何在javascript中封装数据而不在每个对象实例中复制函数?,javascript,oop,duplicates,encapsulation,Javascript,Oop,Duplicates,Encapsulation,我用JavaScript创建了一个类,它具有公共和私有属性——数据和对这些数据进行操作的方法。某些数据是私有的,不应通过类实例中的“.”(点)运算符访问。有没有办法避免每个类实例的方法重复 function MyClass() { let privateVar; let publicVar; function publicFun() { // do something } function privateFun(){ //

我用JavaScript创建了一个类,它具有公共和私有属性——数据和对这些数据进行操作的方法。某些数据是私有的,不应通过类实例中的“.”(点)运算符访问。有没有办法避免每个类实例的方法重复

function MyClass() {
    let privateVar;
    let publicVar;
    function publicFun() {
        // do something
    }
    function privateFun(){
        // do something else
    }
    this.v = publicVar;
    this.f = publicFun;
}

let obj1 = new MyClass();
let obj2 = new MyClass();   // publicFun and privateFun methods duplication

ClassName.prototype
方法要求对所有类数据使用完全公开的API。所以这对我不起作用。

你可以尝试使用它是一个支持OOP的javascript库,这样你就可以像在c#或java中那样编写代码,编译器将为你生成真正的javascript。

你可以在
构造函数中创建一个独立的函数。
函数:

var HelloWorld=(函数(){
匿名函数(){
返回“哈哈哈!我的一切!!!”;
}
函数HelloWorld(){
this.helling=“Hello World”;
}
//公开的
HelloWorld.prototype.greet=函数(){
log(“Hello,”+this.greeting+“”+anonymouse());
};
返回地狱世界;
}());
var greeter=new HelloWorld();
问候者;

控制台日志(接线员)如果我理解正确,您可以向类定义中添加一个参数,并基于此参数,选择在返回对象中包含其他属性

样品
函数myClass(选项){
var myFunc1=函数(){}
var myFunc2=函数(){}
var myFunc3=函数(){}
var myFunc4=函数(){}
var myFunc5=函数(){}
var finalProps={
myFunc1:myFunc1,
myFunc2:myFunc2,
}
开关(选件){
案例“全部”:
finalProps[“myFunc5”]=myFunc5;
案例“更多”:
finalProps[“myFunc3”]=myFunc3;
finalProps[“myFunc4”]=myFunc4;
打破
}
返回最终建议;
}
(功能(){
var f1=新的myClass();
var f2=新的myClass(“更多”);
var f3=新的myClass(“全部”);
控制台日志(f1、f2、f3)

})()
如果我正确理解了您,下面是我的示例:

  • 方法在包装器函数中只定义一次(因此它们不会在每个实例上声明)
  • 您可以创建对象的实例,它们都将引用相同的方法,并且可以具有公开的数据
  • 这是一个小提琴的例子:

    function wrapper() {
      //Methods defined only once
      function method() {
        alert("this is method");
      }
    
      function methodWithParams(param, callback) {
        var paramsVar = param;
    
        function realMethodHere() {
          alert("We passed a param: " + paramsVar);
          paramsVar = "Changed"
          callback(paramsVar);
          alert("Now we cahnged the param's value to: " + paramsVar + ", rerun the method to verify");
        }
    
        return realMethodHere;
      }
    
      //Class constructor
      function classConstructor() {
        //Private
        var privateData = "Private"
    
        function privateFunction() {
          alert("this is some private function, inaccesible");
        }
    
        //This callback was addedto allow yo uto change private data.
        function privateDataChangerCallback(param) {
          privateData = param;
        }
    
    
        //Public
        this.publicData = "Public"
        this.callMethod = method;
        this.paramMethod = methodWithParams(privateData, privateDataChangerCallback);
      }
    
    
      return classConstructor;
    }
    
    var classDefinition = wrapper();
    var classInstance = new classDefinition();
    
    classInstance.callMethod(); //method without param
    classInstance.paramMethod(); //method with exposed Private data
    //rerunning the method to see what the value is:
    classInstance.paramMethod(); //method with exposed Private data
    

    所以,如果我理解正确的话,您希望对同一函数的不同实例中的可用函数使用条件方法。我说得对吗?我已经涉猎这些东西很长一段时间了,我已经设法使它完全适合OOP模型(虽然没有使用ES6,但它完全重写了我们将如何编写它),但我不明白你的问题/问题是什么?你能举一个你的类的例子吗?并显示要隐藏的内容。函数相同。就像在C++类中一样。当我们创建类实例时,会有额外的内存分配给函数,只分配给数据。这里我们为类中描述的每个方法创建单独的实例。所以我只想关心内存使用情况。我仍然不能正确理解您的问题,但是如果您希望删除重复的函数,使用
    prototype
    就可以了。对吗?如果我正确理解了这个示例,那么这里我们有相同的问题:您在
    wrapper
    中声明的每个方法对于每个
    new(wrapper())()都是重复的呼叫。是吗?你是对的,我的错误,更新了示例和代码以反映它不会发生。像这样应该行得通。这样包装器只被调用一次,类定义被调用多次,所以每个实例都被再次创建,而方法只被创建一次。。。但是,如果传递给
    methodWithParams
    privateData
    变量不是对象类型(数字、字符串、布尔),我们会看到什么呢
    methodWithParams
    将收到一份
    privateData
    的副本,但不是一份参考。我不确定您的目标是什么。在构造方法时,方法
    methodWithParams
    正在运行,您定义的参数正在传递给它,只有在调用构造方法后才会运行该方法。该方法的结果是一个由
    realMethodHere
    定义的函数调用,它保留在对象初始化时传递给
    methodWithParams
    的任何参数。如果您传递一个引用,例如一个对象或数组,
    realMethodHere
    有一个引用,如果您传递一个值,例如一个数字、布尔或字符串,
    realMethodHere
    将获得该值。当然,但是如果我们试图更改传递给
    methodWithParams
    的非对象类型变量,它将只更改本地副本(在
    methodWithParams
    函数范围内)但不是类对象的变量。因此,当调用
    methodWithParams()
    复制的变量时,它不再引用类实例的变量。它们只是独立的!对我来说,这是非常复杂的代码!很难维护!