javascript - 为什么 JavaScript 中这些基于闭包的私有(private)变量不起作用

标签 javascript oop closures

我正在尝试在 JS 中模仿类似 OOP 的行为。我试图在函数 Person 中拥有(私有(private))变量:idname。我向此函数传递用于初始化(私有(private))变量的参数。然后,我返回具有 name 的 getter 和 setter 的对象,并且仅具有 id 的 getter,从而有效地使 id 只读。

因此 id 只能通过构造函数设置,而 name 可以随时设置和获取。

这是代码:

     var Person = function (_id,_nm) {
        var id, name;    
                  
        this.id = _id;
        this.name = _nm;

        return {               
            setName: function (nm) {
                name = nm;
            },
            getName: function () {
                return name;
            },
            getId: function () {
                return id;
            },
            print: function () {
                document.writeln("Id: "+id+"<br />Name: "+name);
            }
        }
    }

    var person = new Person(123, "Mahesh");
    person.print();

但是,当 new Person(123,"Mahesh") 执行时,我不明白它实际上是否设置了 idname ,因为在调试时我可以看到将鼠标悬停在它们上方时适当设置的值,但“本地”面板没有显示它们已初始化:

Debugging

或者在 print() 中未引用所需的 id 和 name 变量:

Debugging

这里出了什么问题?

最佳答案

<强> Working fiddle

原因是因为您正在为 Person.prototype 使用 public 成员。您不需要添加对这两个的 this 引用。所以删除:

this.id = _id;
this.name = _nm;

并简单地使用:

 var id = _id,
     name = _nm;  

现在一切都会正常进行。整个想法是使用 var,而不是 this,否则不会创建闭包。现在您将无法直接访问 nameid,而是必须使用 setName()、getName()、setId()、getId( ) 等等

两个成员,idname,现在将按照您希望的方式成为闭包。

更新

如果您使用 this.id,那么它就不会是 private,您只需执行 var p = new Person(1, "Mahesha "); 并直接访问 p.namep.id。它们应该是私有(private),所以这不是您想要的。

使用闭包模式,p.name 和 p.id 未定义,只能通过 p.getName();p.getId(); 访问。了解闭包的工作原理。这个想法是,因为您正在使用该 var name,所以将创建一个闭包来记住它的值。

您的getNamesetName正在使用该闭包来访问name属性。没有 this.name,有一个通过高阶闭包记住的值。

关于javascript - 为什么 JavaScript 中这些基于闭包的私有(private)变量不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16506829/

相关文章:

python - Python 中的仿函数与函数闭包

javascript - HtmlDivElement 没有方法 'indexOf'

javascript - 将原始字符串源转换为 html 以使用 jquery 选择器

javascript - 如何在表格行上启用 anchor 标记?

C++使用迭代器将函数映射到可迭代对象上

javascript - 如何在 Javascript 中访问闭包内的变量

javascript - HTML 5 Canvas 元素无法在 .setInterval 方法中正确设置动画

.net - 为什么我们使用 .NET 属性而不是普通的旧 get/set 函数?

php - 什么时候在 PHP 中使用 Final?

java - 异步任务 ArrayList 对象未从 doInBackground 传递到 onPostExecute