给定带闭包的代码,为什么make_function
在传递对象时返回null
?
Plnkr:http://plnkr.co/edit/L3nNeiibTMdR6GEnyMOX?p=preview
$(document).ready(everything);
function everything() {
var null_start = null;
var object_start = { obj: null };
function make_function (arg) {
return function () {
d3.select('#console')
.append('p')
.text(JSON.stringify(arg))
.style('color', 'blue');
};
}
// Make a function with arg=null
var func = make_function(null_start);
d3.select('#console').append('p').text('Expecting null here');
func();
null_start = {
foo: 5,
bar: 42
};
d3.select('#console').append('p')
.html('Expecting {foo:5, bar:42} here <span style="color:red;">Why is this still null???</span>');
func();
// Make a function with arg={obj:null}
func = make_function(object_start);
d3.select('#console').append('p').text("Expecting {obj: null} here");
func();
object_start.obj = {
foo: 5,
bar: 42
};
d3.select('#console').append('p')
.html('Expecting {obj: {foo:5, bar:42}} here <span style="color:red;">if this one is updated?</span>');
func();
}
答案 0 :(得分:3)
JavaScript中传递的参数不是通过引用传递的,而是通过特殊的“引用副本”传递的。换句话说,当您将null_start
传递给make_function
时,会传递null_start
变量的副本。
null_start
变量的更改不会被传递给函数的变量反映出来。
这就是为什么使用变量的新值创建另一个函数的方法与示例中的预期一致。
请注意,在传递对象时,对象的更改也将由原始变量反映。这是因为JavaScript中的对象是可变的。例如:
function change (obj) { obj.foo = 'bar'; }
var x = {};
change(x);
console.log(x.foo); // 'bar'
这是因为对象只是一组指向值的键。对象内的键指向到值,可以修改这些值,并由函数的外部范围反映出来。但是,如果我们直接传递该值,它将无法工作:
function change (val) { val = 'fff'; }
var x = {foo: 'bar'};
change(x.foo);
console.log(x.foo); // 'bar'
希望有所帮助!