闭包如何具体化数据封装

How does closure reify the data encapsulation?

本文关键字:数据封装 具体化 闭包      更新时间:2023-09-26

在传统的面向对象语言中,我们通常使用私有/公共来实现数据封装。

在Javascript中,没有私有或公共;有人告诉我,数据封装可以通过使用闭包来实现
我想知道背后的逻辑是什么?

实际上并没有创建真正的私有成员。

检查以下代码:

function A() {
    var doStuff1 = function() { };
    this.doStuff2 = function() {
        doStuff1();
    };
};
var instance = new A();
instance.doStuff2();

由于doStuff2被声明并添加到this,它是A实例的一部分,而doStuff1被声明为构造函数中的局部变量,因此,它只能使用同一构造函数中的闭包来访问。

顺便说一句,我不喜欢这种模式,因为当你不使用原型继承时,它非常有效。

假设我想使用原型:

function A() {
     var doStuff1 = function() {}; // ??????
};
A.prototype = {
     doStuff2: function() {
        // How do I access a local variable defined 
        // in the constructor function local scope?
     }
};

因此,整个模式适用于不想使用原型继承的简单场景。

此外,这种模式在想要使用Object.create(...)的场景中不起作用,因为根本没有构造函数。。。

// Constructor isn't ever called...
var instance = Object.create(A.prototype);

那么,您将如何在JavaScript中实现这种封装呢?目前还不可能,但许多库和框架已经选择使用命名约定,让开发人员知道库/框架代码消耗了什么,以及在实际的第三方开发中打算使用什么。

例如:

function A() {
};
A.prototype = {
    ___doStuff1___: function() {},
    doStuff2: function() {
         this.___doStuff1___();
    }
};

毕竟,这是一种命名约定,其中由___ sorround的成员被认为是私有的,或者不适合第三方开发人员。

其他库/框架使用$$(例如Angular$$privateMember)。

您可以通过这种方式将数据封装在"类"中(JavaScript6之前没有真正的类)

var yourClass = function() {
   var privateProp = 'sometext'; //private prop
   this.prop = 1; //public

   this.getPrivateProp = function() {
       return privateProp; //access to your private prop with a closure
   }
}
var test = new yourClass();
//when you use 'new', everything in 'this' is returned in your object. 
//'privateProp' is not in 'this' but 'getPrivateProp' is. 
//You got your private data not directly accessible from outside.
test.prop; // 1
test.privateProp;//undefined
test.getPrivateProp();// 'sometext'