我正在尝试获取这样一个对象的副本:
graphs = (function () {
var trends = {
pointSize: 10,
};
// Object Oriented JavaScript - pp 109
var lockVariable = function(x) {
return function() {
return x;
}
};
var getTrendsConfig = function() {
return lockVariable(trends)();
};
return {
getTrendsConfig : getTrendsConfig
};
}());
c = graphs.getTrendsConfig();
c.pointSize = 11;
console.log(graphs.getTrendsConfig())
我原本打算打印一个“{pointSize:10}”
因为 getTrendsConfig 函数会将trend对象传递给 lockVariable 函数,该函数将返回本地值对象:“{pointSize:10}”,而不是我得到的“{pointSize:11}”。
我从“面向对象的JavaScript”一书的一个例子中得到了这一点,第108-109页:
如何获得预期结果?可能吗?为什么这不起作用?
答案 0 :(得分:1)
graphs = (function () {
var trends = {
pointSize: 10,
};
// Object Oriented JavaScript - pp 109
var lockVariable = function(x) {
return function() {
return x;
}
};
var getTrendsConfig = function() {
return lockVariable(trends)();
};
return {
getTrendsConfig : getTrendsConfig
};
}());
c = Object.assign({}, graphs.getTrendsConfig()); // same as ...graphs.getTrendsConfig() in ES6 spread syntax
c.pointSize = 11;
console.log(graphs.getTrendsConfig());
console.log("c =", c);
由于您已将c.pointSize
重新分配给11
,因此您未获得预期结果,这就是您获得11
的原因;
在JavaScript中,将对象分配给变量是通过引用而不是通过值完成的。这意味着您只是复制对象在内存中的位置,导致任何修改都会影响原始值。
在您分配c = graphs.getTrendsConfig();
的示例中,c
现在将指向同一对象的位置/地址。
当您执行此c.pointSize = 11
时,您修改了相同的(原始)对象而不是副本。
<强>解决方案:强>
另外,为了制作graphs.getTrendsConfig()
的副本,您可以使用Object.assign()
或新的ES6差异语法...
。通过制作副本,您不会修改原始对象的pointSize
变量。
答案 1 :(得分:1)
JavaScript中的原始值(如数字)是不可变的。您可以将x
复制到i
(根据本书),更改x
并保持trends
不变。
对象不是不可变的,只能通过引用来解决。当您返回c = graphs.getTrendsConfig();
(c
)的值时,您将返回对该对象的引用(因此trends
和trends
都包含对同一对象的引用)。修改它时,您修改该对象。获取graphs = (function() {
var lockVariable = function(x) {
return function() {
return x;
}
};
var getTrendsConfig = function() {
var trends = {
pointSize: 10,
};
return lockVariable(trends)();
};
return {
getTrendsConfig: getTrendsConfig
};
}());
c = graphs.getTrendsConfig();
c.pointSize = 11;
console.log(graphs.getTrendsConfig())
的另一个副本会为您提供另一个参考副本...仍然指向同一个对象。
处理这个问题的简单方法是在被调用的函数内移动创建对象的逻辑。
graphs = (function() {
var getTrendsConfig = function() {
return {
pointSize: 10,
};
};
return {
getTrendsConfig: getTrendsConfig
};
}());
c = graphs.getTrendsConfig();
c.pointSize = 11;
console.log(graphs.getTrendsConfig())
&#13;
虽然您可以将其简化为
graphs = (function() {
var trends = {
pointSize: 10,
};
// Object Oriented JavaScript - pp 109
var lockVariable = function(x) {
return Object.assign({}, x);
};
var getTrendsConfig = function() {
return lockVariable(trends);
};
return {
getTrendsConfig: getTrendsConfig
};
}());
c = graphs.getTrendsConfig();
c.pointSize = 11;
console.log(graphs.getTrendsConfig())
&#13;
要使用接近原始代码尝试实现的内容,您可以使用Object.assign()
import pandas as pd
import numpy as np
headers = lista.pop(0)
df = pd.DataFrame(lista, columns = headers)
martin = df[df['"Cliente"'] == 'Martin']
tom = df[df['"Cliente"'] == 'Tom']
merge = pd.merge(martin, tom, on = '"Fecha"')
stats = headers[2:]
compare = ['"Fecha"']
for index, row in merge.iterrows():
for x in stats:
merge[x+'_compare'] = np.where(row[x+'_x'] > row[x+'_y'], 'Martin', 'Tom')
if x+'_compare' not in compare:
compare.append(x+'_compare')
print(merge[compare])
#output
"Fecha" "Subastas"_compare "Impresiones_exchange"_compare "Fill_rate"_compare "Importe_a_pagar_a_medio"_compare "ECPM_medio"_compare
20/12/2017 Tom Martin Martin Martin Tom
21/12/2017 Tom Martin Martin Martin Tom
22/12/2017 Tom Martin Martin Martin Tom
&#13;