JS实例教程:当心JavaScript代码陷阱

2016-02-20 01:10 3 1 收藏

下面请跟着图老师小编一起来了解下JS实例教程:当心JavaScript代码陷阱,精心挑选的内容希望大家喜欢,不要忘记点个赞哦!

【 tulaoshi.com - Web开发 】

下面这段代码,你知道有哪些错误吗:

var g_bar = "bar";function foo(container, config) {var container = container || document,name = config.name || "无名氏",isLive = config.isLive || true;var g_bar = g_bar || "";if(g_foo) {/* your code */}}foo(document, {isLive: false});

请仔细思考后再往下阅读。

- 帮助你思考的刷屏线 开始 -

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/webkaifa/)

- 帮助你思考的刷屏线 结束 -

1. isLive = config.isLive || true, 当传入的值有可能就是0, undefined, null, false, "", NaN这六个 falsy 值时,用 || 来设定默认值不妥当。更保险的做法是:

isLive = "isLive" in config ? config.isLive : true;

如果是独立变量,可以采用:

someVar = typeof someVar !== "undefined" ? someVar : defaultValue;

注意:大部分情况下,用 || 已经够用,比如:

container = container || documentname = config.name || "无名氏"

一切皆权衡。

2. var g_bar = g_bar || "", 原意是取全局变量 g_bar 的值给内部变量 g_bar, 默认为空字符串。然而,实际情况等价为:

var g_bar;g_bar = g_bar || "";

很明显,|| 号左边的 g_bar 也是内部变量,并且为 undefined, 因此var g_bar = g_bar || ""实际上是var g_bar = "", 没有满足代码的原始意图。

思考:代码中的var container = container || document有无问题?为什么?

3. if(g_foo) { /* code */ }, 这段代码在执行时会报错。我们都知道在 JS 里,变量不定义就可以用。但一定要清楚,未定义的变量,仅仅是可写,但不可读。比如:

g_foo = 2; // 等价 window.g_foo = 2var t = g_foo2; // 不等价为 var t = window.g_foo2, 会报错

具体原因可以参见 JavaScript 运行机制浅探:

未定义变量意味着在 scriptObject 的变量表中找不到,JS 引擎会沿着 scriptObject 的 upvalue 往上寻找,如果都没找到,对于写操作 i = 1; 最后就会等价为 window.i = 1; 给 window 对象新增了一个属性。对于读操作,如果一直追溯到全局执行环境的 scriptObject 上都找不到,就会产生运行期错误。

因此严谨的写法是:

if(window.g_foo) {/* your code */}

不要小看这些细微之处,有时会让人抓狂的。但这些细微之处又很容易被忽略或滥用。比如 YUI 2.8r4 里,有一个遗传了很久的 bug:

var NOTHING = [];// ....later: function(when, o, fn, data, periodic) {when = when || 0;o = o || {};var m = fn, d = data, f, r;// ...if (d && !L.isArray(d)) {d = [data];}f = function() {m.apply(o, d || NOTHING);};// ...}

当你的调用代码类似Lang.later(delay[0], o, "show", index)时,如果 index 不幸是 base-0 的,那么取 0 时,m.apply(o, d || NOTHING)会让你得到惊喜。更妥的做法是类似 YUI3 中的修正:

// ...if (!L.isArray(d)) {d = [data];}?f = function() {m.apply(o, d);};//...

对于 || 和 && 的用法,很多 JS 书籍(无论中外),都用来片面强调 JS 的灵活性,包括 Douglas 的《JavaScript The Good Parts》中也存在误导。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/webkaifa/)

最后,有感于 NCZ 今天写的 Writing Maintainable Code, 再举一例(和本文主题关系不明显,但的确又有关系,交给你去思考啰):

var isBoy = true;isBoy = typeof isGirl !== "undefined" ? !isGirl : true;

或者来个耍酷的代码:

var isBoy = true;(typeof isGirl !== "undefined") && (isBoy =  !isGirl);

然而,以上两种写法,无论从代码长度还是性能上讲,都不如更直白的写法:

var isBoy = true;if(typeof isGirl !== "undefined") isBoy =  !isGirl;

简单质朴,往往是最好的。

来源:https://www.tulaoshi.com/n/20160220/1633423.html

延伸阅读
标签: Web开发
使用JavaScript中的OLE Automation 7. 怎样处理集对象 Automation对象与其它的Jscript对象有些有相同的结构。它暴露了多种方法和属性,我们可以对它们进行处理。如果你从来没有接触Visual Basic,你可能就不熟悉集对象了。集就是相关项的组。集用在Visual Basic主要是为了保持跟踪许多事情,比如从你的程序(表单集)中装载表单,或者表单(...
标签: Web开发
好吧,现在让我们来测试一下这个宏。请在HotTMetaL中打开一个文档并将视图切换到源程序视图。你可以在ProgGuide目录中选择其中一段。并且通过使用Tools(工具)-Customization(定制)关闭Enable Source Layout按钮。接着将其中一行用加入空格往右移,再从工具菜单中调用宏对话框。这时会展现出定义在HotMetaL.mcr文件的宏的列表。然后运行Refr...
标签: Web开发
使用JavaScript的字符串函数 字符串对象提供了许多方法,但是很少的程序设计人员充分利用它们,这对于一个程序员来说,不能不说这是一种缺陷。字符串提供的方法可以用于操作字符、产生HTML标签以及搜索字符串等等。 下面首先说说什么是字符串。在JavaScript语言中,字符串就是一种对象。就象在Java中,它们不是作为一系列的字符被存储的,所...
标签: Web开发
使用JavaScript数组 在JavaScript 1.0中构造器只存在Date对象和用户定义的对象。你可能期望有个数组构造器,但是一直没能实现,直到JavaScript 1.1的出现,你的期望成为了现实。我们可以如下来定义用户对象: function blankArray(n) { for (var i=0; i n; i++) this[i] = null; this.length = n; } blankArray函数创建了一个数组,这...
标签: Web开发
Date(日期)对象可以使用Date()构造器来创建,在前面的教程中我们已经介绍了Date()构造器,这里就不重复叙述。它没有参数,返回的数值就是当前的日期。下面的表格显示了为日期构造器的有效输入: var today = new Date(); 返回当前的日期和时间 var newyear = new Date("December 31, 1998 23:59:59"); 输入的是表单的字符串 “月 日,...

经验教程

672

收藏

13
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部