毕竟这些很好的答案,没有更多要说的,所以继承人基于ECMAScript 5规范的解释。
在答案的末尾还有一个deepclone函数。
如在ES5规范中定义的,
11.13.1 Simple Assignment (=) 生产AssignmentExpression:
- 令LREF是评估LeftHandSideExpression的结果:LeftHandSideExpression = AssignmentExpression如下评价。
- 让rref是评估AssignmentExpression的结果。
- 让rval为
GetValue(rref)
。
- 抛出一个SyntaxError异常,如果以下所有条件:
- 类型(LREF)为参考是真的
- IsStrictReference(LREF)为真
- 类型(GetBase(LREF))是环境记录
- GetReferencedName(LREF)或者是 “EVAL” 或 “参数”
- 呼叫
PutValue(lref, rval)
。
- 返回rval。
所以什么时候到达点和rref
发生的是一个对象,是
§8.7.1(的在GetValue(V) //V==rref
是有趣的部分4b)
4。 如果IsPropertyReference(V),然后
- (B)返回调用使用碱作为其该值获得内部方法,并传递GetReferencedName(V)为自变量的结果。
在这一点上
rval
现在持有参考的对象,然后把它放在在
凡第8.7.2节(再次PutValue(V,W) //V==lref , W==rval
4b是最有趣的部分)来进场。
注:W是ATM引用您要分配对象和不值
4. 不然,如果IsPropertyReference(V),然后
- (B)使用base作为此值调用put内部方法,并为属性名称传递GetReferencedName(V),为值传递W,为Throw标志传递IsStrictReference(V)。
正如你可以在你的情况值b
这是个大气压参考到对象[6, 7, 8]
获取与结果置换看到的,可以这么说GetValue(rref)
,这是一个参考到[1, 2, 3];
然而
显然,你正在寻找一个深克隆功能
这是一个。
Object.defineProperty(Object.prototype, "clone", {
value: function (deep) {
var type = Object.prototype.toString.call(this).match(/^\[object (.+?)\]$/)[1];
if (type !== "Object") {
return this.valueOf;
}
var clone = {};
if (!deep) {
for (var prp in this) {
clone[prp] = this[prp];
}
} else {
for (var prop in this) {
if (typeof this[prop] !== "undefined" && this[prop] !== null)
clone[prop] = (typeof this[prop] !== "object" ? this[prop] : this[prop].clone((typeof deep == "boolean" ? deep : (deep - 1))));
else
clone[prop] = "";
}
}
return clone;
},
enumerable: false
});
Object.defineProperty(Array.prototype, "clone", {
value: function (deep) {
var clone = [];
if (!deep) clone = this.concat();
else this.forEach(function (e) {
if (typeof e !== "undefined" && e !== null)
clone.push((typeof e !== "object" ? e : e.clone((deep - 1))));
else
clone.push("");
});
return clone;
},
enumerable: false
});
var a = [1, [2, { a: 3 } ], 4];
var b = a.clone(Infinity);
a[1][1]["a"] = "cloned";
console.log(a[1][1]["a"], b[1][1]["a"]); //"cloned" , 3
而一个演示上JSBin
要使用它,只需调用.clone(levelOfDeepness)
上的对象或数组
注:我使用的对象原型的纯朴的缘故因为我可以在克隆对象和数组元素时直接调用.clone
m(在单个函数中提供了类型检查变体的性能提升)
严格地说,它总是“按值传递”,并且引用对象的变量的值是对该对象的引用。 JavaScript中不存在“通过引用传递”:https://en.wikipedia.org/wiki/Evaluation_strategy。 –
*“如何避免通过引用传递?”*:您必须复制数组:http://stackoverflow.com/q/7486085/218196。 –
你不“通过引用传递任何东西”。这意味着你会(以伪代码的形式)将函数声明为函数why(const n)或函数why(var n)'。不同之处在于,在第一种情况下,创建了'n'的副本,如果您离开某个函数,它将被销毁,但在第二个函数中您将修改该变量,因此保留该函数将保留您的更改。在你的例子中,'a'和'b'都是全局变量,所以默认情况下它们是引用('why'函数无关)。你应该没有问** ** **(变量引用),** ** **(变量引用)。 – Voitcus