Javascript引用指针

系统 1717 0

Quiz

请尝试完成下列完形填空:

      
        /*
      
      
         创建一个队列,头为head0,尾为tail0 
      
      
        */
      
      
        function
      
      
         IntList(head0, tail0){
    
      
      
        this
      
      .head = head0 || 0
      
        ;
    
      
      
        this
      
      .tail = tail0 || 
      
        null
      
      
        ;
}

      
      
        /*
      
      
         返回一个IntList包含数组中的所有数 
      
      
        */
      
      
        
IntList.list 
      
      = 
      
        function
      
      
        (__args){
    
      
      
        var
      
       sentinel = 
      
        new
      
      
         IntList(),
        len 
      
      =
      
         __args.length,
        p;
    p 
      
      =
      
         sentinel;
    
      
      
        for
      
      (
      
        var
      
       i = 0; i < len; i++
      
        ){
        p.tail 
      
      = 
      
        new
      
      
         IntList(__args[i]);
        p 
      
      =
      
         p.tail;
    }
    
      
      
        return
      
      
         sentinel.tail;
};

      
      
        /*
      
      
         返回该对象的字符串表示 
      
      
        */
      
      
        
IntList.prototype.toString 
      
      = 
      
        function
      
      
        (){
    
      
      
        var
      
       temp = ""
      
        ;
    temp 
      
      += "["
      
        ;
    
      
      
        for
      
      (
      
        var
      
       L = 
      
        this
      
      ; L !== 
      
        null
      
      ; L =
      
         L.tail){
        temp 
      
      = temp + " " +
      
         L.head;
    }
    temp 
      
      += " ]"
      
        ;
    
      
      
        return
      
      
         temp;
};


      
      
        /*
      
      
        * 返回一个IntList,包含IntList A和IntList B,
 *  其中B的元素在A的后面。不能使用new关键字。
 
      
      
        */
      
      
        function
      
      
         dcatenate(A, B){
    
      
      
        /*
      
      
         完成功能 
      
      
        */
      
      
        
}


      
      
        /*
      
      
        * 返回一个新的IntList,其长度为len,
 *  以#start元素为开头(其中#0是第一个元素),
 *  不能改变L。
 
      
      
        */
      
      
        function
      
      
         sublist(L, start, len){
    
      
      
        /*
      
      
         完成功能 
      
      
        */
      
      
        
}
      
    

这是一个用Javascript写的链表题。由于链表拥有较为复杂的引用操作,正好可以用来考察下对Javascript的引用的理解。附带简单的测试用例:

      
        /*
      
      
         测试dcatenate和sublist函数是否正确 
      
      
        */
      
      
        function
      
      
         test(){
    
      
      
        var
      
       A = IntList.list([4,6,7,3,8
      
        ]),
        B 
      
      = IntList.list([3,2,5,9
      
        ]);
    dcatenate(A, B);
    
      
      
        if
      
      (A.toString() === "[ 4 6 7 3 8 3 2 5 9 ]"
      
        ){
        alert(
      
      "dcatenate函数正确。"
      
        );
    }
      
      
        else
      
      
        {
        alert(
      
      "dcatenate函数错误。"
      
        );
    }
    
      
      
        var
      
       L = IntList.list([3,4,5,2,6,8,1,9
      
        ]),
        result 
      
      = sublist(L, 3, 3
      
        );
    
      
      
        if
      
      (result.toString() === "[ 2 6 8 ]"
      
        ){
        alert(
      
      "sublist函数正确。"
      
        );
    }
      
      
        else
      
      
        {
        alert(
      
      "sublist函数正确。"
      
        );
    }
}
      
    

 

Javascript引用?

实际上,在对变量赋予引用类型实例时,变量保存的是该实例的引用:

  var temp = new Object();

Javascript引用指针_第1张图片

这种表现非常切合它的名字,引用类型,其实例当然是来引用的。

而当将该变量再付给另一个变量的时候,实际上只是进行了对引用的复制操作:

  var temp2 = temp;

Javascript引用指针_第2张图片

所以虽然从定义式来看:temp2 = temp,但他们并没有直接联系,例如修改了temp的引用:

      
        var
      
       temp =
      
         {
    name: 
      
      "temp"
      
        
};


      
      
        var
      
       temp2 =
      
         temp;

temp 
      
      =
      
         {
    name: 
      
      "not temp2"
      
        
};

temp 
      
      === temp2;    
      
        //
      
      
        false
      
    

当然,如果我们修改的只是指针指向的实例本身,那么temp2依然等于temp:

      
        var
      
       temp =
      
         {
    name: 
      
      "temp"
      
        
};


      
      
        var
      
       temp2 =
      
         temp;

temp.name 
      
      = "also temp2"
      
        ;

temp 
      
      === temp2;    
      
        //
      
      
        true
      
    

 

IntList是什么东东?

我们来分析一下下图:

  1. 创建两个空的变量,所以右图中L和Q是空的。
  2. 创建一个新的IntList其头部为3,尾部为空,将L引用的值赋给Q,所以L和Q都指向这个新的IntList。
  3. Q指向一个新创建的IntList其头部为42,尾部为空,将Q的指针赋给L.tail,这样两个IntList被套嵌起来。

可见IntList是个通过指针达到多重套嵌的数据结构,被称为链表(Linked List)。

 

IntList合并

 我们只需要将其中一个的尾部指向另一个就行了。这样这两个IntList就连接起来了:

      
        /*
      
      
        * 返回一个IntList,包含IntList A和IntList B,
 *  其中B的元素在A的后面。不能使用new关键字。
 
      
      
        */
      
      
        function
      
      
         dcatenate(A, B){
    
      
      
        var
      
      
         p;
    
      
      
        for
      
      (p = A; p != 
      
        null
      
      ; p =
      
         p.tail){
        
      
      
        if
      
      (p.tail === 
      
        null
      
      
        ){
            p.tail 
      
      =
      
         B;
            
      
      
        break
      
      
        ;
        }
    }
    
      
      
        return
      
      
         A
}
      
    

 

IntList截取

由于题目要求不能改变原IntList,所以我们只能从原IntList取出数据再重建一个新的数据。 

      
        /*
      
      
        * 返回一个新的IntList,其长度为len,
 *  以#start元素为开头(其中#0是第一个元素),
 *  不能改变L。
 
      
      
        */
      
      
        function
      
      
         sublist(L, start, len){
    
      
      
        var
      
      
         K,
        P,
        J;
    
      
      
        var
      
       i = 0
      
        ,
        end 
      
      = start +
      
         len;
    
      
      
        for
      
      (P = L; i <= end; P = P.tail, i++
      
        ){
        
      
      
        if
      
      (i <
      
         start){
            
      
      
        continue
      
      
        ;
        }
      
      
        else
      
      
        if
      
      (i ===
      
         start){
            K 
      
      = 
      
        new
      
      
         IntList(P.head);
            J 
      
      =
      
         K;
        }
      
      
        else
      
      
        if
      
      (i > start && i <
      
         end){
            J.tail 
      
      = 
      
        new
      
      
         IntList(P.head);
            J 
      
      =
      
         J.tail;
        }
      
      
        else
      
      
        if
      
      (i >=
      
         end){
            
      
      
        break
      
      
        ;
        }
    }
    
      
      
        return
      
      
         K;
}
      
    

 

思考题

 1.  函数传参数的时候是怎么传的?例如下面代码的引用过程是怎样的?

      
        var
      
       obj =
      
         {
    name: 
      
      "anything"
      
        
};


      
      
        function
      
      
         getName(__obj){
    
      
      
        return
      
      
         __obj.name;
}


      
      
        var
      
       name = getName(obj);
    

 

扩展阅读

Javascript的this关键字详解

Javascript引用指针


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论