Javascript引用指针使用介绍_javascript技巧

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

复制代码 代码如下:

/* 创建一个队列,头为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 = 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是什么东东?

我们来分析一下下图:

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

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

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);

时间: 2024-10-02 21:31:11

Javascript引用指针使用介绍_javascript技巧的相关文章

浅谈JavaScript中指针和地址_javascript技巧

个人理解:指针只是指向内存的一个索引:而地址则是内存中确切的位置. 下面是函数中关于指针和地址一个小例子: function sum(num1,num2){ return num1+num2; } alert(sum(10,10)); //20 var anotherSum=sum; alert(anotherSum(10,10)); //20 sum=null; alert(anotherSum(10,10)); //20  注意:使用不带圆括号的函数的名是访问函数指针,而非调用函数,所以 s

Javascript函数式编程简单介绍_javascript技巧

几十年来,函数式编程一直是计算机科学狂热者的至爱,由于数学的纯洁性和谜一般的本质, 它被埋藏在计算机实验室,只有数据学家和有希望获得博士学位的人士使用.但是现在,它正经历一场复兴, 这要感谢一些现代语言比如Python,Julia,Ruby,Clojure以及--但不是最后一个--Javascript. 你是说Javascript?这个WEB脚本语言?没错! Javascript已经被证明是一项长期以来都没有消失的重要的技术.这主要是由于它扩展的一些框架和库而使其具有重生的能力, 比如backb

javascript基本包装类型介绍_javascript技巧

为了便于操作基本类型值,ECMAScript 提供了 3 个特殊的引用类型:Boolean.Number和 String.这些类型与其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为.实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而能够调用一些方法来操作这些数据. 一.基本包装类型概述 var box = 'Mr. Lee';//定义一个字符串 var box2 = box.substring(2);//截掉字符串前两位 alert(box2);//

Javascript中的delete介绍_javascript技巧

一.问题的提出 我们先来看看下面几段代码,要注意的是,以下代码不要在浏览器的开发者工具(如FireBug.Chrome Developer tool)中运行,原因后面会说明: 为什么我们可以删除对象的属性: 复制代码 代码如下: var o = { x: 1 }; delete o.x; // true o.x; // undefined 但不以删除像这样声明的变量: 复制代码 代码如下: var x = 1; delete x; // false x; // 1 也不能删除像这样定义的函数:

JavaScript Function函数类型介绍_javascript技巧

// 在JS中,Function(函数)类型实际上是对象;每个函数都是Function类型的实例;而且都与其他引用类型一样具有属性和方法; // 由于函数是对象,因此函数名实际上也是一个指向函数对象的指针; 一 函数的声明方式 1.函数声明方式 function box(num1,num2){ return num1+num2; } 2.函数表达式定义函数 var box = function(num1,num2){ // 通过变量box即可引用函数; return num1+num2; };

JavaScript作用域链使用介绍_javascript技巧

之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时候发现作用域和执行环境确实很重要,又很基础,对理解JavaScript闭包很有帮助,所以在写一篇对作用域和执行环境的理解. 作用域 作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域. 单纯的JavaScript作用域还

JavaScript中的闭包介绍_javascript技巧

所谓的闭包应该是指: 内部函数读取当前函数以外的变量,即创建时所处的上下文环境. 复制代码 代码如下: function hello(){     var char = "hello,world";     function print(){         console.log(char);     };     return print(); } 需要注意的是这里的print函数引用了外部hello函数的char变量,于是在这里我们能够返回一个 复制代码 代码如下: hello,

JavaScript设计模式之适配器模式介绍_javascript技巧

适配器模式说明 说明: 适配器模式,一般是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况: 场景: 就好比我们买了台手机,买回来后发现,充电线插头是三插头,但家里,只有两插头的口的插座,怎么办?为了方便,也有为能在任何地方都能充上电,就得去买个通用充电适配器; 这样手机才能在自己家里充上电:不然只能放着,或跑到有这个插头的地方充电: 实际开发环境下,由于旧的系统,或第三方应用提供的接口,与我们定义的接口不匹配,在以面向接口编程的环境下,就无法使用这样旧的,或第三方的接

JavaScript prototype属性深入介绍_javascript技巧

每个函数创建时默认带有一个prototype属性,其中包含一个constructor属性,和一个指向Object对象的隐藏属性__proto__.constructor属性的值为该函数的对象.在一个函数前面加上new来调用,则会创建一个隐藏连接到该函数prototype成员的新对象(由__proto__属性来链接),同时函数的this将会被绑定到那个新对象上. 函数总是返回一个值:如果没有指定返回值,就返回undefined:如果当做构造函数来调用,且返回值不是对象,则返回this(该新对象):