var steve = function() {
var bob = {};
bob.WayCoolTest = function () {console.log('done deal');};
return bob;
}
window["steve"]["WayCoolTest"]
在我的测试应用程序的chrome控制台中运行它,任何地方的结果都是未定义的。我不明白为什么,有人可以解释为什么这不起作用并帮助我解决它。非常感谢!!
答案 0 :(得分:4)
使用窗口通常是多余的 - 让我演示一下:
var foo = '123';
alert(foo); //123
alert(window.foo) //123
alert(window['foo']) //123
很明显哪个更方便。在某种情况下,使用窗口是有意义的,但这种情况几乎总是因为糟糕的架构。使用窗口允许我们访问变量全局变量 - 有趣的措辞:)这应该清除它:
var foo = '123';
var bar = 'abc';
var prop;
if (blah) { //some condition here
prop = 'foo';
}
else {
prop = 'bar';
}
现在......我们如何使用prop来获取相应变量的值?
console.log(window[prop]); //123 or abc - bracket notation lets us use variable property names
这种事物在对象中非常常见,但不适用于窗口。原因是我们应该尽可能地避免全局变量(窗口的属性)。因此,任何需要变量属性名称的逻辑都应该在对象内部,处理对象 - 不是window
。现在窗口可能不合适了。
在其他功能中创建功能通常是不好的做法。这意味着每次调用函数A时,都会重新创建函数B.大多数情况下,人们这样做是因为他们不知道更好,而不是因为他们需要。
在我看来,您打算给steve
一个名为WayCoolTest
的属性,这两个属性都是函数。这可以做到。
var steve = function() {
console.log("I'm Steve!");
}
steve.WayCoolTest = function() {
console.log("I'm a Way Cool Test!");
}
steve(); //I'm Steve!
steve.WayCoolTest(); //I'm a Way Cool Test!
这是有效的,因为函数是javascript中的对象。因此,您可以向它们添加属性。
让我们加快步伐吧!
为了强调良好实践,我将把这个例子包装在一个对象testApp
中(它就像一个名称空间......我们使用它而不是窗口)。
我将创建一个名为testApp
的{{1}}属性,它将是一个函数。
我不会直接创建steve
作为函数,而是使用IIFE(立即调用的函数表达式),这是一个将steve
设置为return
的函数。
在IIFE中,我将为steve
创建函数并附加steve
,如前面的示例所示,然后返回该函数并将其分配给WayCoolTest
。
steve
现在,让我们考虑另一种变体。
var testApp = {
steve : (function() {
var steve = function() { //the name here doesn't matter, just being consistent, since this will be the value of the property `steve`.
console.log("I'm Steve!");
}
steve.WayCoolTest = function() {
console.log("I'm a Way Cool Test!");
}
return steve;
}());
};
testApp.steve(); //I'm Steve;
testApp.steve.WayCoolTest(); //I'm a Way Cool Test!
如果例如var testApp = {
steve : (function() {
var steve = function() { //the name here doesn't matter, just being consistent, since this will be the value of the property `steve`.
console.log("I'm Steve!");
WayCoolTest(); //Steve can use this, but nothing else can! Encapsulation.
}
var WayCoolTest = function() { //THIS PART!! No longer a property of "steve"
console.log("I'm a Way Cool Test!");
}
return steve;
}());
};
testApp.steve(); //I'm Steve! I'm a Way Cool Test
testApp.steve.WayCoolTest(); //undefined, of course
是一个复杂的函数,并且您希望将其分解为只有steve
知道的其他一些小函数,那么这非常有用。
答案 1 :(得分:1)
如果您声明使用var
,则它不会与全局window
范围相关联。它是一个局部变量。另外bob不是你设置的史蒂夫对象的属性
答案 2 :(得分:1)
假设steve
在全局范围内并且您似乎不使用steve
作为构造函数,则可以使用立即函数并返回您在其中创建的新对象。
var steve = (function () {
var bob = {};
bob.WayCoolTest = function () {
console.log('done deal');
};
return bob;
})();
window["steve"]["WayCoolTest"]();
如果它在一个闭包中,那么你必须删除var
才能使其成为窗口的一部分,或者将它作为一个属性设置为窗口对象。
window.steve = (function () {
var bob = {};
bob.WayCoolTest = function () {
console.log('done deal');
};
return bob;
})();
答案 3 :(得分:1)
为了补充其他答案,您的代码将以这种方式工作:
var steve = function() {
var bob = {};
bob.WayCoolTest = function () {console.log('done deal');};
return bob;
}
window["steve"]()["WayCoolTest"]();
或
var steve = (function() {
var bob = {};
bob.WayCoolTest = function () {console.log('done deal');};
return bob;
})();
window["steve"]["WayCoolTest"]();
或者,最脏的方式......
steve=(function() {
var bob = {};
bob.__defineGetter__("WayCoolTest", function () {console.log('done deal');});
return bob;
})();
window["steve"]["WayCoolTest"];