请注意,我将所有论据都基于实际用例。不能用真实,完整,有趣,有用的应用程序中的使用示例备份的反参数无效。我看过其他所有人都有的“语言演示”,也看过博客文章,详细介绍了原型和动态类型如何使一些琐碎的小例子比C#短几行,但是这些根本不相关您遇到的问题是编写真实
代码,而不是微型演示和玩具。所以这是我对JS的理解:
a)魔术“ this”。就是这样,除非是那样。JavaScript促使您在各处使用匿名函数,除非它们总是最终会丢失'this'变量的正确上下文,因此您最终会在各处使用诸如“ var _this = this”这样的愚蠢代码,然后再使用它在您的回调或其他函数中。有时候,我发誓我设法编写的不使用重命名的“ this”的函数的数量实际上少于使用的函数的数量。
b)1 +“ 1”-1 =10。此外,“ 1” + 0 =“ 10”。是的,这实际上对我们的应用程序造成了错误,由于另一个应用程序中的错误,本来应该是数字的数据从JSON文件作为字符串加载了,结果并不理想。我们所有的加载代码都必须进行更新,以在整个地方添加大量类型转换。当我需要某些东西作为数字时,我真的非常想让它成为数字,而不是字符串或对象或null或其他任何东西。Lua在大多数方面与JavaScript非常相似,它只是由于没有足够的延迟才能使用相同的运算符进行加法和字符串连接而解决了该问题。
c)默认情况下为全局变量。因此,即使您认为动态类型化只是“更轻松”,因为您不必考虑变量声明,JavaScript还是通过在整个位置将“ var”放在新标识符的前面,从而将该参数抛出了窗外。 。然后,如果您忘记了,它会默默地将您拧紧。
d)原型而不是类。很少有大型的现实世界JavaScript应用程序不插入自己的类系统来解决大型应用程序体系结构中原型固有的无用性。那些相同的应用程序很少使用原型来扩展基本的JavaScript类型,这仅仅是因为JS的设计如此糟糕,以至于它附带的两个有趣的内置类型都缺少您期望它们具有的一半功能。
e)无法创建按值传递类型。实际上,除了C ++ / D之外,几乎所有语言都经常出现此问题。对于那些使用JavaScript编写WebGL应用程序的人,请查看所有用于JavaScript的线性代数库。在3D应用程序中,向量几乎比标量更经常使用。想象一下,如果应用程序中的每个整数都是通过引用传递的,那么“ a = 1; b = a; b ++”使a和b都等于2。每三个成分向量都是一个完整的完整对象。它们是通过引用传递的(实际上,到目前为止,我们的WebGL游戏中几乎有一半的错误源)。它们大量存在,被堆分配并被垃圾回收,这给GC带来了巨大压力,即使在简单的WebGL游戏中,GC也会造成GC暂停,除非开发人员跳过非常复杂的圈,以避免在逻辑上创建新矢量的所有地方创建新矢量。您不能有运算符重载,因此您有非常大而丑陋的表达式来执行基本操作。访问单个组件很慢。这些对象不是本机打包的,因此将其压入顶点缓冲区的速度非常之慢,除非您将它们实现为Float32Array实例,否则会使当前V8和SpiderMonkey的优化器中的废话弄混。我是否提到它们已通过引用传递?访问单个组件很慢。这些对象不是本机打包的,因此将其压入顶点缓冲区的速度非常之慢,除非您将它们实现为Float32Array实例,否则会使当前V8和SpiderMonkey的优化器中的废话弄混。我是否提到它们已通过引用传递?访问单个组件很慢。这些对象不是本机打包的,因此将其压入顶点缓冲区的速度非常之慢,除非您将它们实现为Float32Array实例,否则会使当前V8和SpiderMonkey的优化器中的废话弄混。我是否提到它们已通过引用传递?
f)没有内置的包含或不需要功能。认真地,仍然。存在第三方库,但几乎所有第三方库都存在某种或多种错误,至少在Chrome中,这是一个令人困惑的缓存问题,这使得进行实际开发变得更加困难。
g)动态打字。是的,我愿意提出这一论点。您会在停止编写小型Web应用程序或网页并开始编写大型应用程序的那一刻开始注意到它,而实际上您的数据的持久性要比单击一次鼠标或请求/响应周期长:将错误的对象类型添加到数组,以便稍后处理,并通过与实际错误所在完全不同的代码段中的丢失方法或成员而导致崩溃。娱乐时间。是的,Java使静态类型看起来很邪恶。不,Java / C#/ C ++不是唯一的静态类型输入方法。类型推断,隐式接口绑定等为您提供了动态类型化的所有“易于处理且无需击键”的优点,而没有所有错误。实际上,第二流行的Web语言(ActionScript 3)是静态类型的,尽管与JS / ECMAScript相同。顺便说一句,我从Fedora桌面上的Python应用程序崩溃比从C / C ++应用程序得到的崩溃更多(实际上,考虑到现在,我的桌面崩溃的C / C ++应用程序都没有)。缺少成员例外==如此容易开发和维护应用程序,对吗?
h)速度。是的,大量超级坏蛋开发人员在语言运行时中付出了可笑的巨大努力,以使JS的速度几乎是一个大学三年级学生可以在少数几种语言中编写的低级C编译器的一半。几个月。而且,就基本语言限制而言,LuaJIT与JS在同一条船上,但是无论如何,它都比每个JavaScript实现都做得更好。不了解V8中的所有JS优化实际上是做什么的人就像声称JS可以在速度方面做得很棒,但是事实是,所有这些优化基本上只是“非常努力地分析代码以找出变量的类型,然后像稍微延迟的静态类型一样对其进行编译。语言的编译器会做到这一点。” 哦,这里有跟踪,但是跟踪也适用于静态类型的语言(由于生成的机器代码中不需要类型保护,因此跟踪效果更好)。实际上,JS并没有为JS发明过任何一种whizbang优化。大多数都来自研究型JVM(Java是邪恶的!)或经典的OOP语言(原型很棒!)。
i)甚至没有IntelliSense。是否想查看您在文本编辑器中foo.js的第187行上存在的变量上存在哪些方法?太糟糕了。遍历代码,直到弄清楚它的初始化位置,然后遍历代码以查找其原型所具有的内容。然后希望没有代码可以动态地改变背后的原型。实际上,只需在浏览器中运行它并设置断点,因为对于任何比JavaScript辩护者用来美化JavaScript的易用性的toy_web_app.html网站更大的代码库,基本上都不可能以其他任何方式找到有关该值的任何有用信息。一些代码编辑器确实努力地做得更好,并且在真正简单的情况下有时甚至几乎是一次成功。
j)没有优势。与其他动态类型的语言相比,JavaScript甚至都不是特别的。它根本无法执行Lua,Python,Ruby等也无法完成的任何有趣的事情。所有JS实现都不比LuaJIT或PyPy或其他动态的其他高级JIT-ing实现快语言。与其他常用语言相比,JS没有优势。哦,除了它在没有插件的Web浏览器中本机运行。这是世界上如此受欢迎的唯一原因。实际上,这是事件发生的唯一原因存在。如果10年前的某个人只是想:“哎呀,让我们在浏览器中放一个已有的设计良好和完善的语言,让其他人也去做,而不是让每个人都使用NetScape提出的这个愚蠢的小技巧。 ”,今天的网络看起来将有很大的不同(更好)。试想一下,如果Chrome将Python作为受支持的语言放到Chrome中,那么未来将会如何。或实际上,可以想象一下:Google将C / C ++作为受支持的语言放到Chrome中(http://code.google.com/p/nativeclient/)。