【问题标题】:Why am I finding Javascript/jQuery so difficult to get right?为什么我发现 Javascript/jQuery 如此难以正确?
【发布时间】:2010-08-03 15:44:44
【问题描述】:

我的背景是 C 语言,我已经学会了 PHP、mySQL、HTML、CSS,没有太多问题。

但我发现 Javascript/jQuery 出奇地难以正确处理。 非常令人沮丧。 为什么?

  1. 它似乎违反了许多传统的编程原则(例如变量作用域)

  2. 未定义的变量似乎无处不在,并且已经具有与之关联的值。例如(来自 jQuery 文档):

    $("a").click(function(event) {
        event.preventDefault();
        $('<div/>')
              .append('default ' + event.type + ' prevented')
              .appendTo('#log');
    });
    

    究竟什么是“事件”?我必须使用这个变量名吗?我是否应该假设这个对象是用正确的东西神奇地实例化的,我可以使用JQuery API 中的任何方法列表?

  3. 似乎有一堆随机规则(例如,返回 false 以停止默认操作,但有时这不起作用?)

  4. 调试时的不确定行为。 (例如,我刷新浏览器,尝试一些东西并为我在 Firebug 中观看的 JS 变量获取结果 X。我再次刷新并得到结果 Y?)

  5. 看起来非常凌乱的代码,难以理解。什么时候发生?我正在使用 Firebug 和 Chrome 开发者工具,但我的知名度不够。

似乎每天都有一些随机的 JS “规则”出现,这是我在我的任何 JS 书籍或教程中从未见过的。

我需要做什么才能使 Javascript/jQuery 对我来说更具确定性、可控性和逻辑性?

是否有任何资源可以解释 Javascript 的怪癖/陷阱?

谢谢!

【问题讨论】:

  • 是的,JS 是个善变的情妇。但是您忘记了“6) 跨浏览器平台的工作方式不同。”
  • 你忘记了“可选”分号 :)
  • 请提供#2、#4 和#5 的示例。当心克罗克福德。
  • 你可以用任何编程语言编写杂乱无章的代码。这是程序员的错,而不是语言。
  • @Felix 你用过 JavaScript 吗?在 JavaScript 中编写不混乱的代码是一项严峻的挑战。这是语言。

标签: javascript jquery


【解决方案1】:

1) 它似乎违反了许多传统的编程原则(例如变量作用域)

你需要使用var声明变量,否则它会进入全局范围。

2) 未定义的变量似乎突然出现并且已经有与之关联的值(这是怎么发生的?)

这可能与 1) 和/或 4) 有关。

3) 似乎有一堆随机规则(例如,返回 false 以停止默认操作,但有时这不起作用?)

您还需要让处理程序返回 false。例如。 form onsubmit="return functionname()"。您还需要从“主”函数返回,而不仅仅是从闭包(函数内部的函数)返回,参考您的previous question。它只会返回“main”函数并继续。

4) 调试时的非确定性行为。 (例如,我刷新浏览器,尝试一些东西并为我在 Firebug 中观看的 JS 变量获取结果 X。我再次刷新并得到结果 Y?)

可能代码是在 HTML DOM 完成填充之前执行的。每当您想在页面加载期间执行某些内容时,您都需要挂钩 window.onload$(document).ready()

5) 看起来非常凌乱的代码,难以理解。什么时候发生?我正在使用 Firebug 和 Chrome 开发者工具,但没有获得足够的可见性。

我敢打赌,您说的是 jQuery 源代码?这只是一个大图书馆。毕竟你在调试时不应该担心这个。而是担心自己的代码。但是,请确保您正在查看 jQuery 源代码的未缩小版本。


另见:

【讨论】:

  • 在 1)。他仍然有块范围的“问题”(或没有)
【解决方案2】:

Douglas Crockford 的“Javascript: The Good Parts”是非常宝贵的资源。与 C 相比,Javascript 更像 Lua、Lisp 或 Python,只是碰巧看起来像 C。

提供给亚马逊的链接;我从 O'Reilly 那里抢到了我的。

【讨论】:

  • 那个亚马逊链接,“rads.stackoverflow.com/amzn/click/0596517742”。你在那里做什么?
  • @Crescent 我认为 SO 会自动将亚马逊链接转换为他们的参考。代码。对他们有好处。
  • The Good Parts 是一本优秀的语言参考书,值得推荐。它不涵盖浏览器,仅涵盖核心语言。
【解决方案3】:

老实说,我认为你有一个很好的理解。我的一些挂断是相似的。我一直在前进的方式是“好吧,如果是这样,那就是这样”。只是接受特质并继续前进。 PHP 做了一些相同的事情(变量可以突然出现,等等......)。只需按照您想要的编码方式进行编码,如果它有效,那就太好了!

然后在你达到那个点之后开始分解分析器,看看是否有什么可以优化的。

这里有几件事:

如果您了解 CSS,那么 jQuery 选择器应该很简单。就代码而言,如果您可以处理 chaining 和 JSON,那也很简单。 编辑:另外,jQuery documentation 上的一切都非常好!而且这里不乏 jQuery 专家来帮助我们的菜鸟(希望我们可以回报新菜鸟的青睐)。

有一个工作范围。 (基本上)在函数或对象之外编写的任何内容都在全局范围内。如果您在对象或函数内部并使用var,则设置变量的范围

Javascript 不像基于 C 的语言(甚至 C++ 或 PHP)。它使用原型来处理类/对象关系,而不是子类化方案。

让我陷入循环的第一件事是,任何出现在页面上任何位置或包含在&lt;script&gt; 标签中的 JS 都是公平的游戏。如果你在一个脚本中有一个全局变量,你可以在一个完全不同的脚本中使用同一个变量,它会起作用。这可能就是你所说的变量突然出现的意思。此外,还有一些基于 DOM 的变量也可以“显示”。

不管怎样,我认为如果你继续前进,你会得到一些“啊哈”的时刻。我是编程的相对菜鸟,但只要我不挂断对实际运行代码没有太大影响的事情,我就会不断成长。

【讨论】:

    【解决方案4】:
    1. 它是一种基于原型继承的语言,受函数式编程语言和范式的影响,因此它不像其他语言那样完全只是 OO/Procedural。变量是隐含的全局变量,除非用 var 声明。

    2. 请举个例子?

    3. return false 与任何语言的 return 语句一样退出函数。 preventDefault() 将是取消链接默认行为的 DOM 方法

    4. Javascript 主要用于客户端。由于有很多用户代理,它们每个都有不同的 DOM 实现,这非常不一致,比 JS 本身更不一致。再次,请附上一个真实的例子以获得明确的答案。

    5. 您会发现任何语言的代码看起来都很杂乱,也许您缺乏理解会认为代码很杂乱,但实际上并没有那么糟糕。或者,也许您正在查看一些缩小/混淆的代码。

    我推荐 http://eloquentjavascript.net/ 学习 Javascript。

    您将从上面的链接中学到的东西

    • lambdas
    • 关闭
    • 原型继承
    • 基于事件的编程
    • 调试
    • DOM

    【讨论】:

      【解决方案5】:

      Douglas Crockford 的“JavaScript: The Good Parts”是一个好的开始

      在你的例子中,附录(“坏的部分”和“糟糕的部分”)可能是最有趣的 :)

      【讨论】:

        【解决方案6】:

        Crockford 的“Javascript: The Good Parts”提供了一些有助于变量私有化和范围界定的常见 JS 模式。这通常适用于javascript。对于 jQuery,我只使用 API。此外,JavaScript 上的 Yui Theatre 视频也相当不错

        【讨论】:

          【解决方案7】:

          Javascript 可能有点棘手,而且它的某些功能方面会让人们感到困惑。如果你真的学习并理解了这门语言,你会发现它真的很有用,大多数人只是随机开始使用它,然后就讨厌了。

          阅读 crockford 的 javascript 的优秀部分,真的很有帮助:http://javascript.crockford.com/

          还要确保您了解closure。这是人们没有得到但经常使用的基本原理。

          【讨论】:

            【解决方案8】:

            就变量作用域而言,有局部变量和全局变量。在这个例子中可以看到变量范围的一个问题:

            var thisIsAGlobalVariable
            function anon () { 
               var thisIsALocalVariable
               thisIsAGlobalVariable = 5; //if you don't use the var prefix inside a fn, it becomes global
            }
            

            【讨论】:

            • 具有讽刺意味的是,这个问题对我来说似乎很直观。
            • 对我来说似乎很棘手的部分是,您可以通过省略 var 前缀在函数内部创建一个全局变量。如果我弄错了,请告诉我
            【解决方案9】:

            你觉得这很困难,因为:

            • javascript 有另一种语法。
            • javascript 难以调试
            • javascript 没有像 c# 等那样的自动完成功能?或者是这样
            • javascript 有不合逻辑的规则(一旦你知道它们就会变得合乎逻辑)
            • 任何事情都可以通过 1000 种方式完成,当您搜索解决方案时,您会找到 2000 个答案 :) 其中 c#、php 大多具有您“应该/可以”使用的良好实践功能

            然而,我半年前开始使用 js/jquery,和你一样的理由,我坚持使用它,现在我每天都使用它来增强我的 webapps。

            我就是喜欢它(尤其是 jquery)。它是一个救生员,我知道该看什么和在哪里看,我可以用它做任何事情。

            一切似乎都合乎逻辑。

            如果我能给你一个建议:javascript/jquery 是一个酸苹果,但坚持下去,有点低谷,你不会后悔的。

            另外,有很多人使用它,如果需要,总是愿意伸出援手(我知道我愿意)

            【讨论】:

            • IntelliSense(又名“AutoCompletion”)是 IDE 的属性,而不是语言。我会强烈质疑您关于 JS 不合逻辑的说法,它与任何语言一样合乎逻辑(即,如果不是,那是程序员的错),并且 PHP 具有比 JS 更好的实现路径的想法是......好吧......只是没有。
            • IntelliSense 确实是一个属性,我指的是 IDE,因为大多数语言都有很好的 ide 支持,据我所知,js 较少。对于不合逻辑的部分,我可能表达错了,语言不是不合逻辑的,但我总觉得你的限制比使用 php 或 C# 时要少得多,它们感觉更加封装在它们的层中(但是好的 javascript 实际上只有1 层)。
            【解决方案10】:

            Javascript 很棘手。你没有一个编译器在看着你。作为补偿,单元测试变得更加重要。我一直在使用 jQuery/QUnit 进行单元测试,但我最近开始使用 Jasmine (http://github.com/pivotal/jasmine),我推荐它 200%。它是一个很棒的测试框架。

            如果您不熟悉测试或使用 javascript 进行测试,我强烈建议您为其他 OSS javascript 项目(希望您可以使用的代码)寻找单元测试并查看他们如何测试它。

            使用单元测试,您会犯同样的错误,但可以更快地发现它们,并且减少痛苦。如果你的测试是好的,那么在你修复它之后错误就不会再出现了。

            【讨论】:

              【解决方案11】:

              我不知道你在 C 中做了多少 UI 设计,但事件变量只有在调用者发送它并且处理程序需要处理对象时才会显示。如果您阅读事件对象,那么问题 #2 中的混乱应该会消失。

              PHP 中没有事件处理,所以我认为您过去没有遇到过这个问题。 JavaScript 是一种有其自身目的的编程语言,因此它旨在为特定目的而工作。

              【讨论】:

                【解决方案12】:

                也许您必须将代码链接到 HTML onclick="event()" 按钮才能作为事件触发。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-11-10
                  • 1970-01-01
                  • 2010-11-30
                  • 2021-12-14
                  • 2020-03-23
                  • 1970-01-01
                  相关资源
                  最近更新 更多