我正在阅读somewhere当我们将一个对象传递给函数时“…当它作为参数传递时,JavaScript 总是通过引用使用该对象…”我认为这意味着(如果我错了,请纠正我)是如果该函数是以某种方式修改对象,就会改变原来定义的对象。我尝试用一些代码来说明这一点,它确实做了我认为它会做的事情,但是当我使用 Number 对象尝试博客文章中的示例时,它不会更改该对象中的原始值。请看我的jsbin:https://jsbin.com/wociro/edit?js,console,output
console.clear();
/**myobject Object**/
function myobject() {
this.value = 5;
}
var o = new myobject();
console.log("Original value of o: " + o.value); // o.value = 5
function objectchanger(fnc) {
fnc.value = 6;
}
objectchanger(o);
console.log("New value of o: " + o.value); // o.value is now equal to 6
/*Number Object*/
var num2 = new Number(2);
console.log("Original value of num2: " + num2);
function numberChanger(fnc) {
return fnc + 1;
}
console.log("num2 after running numberChanger: " + numberChanger(num2));
console.log("New value of num2: " + num2); //looks the same
我错过了什么吗?
最佳答案
数字对象仍然是对象。因此它们的值是一个引用,如果函数更改作为参数传递的对象的属性,则该对象将在函数外部受到影响。
function changer(obj) {
obj.foo = 'bar';
}
var num = new Number(123);
console.log(num.foo); // undefined
changer(num);
console.log(num.foo); // 'bar'
但是,包装在数字对象内的值不会存储为属性。它存储为 [[NumberData]] 内部槽。 ECMAScript 无法提供更改该插槽的方法,因此您无法更改该数字。
您尝试使用 fnc+1
来解包数字对象以获取其 [[NumberData]],并向其添加 1
。但结果只是被丢弃,它没有存储回 fnc
的 [[NumberData]] 槽中。
如果您希望能够实现类似于更改 [[NumberData]] 的功能,您可以
function MyNumber(num) {
this.__number__ = +num;
}
MyNumber.prototype = Object.create(Number.prototype);
Object.getOwnPropertyNames(Number.prototype).forEach(function(prop) {
var desc = Object.getOwnPropertyDescriptor(Number.prototype, prop);
if(desc && desc.value && typeof desc.value == 'function') {
var native = desc.value;
desc.value = function() {
return native.apply(this.__number__, arguments);
};
Object.defineProperty(MyNumber.prototype, prop, desc);
}
});
var num = new MyNumber(123);
console.log(+num, num+'', num.toFixed(2)); // 123, "123", "123.00"
num.__number__ = 456;
console.log(+num, num+'', num.toFixed(2)); // 456, "456", "456.00"
关于javascript - 通过引用传递给函数的对象数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38274142/