CNode

作为传入参数的变量的作用域

Wwillwen发布于14 年前最后回复14 年前27 回复9173 浏览0 收藏

今晚在写connect的Response Pipelining的时候发现,若在函数内把该函数的传入参数进行重新定义的时候,该对象的指针不会起作用,即函数以外的那个传入的对象不会受影响。

var foo = "foo";
function reset (arg) {
    arg = "bar";
    console.log(arg);
}
reset(foo);   //  bar
console.log(foo);    //   foo

大家来讨论下。

查看回复

回复 (26)

L
leolovenodejs#1·14 年前
引用 jin52yang基本类型传的是值的拷贝,引用类型传的是引用的拷贝。和java一样

ECMAScript中的所有参数传递的都是值,不可能通过引用传递传数。

S
sumory#2·14 年前
var array= [1,2];
function reset (arg) {
    arg.push(3);
    console.log(arg);
}
reset(array);   //  [1,2,3]
console.log(array);    //   [1,2,3]
W
willwen#3·14 年前
引用 sumoryvar array= [1,2]; function reset (arg) { arg.push(3); console.log(arg); } reset(array); // [1,2,...

嗯,若只是调用参数方法来改变参数值是有效的,只有直接对参数赋值会出现该问题。应该说是特性吧。

S
sumory#4·14 年前
引用 sumoryvar array= [1,2]; function reset (arg) { arg.push(3); console.log(arg); } reset(array); // [1,2,...

@WillWen 哦去,你也是夜猫子!再看看这个,放在一块看更有意思

var foo = "foo";
function reset () {
    foo= "bar";
    console.log(foo);
}
reset(foo);   //  bar
console.log(foo);    //   bar
Y
young40#5·14 年前

很多语言里面都有这样的现象或者说问题,

似乎叫做值参数, 引用参数这样的概念吧.

@WillWen 的例子是值参数的情况, 传递的是一个简单类型, 比如字符串, 数字等

@sumory 的例子在node中估计是引用参数的例子, 所以会改变原变量值.

就我所接触到的语言范围来看, 对象这种一般都是引用参数

S
sumory#6·14 年前
W
willwen#9·14 年前
引用 young40很多语言里面都有这样的现象或者说问题, 似乎叫做值参数, 引用参数这样的概念吧. @WillWen 的例子是值参数的情况, 传递的是一个简单类型, 比如字符串, 数字等 @sumory 的例子...

实际上可以这样理解:当我们运行某个函数并传入参数时,解析器就会新生成一个映像,这个映像拥有所以对应原传入参数各属性的getter(而没有setter),因为对象的方法处在该函数的作用域之外,所以方法中对该对象的重新赋值是有效的,而在函数作用域内的参数是没有setter的,故set动作无效。 PS:这就是为什么Backbone会选择用方法来改变值,而不是直接使用对象字面量。

W
willwen#10·14 年前
引用 sumoryvar array= [1,2]; function reset (arg) { arg.push(3); console.log(arg); } reset(array); // [1,2,...

@sumory 解析器现在该函数的代码块(作用域)内寻找foo,找不到后就会冒泡到上一层(即进程层)查找,找到了然后对它赋值。

G
guilin#11·14 年前

arg 是一个引用而不是一个指针.

S
sumory#12·14 年前
引用 guilinarg 是一个引用而不是一个指针.

js中有指针的概念?貌似没有吧

W
willwen#13·14 年前
引用 guilinarg 是一个引用而不是一个指针.

我指的是这个引用的值指向,一种单向获取值而不能赋值的引用。。坑爹啊,要把一系列中间件改一遍。。

S
sumory#14·14 年前
引用 guilinarg 是一个引用而不是一个指针.

@WillWen 玩不同的语言有时会被它的特性所吸引,有时也会被折磨...

B
blue5tar#15·14 年前

js 中 数组和对象师引用的 你的例子中foo是字符串 是值传递不是引用传递

var foo = {a:2}; 
function reset(arg) { 
   arg.a = 1; 
   console.log(arg.a); //1
} 
reset(foo); 
console.log(foo.a); //1
L
leizongmin#16·14 年前
var obj = {foo: "foo"};
function reset (arg) {
  arg.foo = "bar";
  console.log(arg.foo);
}
reset(obj);             //  bar
console.log(obj.foo);   //   foo
W
willwen#17·14 年前
引用 blue5tarjs 中 数组和对象师引用的 你的例子中foo是字符串 是值传递不是引用传递 var foo = {a:2}; function reset(arg) { arg.a = 1; console...

嗯,凡是在函数作用域意外的东西都不受限制,只有在传参后对参数本身进行赋值才会出现问题。

J
jin52yang#18·14 年前

基本类型传的是值的拷贝,引用类型传的是引用的拷贝。和java一样

O
olddog#20·14 年前
引用 blue5tarjs 中 数组和对象师引用的 你的例子中foo是字符串 是值传递不是引用传递 var foo = {a:2}; function reset(arg) { arg.a = 1; console...

这个是正确的,记得字符串只有在赋值的时候是按照引用类型处理。其他时候都是按照值传递。这点在周爱民的那本书里有说明

L
leolovenodejs#22·14 年前
引用 jin52yang基本类型传的是值的拷贝,引用类型传的是引用的拷贝。和java一样

@jin52yang 如果传递的是引用类型的值,这个值其实是不是就是内存地址啊?

J
jin52yang#23·14 年前
引用 jin52yang基本类型传的是值的拷贝,引用类型传的是引用的拷贝。和java一样

@leolovenodejs 不是指针哇,是引用地址而已哇...

L
leolovenodejs#24·14 年前
引用 jin52yang基本类型传的是值的拷贝,引用类型传的是引用的拷贝。和java一样

@jin52yang 引用地址:即堆内存地址;而这个引用地址是被保存在栈内存中的。 引用传递其实传递的是栈中的值,即值传递,值为堆内存地址。 这么理解对不?

参与回复
登录后即可参与回复。登录