JavaScript 和作用域






2.55/5 (8投票s)
JavaScript 和作用域
引言
好了,我有一段时间没有发帖了,这归结于假期。没有什么比假期更能扰乱你的生活了。如果你像我一样,你会尽可能地组织你的生活,这是你能够运作的唯一原因。这让我开始思考这篇博文,并给了我一个想法。
我一直在准备一些关于 MVC 的文章,甚至是一个演示文稿。我可能会把它带到代码训练营,甚至向我在哈里斯堡地区社区学院 (HACC) 的学生展示。这让我想到 MVC 最强大的优势之一是灵活性和将代码组织成独立的模块的能力。通过构建这个,我们可以将我们的代码组织成独立的类和导航控制器。我们可以隔离代码并保持松散的耦合,从而使代码更具可测试性。
现在我无法告诉你我看到多少次精彩的代码崩溃了。太多时候,我看到人们说“我们正在使用 MVC”,并说得好像它保证你的代码不仅使用了当前的技术,而且是正确的并且经过了适当的架构。 MVC 是一个框架,就像任何其他框架一样,这意味着就像任何框架一样,它只和代码的设计以及程序员的工作一样好。如果有一项技术可以保证好的代码,我们都将失业。
话虽如此,但有很多开发人员正确地利用了 MVC。他们使用适当的关注点分离。他们设置他们的控制器,使用控制器和控制器操作的逻辑分组。但这完全是另一篇文章的主题,以及 MVC 可能被滥用的方式。
但撇开这一切不谈,我看到最滥用基本结构和模式的地方是 JavaScript。例如,假设你在部分视图中编写如下代码
<div>
Number 1 : <input type="text" id="Number1" /><br />
Number 2 : <input type="text" id="Number2" /><br />
<input type="button" id="btnAddNumbers" onclick="AddNumbers()" value="Add Numbers" />
</div>
现在,像任何优秀的开发人员一样,你将你的 JavaScript 代码放在一个名为 "Add.js" 的单独的 JS 文件中。它包含以下代码
function AddNumbers() {
var num1 = parseInt($("#Number1").val());
var num2 = parseInt($("#Number2").val());
var total = num1 + num2;
alert(total);
}
现在对我们大多数人来说,这看起来像是完美的 JavaScript 代码。这里没有什么特别的。当你要将它添加到页面时,你会在页面的 head
标签中添加对 JS 文件的引用。一切都很好,对吧?
不完全是……现在,上面的 JavaScript 代码正在所谓的全局命名空间中声明。这意味着代码正在页面级别声明,并且此函数中的所有内容都可用于整个页面。
问题是,当另一个开发人员编写具有以下 HTML 的部分视图时会发生什么
<div>
Number to increment:<input type="text" id="NumberValue" /><br />
<input type="button" id="btnAdd"
value="Increment Number" onclick="AddNumbers()" />
</div>
他们编写以下函数
function AddNumbers()
{
var num = parseInt($("#NumberValue").val());
num = num + 1;
$("#NumberValue").val(num);
}
他们在页面底部声明他们的 JS,认为它会在最后加载,并将他们的部分视图插入到与你的视图相同的视图中。问题是现在会发生什么?有两个函数以相同的名称声明。如果这是服务器端代码,我们将收到编译错误。
但是,考虑到这是 JavaScript,如果我在 "Number 1
" 文本框中输入 "1",在 "Number 2
" 文本框中输入 "2
",然后单击 "Add Numbers
" 按钮,我将在 "NumberValue
" 文本框中得到 "NaN
"。
现在这是为什么?因为当浏览器加载页面时,它是从上到下加载的,这意味着它用执行递增的函数替换了 "AddNumbers
" 函数。这是因为 JavaScript 处理函数的方式与处理对象的方式非常相似。因此,通过在全局命名空间中声明它,你允许你的代码有可能被其他人替换。
你能做什么?老实说,最好的选择是限定你的 JavaScript 的范围,使其不位于全局命名空间中,并避免出现这种情况。你可以像处理对象一样处理函数,并按以下方式修改你的代码。
function CalcMath() {
var addNumbers = function ()
{
var num1 = parseInt($("#Number1").val());
var num2 = parseInt($("#Number2").val());
var total = num1 + num2;
alert(total);
}
return {
AddNumbers : addNumbers
}
}
这创建了一个名为 "CalcMath
" 的对象,以及该对象的一个名为 "AddNumbers
" 的“方法”。这允许我更新按钮以具有以下内容
<div>
Number 1 : <input type="text" id="Number1" /><br />
Number 2 : <input type="text" id="Number2" /><br />
<input type="button" id="btnAddNumbers" onclick="CalcMath().AddNumbers()" value="Add Numbers" />
</div>
现在,如果有人添加一个名为 "AddNumbers
" 的函数,它不会影响你的部分视图。这允许一切保持模块化和分离,并防止其他代码在将来影响你的代码。
许多 JavaScript 框架(Angular、Knockout 等)都基于这个原则,并将其用作它们提供的其他好处的基础。
这就是目前的情况,更多关于演示文稿的信息,更具体地说,更多关于创业公司资源的信息,以及关于从我当前创业工作中吸取的教训的文章。