如何在JavaScript中将基元作为参数传递到函数中
How are primitives passed into functions as arguments in JavaScript?
将基元作为参数传递到JavaScript函数时,它是传递到函数中的值(即正在创建的新变量)的副本,还是只是指向内存中变量位置的指针,就像对象一样?由于对象是可变的,这很容易证明,然而,由于基元是不可变的,它们总是会被重新分配,所以很难判断幕后发生了什么。
在以下代码中(http://jsbin.com/egufog/2/edit)演示了我的意思:
var pvalue = 'foo'; //primitive
var ovalue = { foo : 'foo' }; //object
changeMe( pvalue, ovalue ); //changes values
console.log( pvalue, ovalue ); //pvalue unchanged, ovalue was changed
reassignMe( ovalue ); //reassigns the object, breaking the reference
console.log( ovalue ); //ovalue remains unchanged
function changeMe( primitive, obj ){
primitive = 'bar'; //did this reassign the pointer or just create another variable?
obj.foo = 'bar'; //updates the object in memory
}
function reassignMe( obj ) {
obj = { baz : 'baz' }; //reassignment breaks the pointer reference
}
当将基元作为参数传递到JavaScript函数中时,它是传递到函数中的值(即正在创建的新变量)的副本,还是只是指向内存中变量位置的指针,就像对象一样?
函数参数总是创建一个新变量,即一个名称包含值的槽。由于javascript没有指针,所以它保存值的位置,而不是变量的位置。
由于基元是不可变的,它们总是会被重新分配,所以很难判断幕后发生了什么。
确切地说,我们不知道。但由于它们是不可变的,因此无论变量是被分配了值本身的副本还是值的位置,都没有区别。JS引擎可以自由选择——我希望对大字符串使用引用,但对数字或布尔值不使用引用。
changeMe( 'foo' ) function changeMe( primitive, obj ){ primitive = 'bar'; //did this reassign the pointer or just create another variable? }
自从调用该函数以来,就不存在新的变量primitive
。它以前保存值'foo'
(或指向它的指针),现在保存值'bar'
(或指向该值的指针)。
只有对于对象,我们知道保存它们的变量包含指向内存中数据结构的指针-它们被称为"引用值"(与基元相反)。如果你改变数据,你可以从引用对象的每个变量中看到这一点。
我认为说太简单了
console.log( pvalue, ovalue ); //pvalue unchanged, ovalue was changed
如果我们认为pvalue和ovalue是对对象的引用,我们将引用保存在堆栈上,为被调用的函数制作副本以供使用,然后调用该函数。在这一点上,被调用的函数有自己的引用,但它仍然指向相同的对象,因此能够更改它们
如果我们重新分配传递到函数中的引用,例如
primitive = 'bar'; //did this reassign the pointer or just create another variable?
或obj = { baz : 'baz' }; //reassignment breaks the pointer reference
然后,我们所做的只是更改原始引用的副本,其范围仅限于被调用的函数。回到调用函数,我们从堆栈中删除原始引用
据我所知,当基元类型在函数的参数中传递时,它们会按值传递,并且基元值的副本会在函数中传递。这意味着,如果在函数中更改参数的值,那么变量的"原始"值是完整的。
var pvalue = 'foo'; //primitive
function changeMe(prim) {
prim = 'bar';
}
changeMe(pvalue);
console.log(pvalue); // pvalue remains foo (unchanged)
但是,如果你对一个对象进行同样的尝试,它将更改"原始"对象,因为它在函数中的新变量也将指向原始对象。但这并不意味着它是通过引用传递的。看看这个。
function changeMe(obj) {
obj.foo = "foo";
obj = new Object();
obj.foo = "bar";
}
var ovalue = { foo : null };
changeMe(ovalue);
alert(ovalue.foo); // Changed to foo but not to bar
这意味着,如果obj是由refence传入的,那么当我将新Object分配给obj并更改属性时,它也会将原始对象的foo属性更改为bar。
因此,我认为对象也是按值传递的,例如,当您使用该值分配属性时,它会将其指向与以前相同的对象。但是,如果您在函数内将obj重新分配给一个新对象,那么这个新对象将指向一个不同的本地对象,该对象可以在其创建的函数范围内访问。
- 函数未将值作为参数传递
- 如何在HTML元素上创建函数,而不是将元素作为参数传递
- 如何传递函数中的参数
- 将参数传递给函数
- 如何向onClick事件处理程序传递一个接受参数的函数,并且仍然将该函数绑定到组件's”;这个“;上下文
- 传递带有参数的函数
- javascript,将参数传递给函数内部的闭包中的回调
- 将字符串作为参数传递给函数onclick event jquery
- 将修改后的数组作为参数传递给函数
- 代码气味-将布尔控制参数传递给函数
- 将参数传递给函数,同时保留事件处理程序
- 如何使用按钮将参数传递给函数
- 作为参数传递时如何计算函数
- 将对象作为参数传递时的 Javascript 函数作用域
- 将回调作为参数传递给函数
- 在构造控制器、服务等时作为函数参数传递之前列出的角度 JS 变量
- 作为参数传递的函数的异步执行
- 将请求作为参数传递给函数
- 什么时候需要在javascript中的函数中将对象作为参数传递
- Javascript,对象,用参数传递函数作为参数- angular, jquery概念基本误区