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();
这种表现非常切合它的名字,引用类型,其实例当然是来引用的。
而当将该变量再付给另一个变量的时候,实际上只是进行了对引用的复制操作:
var temp2 = temp;
所以虽然从定义式来看: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是什么东东?
我们来分析一下下图:
- 创建两个空的变量,所以右图中L和Q是空的。
- 创建一个新的IntList其头部为3,尾部为空,将L引用的值赋给Q,所以L和Q都指向这个新的IntList。
- 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);
    
  
扩展阅读


 
     
     
					 
					