如何在每个对象实例中没有函数重复的情况下将数据封装在javascript中?

时间:2016-07-07 10:51:51

标签: javascript oop duplicates encapsulation

我在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。所以这对我不起作用。

4 个答案:

答案 0 :(得分:2)

如果我理解正确的话,这是我的例子:

  1. 方法只在包装函数中定义一次(因此它们不在每个实例上声明)
  2. 您可以创建对象实例,它们都将引用相同的方法,并且可以显示公开数据。
  3. Here是一个小提琴的例子:

    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
    

答案 1 :(得分:1)

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

答案 2 :(得分:0)

您可以在constructor功能中创建独立功能:



var HelloWorld = (function () {
	function anonymouse() {
		return "MUHAHAHA! ALL MINE!!!";
	}
    function HelloWorld() {
        this.greeting = "Hello World";
    }
    //public
    HelloWorld.prototype.greet = function () {
        console.log("Hello, " + this.greeting + " " + anonymouse());
    };
    return HelloWorld;
}());
var greeter = new HelloWorld();
greeter.greet();

console.log(greeter);




但这会产生副作用,即在您班级的所有实例上复制所述功能。

或者,可以创建一个名称空间来隐藏它,并从那里引用你的函数。这将消除重复的功能问题:



var MySecretClasses;
(function (MySecretClasses) {
    function anonymouse() {
        return "MUHAHAHA! ALL MINE!!!";
    }
    var HelloWorld = (function () {
        function HelloWorld() {
            this.greeting = "Hello World";
        }
        //public
        HelloWorld.prototype.greet = function () {
            console.log("Hello, " + this.greeting + " " + anonymouse());
        };
        return HelloWorld;
    }());
    MySecretClasses.HelloWorld = HelloWorld;
})(MySecretClasses || (MySecretClasses = {}));
var greeter = new MySecretClasses.HelloWorld();
greeter.greet();
console.log(MySecretClasses);
console.log(greeter);




<强>打字稿

正如Shlomi Haver指出的那样,您可以使用TypeScript

module MySecretClasses {

    function anonymouse() {
            return "MUHAHAHA! ALL MINE!!!";
    } 
    export class HelloWorld {
        greeting: string = "Hello World";
        constructor() {

        }
        //public
        public greet() {
            console.log("Hello, " + this.greeting + anonymouse());
        }
    }
}
var  greeter = new MySecretClasses.HelloWorld();
greeter.greet();
console.log(greeter);

答案 3 :(得分:0)

如果我理解正确,您可以在类定义中添加一个参数,并根据此参数,您可以选择在返回对象中包含其他属性。

示例

function myClass(option) {
  var myFunc1 = function() {}
  var myFunc2 = function() {}
  var myFunc3 = function() {}
  var myFunc4 = function() {}
  var myFunc5 = function() {}

  var finalProps = {
    myFunc1: myFunc1,
    myFunc2: myFunc2,
  }

  switch (option) {
    case "all":
      finalProps["myFunc5"] = myFunc5;
    case "more":
      finalProps["myFunc3"] = myFunc3;
      finalProps["myFunc4"] = myFunc4;
      break;
  }
  return finalProps;
}

(function() {
  var f1 = new myClass();
  var f2 = new myClass("more");
  var f3 = new myClass("all");

  console.log(f1, f2, f3)
})()