我认为两个例子最能说明我的问题。
(function(){
var myBtn = document.getElementById('myBtn');
function one() {
console.log(myBtn.innerHtml);
}
function two() {
myBtn.innerHtml = "apple";
}
function three() {
console.log(myBtn.value);
}
})();
VS
(function(){
function one() {
var myBtn = document.getElementById('myBtn');
console.log(myBtn.innerHtml);
}
function two() {
var myBtn = document.getElementById('myBtn');
myBtn.innerHtml = "apple";
}
function three() {
var myBtn = document.getElementById('myBtn');
console.log(myBtn.value);
}
})();
所以第一个例子使用了一个全局变量(或者当它被一个自调用函数锁定时,它不是一个全局变量?)第二个例子没有。第一个例子是DRY,而第二个例子是将所有内容保存在函数内。
哪一个更好用?两者的优点和缺点是什么?项目规模是否重要?
这也是一个理论上的例子,这些功能显然不会在没有html的情况下发挥作用。感谢。
答案 0 :(得分:1)
第二个缺点之一是在每个函数中需要再次计算和存储变量。这将对性能产生影响。变量在所有函数中都是相同的,因此您可以在函数1的函数上方将它减去它。示例1中的变量不会成为全局变量(因为使用了iffy)。这也是积极的。需要尽可能保持全球环境的清洁。就个人而言,我认为选项1也更加明显。
答案 1 :(得分:0)
第一个更好用。它提供了更清晰,更快速的代码。
(function(){
var myBtn = document.getElementById('myBtn');
function one() {
console.log(myBtn.innerHtml);
}
function two() {
myBtn.innerHtml = "apple";
}
function three() {
console.log(myBtn.value);
}
})();
编辑:只需在所有功能中存储和共享结果,就不需要多次运行相同的代码
答案 2 :(得分:0)
document.getElementById
函数将返回对指定了ID的第一个对象的引用。这意味着它将在后续调用期间返回对同一对象的引用(在大多数情况下,如果使用得当),它将永远不会引用其他元素,或者无效。
您可以放心地坚持第一个例子的风格。这不是c ++,你的对象不会消失。
答案 3 :(得分:0)
您的问题中有第三种缺失方法:使用对象。
如果myBtn
元素在页面生命周期内不会从文档中删除(即直到用户刷新页面 F5 ),作为第一种方法,你应该存储一个引用该元素以避免多次查询文档:
(function() {
// SomeObject isn't global, but a local variable of IIFE's scope ;)
var SomeObject = function() {
this.myBtn = document.getElementById("myBtn");
};
SomeObject.prototype = {
one: function() {
console.log(this.myBtn.innerHTML);
},
two: function() {
this.myBtn.innerHtml = "apple";
},
three: function() {
console.log(this.myBtn.value);
}
};
// This is required in order to be sure that SomeObject is going to
// be able to retrieve "myBtn" element during its construction time,
// because the document is already loaded
document.addEventListener("DOMContentLoaded", function() {
var some = new SomeObject();
some.one();
});
})();
<button id="myBtn">My button</button>
答案 4 :(得分:0)
它建议您不使用全局变量的原因是您不会污染全局命名空间。对于大闭包,相同的参数将成立。您不希望使用过多的变量污染闭包
所以像
这样的东西(function(){
var myBtn = document.getElementById('myBtn');
function one() {
console.log(myBtn.innerHtml);
}
function two() {
myBtn.innerHtml = "apple";
}
function three() {
console.log(myBtn.value);
}
})();
不会污染全局范围,它确实污染了封闭,即想象如果你有类似的东西会有多难维护
(function(){
var myBtn = document.getElementById('myBtn');
// lots of code..
function one() {
console.log(myBtn.innerHtml);
}
// lots of code..
function two() {
myBtn.innerHtml = "apple";
}
// lots of code..
function three() {
console.log(myBtn.value);
}
})();
因为您必须知道当您在three()
时myBtn存在于父作用域中并且在three
中创建局部变量时会掩盖该
反对使用外部范围的变量的另一种情况
(function(){
var myBtn = document.getElementById('myBtn');
// lots of code..
function one() {
console.log(myBtn.innerHtml);
}
// lots of code..
var myBtn1 = document.getElementById('myBtn1');
function two() {
myBtn1.innerHtml = "apple";
}
// lots of code..
function three() {
console.log(myBtn.value);
}
})();
有一个足够长的外部封闭,你将被迫跟踪myBtn,myBtn1 ....所以虽然这比全局范围(你必须跟踪文件中的变量)更好,现在你(只是?)必须跟踪闭包内的所有变量。
这引出了一个问题,对于大型闭包来说,更好的方法 。这是一个选项
(function () {
// lots of code..
function one(myBtn) {
console.log(myBtn.innerHtml);
}
// lots of code..
function two(myBtn) {
myBtn.innerHtml = "apple";
}
// lots of code..
function three(myBtn) {
console.log(myBtn.value);
}
var myBtn = document.getElementById('myBtn');
one(myBtn);
two(myBtn);
three(myBtn);
})();
保持一切很好地本地化。当然,如果你有一个大的闭包,这可能表明你在闭包(模块)中做了太多。
当然对于小型封口,你的第一个选择还不错。