我有一个这样的课程设置:
.factory('DesignerService', function () {
var kit = {
clubName: 'Moss side archery club',
teamName: 'The flying arrows',
selectedColours: ['082140', '841c3d'],
selectedGarments: ['hoody'],
selectedDesign: "Angelus",
total: '00.00',
templates: []
};
var getTemplates = function () {
var templates = [];
console.log(kit);
for (var i = 0; i < kit.selectedGarments.length; i++) {
var garment = kit.selectedGarments[i];
kit.templates.push('/assets/garments/' + garment + '.svg');
}
return kit;
};
var getColours = function () {
return ['000000', 'FFFFFF', '00adef', 'ed008c', 'fef200', '2e3192', '00a652', 'ed1b24', 'c7c8ca', 'f14e23', '6c9d30', 'c0d731', 'f5a3c7', '816ab0', '082140', '1e4f2f', '5bcaf5', 'f04e3f', 'f68b1f', 'cdbe01', 'ee4d9b', '007193', '5f1e08', '841c3d'];
};
var getGarments = function () {
return ['Shirt', 'Track top', 'Skirt', 'Hoody', 'Socks', 'Shorts', 'Track pants', 'Polo shirt', 'Beanie hat', 'T - shirt'];
};
var getDesigns = function () {
return ['Angelus', 'Claudius', 'Equitius', 'Octavius', 'Valerius']
}
var addToArray = function (array, item) {
array.push(item);
};
var removeFromArray = function (array, item) {
var index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
}
};
var modifyArray = function (array, value) {
var i = array.indexOf(value);
if (i > -1) {
removeFromArray(array, value);
} else {
addToArray(array, value);
}
}
var setColour = function (colour) {
return modifyArray(kit.selectedColours, colour);
return kit;
};
var setGarment = function (garment) {
console.log(kit);
modifyArray(kit.selectedGarments, garment);
var kit = getTemplates();
console.log(kit);
return kit;
};
var setDesign = function (design) {
kit.selectedDesign = design;
return kit;
};
return {
kit: kit,
getTemplates: getTemplates,
getColours: getColours,
getGarments: getGarments,
getDesigns: getDesigns,
setColour: setColour,
setGarment: setGarment,
setDesign: setDesign
};
})
如果我调用函数 setGarment ,则第一个console.log(kit)会在 kit.selectedGarments 中返回undefined以及 modifyArray 错误。 但如果我注释掉这一行:
// modifyArray(kit.selectedGarments,服装);
然后 getTemplates 实际记录工具包对象并返回更新后的对象。
有人可以解释原因吗?
更新1
好的,现在我理解了这些悬挂的东西,我重新设计了我的服务,看起来像这样:
.factory('DesignerService', function () {
var self = this;
var addToArray = function (array, item) {
array.push(item);
};
var removeFromArray = function (array, item) {
var index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
}
};
var modifyArray = function (array, value) {
var i = array.indexOf(value);
if (i > -1) {
removeFromArray(array, value);
} else {
addToArray(array, value);
}
}
self.kit = {
clubName: 'Moss side archery club',
teamName: 'The flying arrows',
selectedColours: ['082140', '841c3d'],
selectedGarments: ['hoody'],
selectedDesign: "Angelus",
total: '00.00',
templates: []
};
self.getTemplates = function () {
var templates = [];
for (var i = 0; i < self.kit.selectedGarments.length; i++) {
var garment = self.kit.selectedGarments[i];
self.kit.templates.push('/assets/garments/' + garment + '.svg');
}
return self.kit;
};
self.getColours = function () {
return ['000000', 'FFFFFF', '00adef', 'ed008c', 'fef200', '2e3192', '00a652', 'ed1b24', 'c7c8ca', 'f14e23', '6c9d30', 'c0d731', 'f5a3c7', '816ab0', '082140', '1e4f2f', '5bcaf5', 'f04e3f', 'f68b1f', 'cdbe01', 'ee4d9b', '007193', '5f1e08', '841c3d'];
};
self.getGarments = function () {
return ['Shirt', 'Track top', 'Skirt', 'Hoody', 'Socks', 'Shorts', 'Track pants', 'Polo shirt', 'Beanie hat', 'T - shirt'];
};
self.getDesigns = function () {
return ['Angelus', 'Claudius', 'Equitius', 'Octavius', 'Valerius']
}
self.setColour = function (colour) {
return modifyArray(self.kit.selectedColours, colour);
return self.kit;
};
self.setGarment = function (garment) {
modifyArray(self.kit.selectedGarments, garment);
self.getTemplates();
return self.kit;
};
self.setDesign = function (design) {
self.kit.selectedDesign = design;
return self.kit;
};
return self;
})
这是正确的方法吗?
答案 0 :(得分:4)
这看起来像是一个Javascript variable hoisting问题。 Javascript解释器通过代码进行两次传递。第一遍,它查找变量声明,第二遍传递它执行代码。这基本上是对您的代码执行以下操作:
var kit = getTemplates()
变为:
var kit;
kit = getTemplates();
此时,Javascript解释器将首次通过,寻找变量声明(var kit
)。下一遍将实际执行代码(kit = getTemplates()
)。基本上,您的代码变为:
var kit;
console.log(kit); // kit is undefined
modifyArray(kit.selectedGarments, garment); // kit is still undefined
kit = getTemplates(); // kit is no longer undefined
console.log(kit); // kit will log out properly here
return kit;
希望这是有道理的。简单的解决方案是将您的范围kit
变量重命名为其他内容(可能是scoped_kit
)。通常,最好不要将变量名称从一个范围隐藏到另一个范围。
希望这有帮助!
答案 1 :(得分:1)
您遇到了悬挂问题。
在javascript中,您可以在声明之前初始化并使用变量。
x = "hello";
y = "world";
var x, y;
document.getElementById("message").innerHTML = x + " " + y;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message"></div>
声明已提升,但初始化不是。
var x = "hello";
document.getElementById("message").innerHTML = x + " " + y;
var y = "world";
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message"></div>
功能表现略有不同。函数声明可以在声明它们之前在代码中使用,这是因为它们在任何代码运行之前被加载,并被提升。
alert(works());
function works() { ... };
函数表达式不同。它们在代码中到达之前不会加载。
alert(doesntWork());
var doesntWork = function() { ... };
// Function declarations have their bodies hoisted.
document.getElementById("message1").innerHTML = y();
function x() { return "hello"; };
function y() { return x() + " world"; }
// Function expressions only load when the code is reached, they need to be declared before being used.
// document.getElementById("message2").innerHTML = b(); <-- This would cause an error.
var a = function() { return "hello"; },
b = function() { return a() + " world"; };
document.getElementById("message2").innerHTML = b();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="message1"></div>
<div id="message2"></div>
答案 2 :(得分:1)
由于您从OOP方面接近Angular工厂并提及公共“班级”成员,因此将其称为this.kit
而不是kit
是一种很好的做法(他们不会如果服务的kit
属性已更改,则相等。它还使代码明确且可读。
本地var kit
的问题是经典的JS吊装问题,正如比尔·伯格奎斯特的答案所解释的那样。