JavaScript中闭包模仿对象私有属性的问题?

看高程书,里面有一个章节是关于JavaScript模拟OOP中的对象私有属性。请看这段代码

<script>    
        function Person(name)
        {
            this.getName = function(){
                return name;
            }
            this.setName = function(newName){
                name = newName;
            }
        }

        var lily = new Person("Lily");
        var lucy = new Person("Lucy");

        lily.setName("I am Lily");
        lucy.setName("I am Lucy");  
        println(lily.getName());    // I am Lily
        println(lucy.getName());    // I am Lucy

        function println(obj)
        {
            console.log(obj + "\n");
        }
</script>

我对闭包的理解是,闭包函数的[[Scope]]持有了一个外部函数的活动对象引用。所以闭包能访问外部函数的局部变量。而且访问的值是外部函数局部变量最后一次更改的值。
那在我这个例子中,外部函数的name变量最后一次更改是这个语句
lucy.setName("I am Lucy");
为什么两个lily、lucy两个对象依然可以打印各自不同的值。而不是最后一次更改的值。
虽然这lucy和lily的闭包不是同一个闭包,可是这两个闭包持有的外部函数活动对象不都是Person函数的活动对象吗。
println(lily.getName()); // I am Lily
println(lucy.getName()); // I am Lucy

阅读 4.4k
6 个回答

你想的应该是只实例化一个对象。

function Person(name){
   this.getName = function(){
       return name;
   }
   this.setName = function(newName){
       name = newName;
   }
}

var temp = new Person()
var lily = temp.setName('Lily')
var lucy = temp.setName('Lucy')

println(temp.getName())

function println(obj){
    console.log(obj + "\n");
}

两个语句分别创建了两个 Person 的实例,所以最后的结果是不同的。

你的构造函数代码相当于

function Person(name) {
    var name = name;
    this.getName = function () {
        return name;
    };
    this.setName = function (newName) {
        name = newName;
    };
}

每次 setName 修改的都是对应构造器里面的 name 变量。唯一的区别是修改的不同实例的罢了。

new Person(name)这已经是实例化,实例化后的对象已经是不一样了,完全分离的,只能说实例化的原型是同一个

setName里的,name定义是全局变量

new创建两个Person的实例

答案我知道了,其实是我对活动对象的理解没到位。活动对象并不是和函数相关的,活动对象只和执行环境相关。同一个函数被执行多次,每次执行都会创建不同的活动对象。而这个函数内部的闭包也会持有不同的活动对象引用。
在这个例子中,Person被调用了两次,闭包set和get函数持有的Person活动对象各自不同。
JavaScript的作用域链和闭包真是难理解啊。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题