书上有个例子:
-
function setName(obj) {
-
obj.name = 'Nicholas';
-
obj = new Object();
-
obj.name = "Greg";
-
console.log(obj.name); // "Greg"
-
}
-
-
var person = new Object();
-
setName(person);
-
alert(person.name) // "Nicholas"
另外不传递参数改成:
-
function setName() {
-
person.name = 'Nicholas';
-
person = new Object();
-
person.name = "Greg";
-
console.log(person.name); // "Greg"
-
}
-
-
var person = new Object();
-
setName();
-
console.log(person.name) // "Greg"
分析一下原因:
第一个case:
person这个object作为参数传递给function的时候,function内部的作用域可以找到person而且这个时候obj的值是一个指向的是“堆内存空间中person所指向的这个Object它本身”(person本身也是个指针,obj是person这个指针被作为参数传递后复制出来的副本);然后下一步new出一个Object的时候,是在堆内存空间中新建了一个Object(),这个时候obj是指向这个新new出来的Object的指针,所以对这个Object新增一个叫name的属性并且在这个局部变量指针还未被销毁(即函数未执行完毕)之前打出log,输出的是这个新new出来的Object里的name属性,是Greg。需要注意的是,在function执行的这一个阶段里,对于原来的Object进行操作只有一次,即给它的name属性赋值为'Nicholas',随即在这个函数里就没有指针再指向它了,所以在外部的输出就是"Nicholas";
第二个case:
从始至终person伴随着我们的一直是person这个指针, 最初在声明阶段即在function外部那个 var person = new Object(); 时,这一步它是指向new出来位于堆内存内的Object。但在之后function中的执行阶段, person指针又被指向function里new出的这个Object了,注意这次不是局部变量,所以person就一直指向新的Object()了,所以后边的log输出就是这个新new出来的对象的name: "Greg" 。
所以第一个case里我想要让两个new出的Object里的name都输出出来,就可以建立一个全局变量,然后把指针的值存储区来,如下:
-
<span style= "font-size:14px;"> function setName(obj) {
-
obj.name = 'Nicholas';
-
obj = new Object();
-
obj.name = "Greg";
-
pointer = obj;
-
}
-
-
var person = new Object();
-
var pointer = null;
-
setName(person);
-
alert(pointer.name); // "Greg"
-
alert(person.name); // "Nicholas"</span>