• 有意思的一道题


      今天有同学问了这么一道题,倒是有点意思,如下:

        function Person(name) {
          this.getName = function () {
            return name;
          }
          this.setName = function (name) {
            name = name;
          }
        }
        var person1 = new Person("wayne");
        console.log(person1.getName()); // wayne
        var person2 = new Person("hedy");
        console.log(person2.getName()); // hedy 
        console.log(person1.getName()); // wayne

        很简单,就是为什么最后的结果是这样的。 最后一个结果为什么不是hedy。

      

      于是,我给他举了下面这样的一个例子:

       function Person(obj) {
          this.getName = function () {
            return obj.name;
          }
          this.setName = function (obj) {
            name = obj.name;
          }
        }
        var obj = {
          name: "wayne"
        };
        var person1 = new Person(obj);
        console.log(person1.getName()); // wayne
        obj.name = "hedy";
        var person2 = new Person(obj);
        console.log(person2.getName()); // hedy 
        console.log(person1.getName()); // hedy

      到这里,他还是不太明白,所以,我可以给他解释一下了。

      在new的过程中,实际上也是在调用函数,且调用函数时就会创建一个新的函数作用域,对于第一个程序,实际上涉及到了闭包的概念,因为构造函数内部的name还在引用这个构造函数,所以形成了闭包,即使在new之后,这个构造函数中的name依然会保存,而在getName()的过程中,就去寻找这个name; 而再new另外一个Person的时候,实际上又进入了一个新的函数作用域,这个函数作用域同样又保存了新的name,所以第一个程序也就不难理解了。

      而第二个程序,因为我创建了一个对象,在对象传入函数的过程中,实际上是传递的引用,即这个对象始终都在堆中的同一个内存里,所以说修改了对象之后,getName()得到的值就始终一样了 。

      接着,他又问我,第一个程序中在person1.getName()之后,这里已经将getName()调用了,那么构造函数中的name不是应该释放了吗?为什么最后调用还是可以找到呢? 我又写了下面的这个函数:

        function Person(name) {
          this.getName = function () {
            return name;
          }
          this.setName = function (name) {
            name = name;
          }
        }
        var person1 = new Person("wayne");
        alert(person1.getName()); // wayne
        var person2 = new Person("hedy");
        alert(person2.getName()); // hedy 
        person1.getName = null;

      这样,getName函数就不会对Person构造函数进行引用了,这时,实际上Person中的name就会被释放了。  

           看似简单的一道题,实际上涉及到了构造函数的本质、基本数据类型和引用类型在传参的区别、作用域、闭包等等概念,还是非常不错的。

  • 相关阅读:
    Centos6.4 cobbler安装要点
    zabbix oracle监控插件orabbix部署安装
    CPP
    基于curl 的zabbix API调用
    oracle 存储过程
    sqlplus乱码
    Intent之对象传递(Parcelable传递对象和对象集合)
    IOS压缩解压缩
    深入浅出java静态代理和动态代理
    c语言用rand() 函数,实现random(int m)
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/8969927.html
Copyright © 2020-2023  润新知