zoukankan      html  css  js  c++  java
  • 有意思的一道题

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

        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就会被释放了。  

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

  • 相关阅读:
    《命运赋》
    CSS3中的 transform (变形)+Transition(转换) = animation(动画)
    c#进阶之泛型
    正则表达式运用
    查询某时间段的统计数据
    很好用的request转换为实体方法还有判断实体所有参数不能为空的方法
    http 协议集合,超级简单
    今天无意发现jquery的一个以前的误导
    IFRAM随内部长宽高变化
    就最近学习MVC4.0的页面用法学到的东西
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/8969927.html
Copyright © 2011-2022 走看看