表示最近在学JS, 相对个人以前学的Python, JAVA之类的语言, JS的语言确实有一些”奇葩”. 把初学时的一些语法错误记录下来,方便自己以后查阅, 如果能帮助到读这篇文章的你自然就更好了.
number 与 string 相加/减/乘/除
Example 1:
1 | var a = "5" + 2; // the result is "52" |
在 number 与 string 相加时, number 会被转化为 string, 然后这两个字符串会根据前后顺序做拼接. 这一点上, 有点类似与 JAVA 中的System.out.println(2 + "5");
, 数字遇到加号时会变为字符串,让后做拼接运算.
Example 2:
1 | var a = "5" + 2 + 2; // the result is "522" |
如果在 string 前有 number 的运算, 那么 number 仍然会进行正常的 number 之前的运算,直到遇到 string, number 才会 被转为 string.
反过来, 如果在 number 前线遇到了 string, 那么后续的每一个 number 都会被当作 string 进行运算.
如果对 JAVA 熟悉一点, 这一点也还好理解, 这跟JAVA中System.out.println(2 + 2 + "5");
和System.out.println("5" + 2 + 2);
的结果也是一样的.
Example 3:
1 | var x = "5" - 2; // the result is 3 |
比起加法, 减/乘/除 相对更简单一点,只要 string 能转化为 number, 那么 string 就会转化为 numner 进行运算.
Undefined 不是 Null
在 JS 中, null 更多是针对 objects 而言的, 而 undefined 则更多是针对 variables, properties, methods 而言的.
要变成null, 一个 object 首先要被定义, 否则只能变成 undefined.
因此 如果要判断一个 object 是否存在(不为空 且 已被定义),那么以下发发是错的:
1 | if (myObj !== null && typeof myObj !== "undefined") |
这样的结果则是 Uncaught ReferenceError: myObj is not defined(…)
所以 要判断是否为 null 前必须要判断是否 已被定义, 所以调换以下判断顺序就可以解决上面的问题了:
1 | if (typeof myObj !== "undefined" && myObj !== null) |
只有 myObj 被定义了 且 不为 null 时, 上述判断语句才能被盘为 true, 否则均为 false.
向Array添加元素的方式
如果已知一个数组arr = [1, 2, 3]
, 那么向它的末尾添加元素的方式至少有以下三种:
Example:
1 | arr[3] = 4; // 方法1 |
虽然这三种都可以完成预期目标,但极不推荐方法1,原因是用数字索引很容易产生不期望的错误,仍旧以arr = [1, 2, 3]
为例。假设 我不小心写成了arr[4] = 4
会怎样呢?实际结果是arr
会变成:
1 | [1, 2, 3, undefined, 4] |
可以看出,JS在此时会自动填充undefined。所以为了避免这种情况的发生,强烈建议采用方法2和方法3向数组末尾添加元素.
断开的 return 语句
Example:
1 | function myFun() { |
猜猜调用 myFun() 时, 它会返回什么 ? 经测试正解是 undefined .
原因是 JS 是这样解释的:
1 | function myFun() { |
JS 会在那一行的末尾自动补上一个分号以示结束. 所以结果自然是 undefined.
Switch 的严格比较
先看例子:
1 | var x = 10; |
在这个例子中, 网页跳出的弹窗中会显示那条信息呢?经测试, 是后一条(“run in default”),而不是前一条(“run in case”).
原因很简单, 10 === "10"
是 false. 所以 不能进入第一个case, 最终会进入到 default 中.
精度的损失
不管是什么语言, 浮点数的精度损失不可避免,有的损失比较小, 可以不用太在意,而有的损失可能就比较大,需要额外的注意.
Example:
1 | var x = 0.1; |
我经过实际运行可以发现 z 的 值其实是 0.30000000000000004 . 跟期望的有点出入. 所以在实际运行网页上不会有弹窗出现.
就算是写成 var z = 0.1 + 0.2;
也只是换汤不换药.
除非直接写成 var z = 0.3
如果需要要到x, y变量是可以考虑这么写:
1 | var z = (x * 10 + y * 10) / 10; // z will be 0.3 |
object 之间不能比较
Example:
1 | var x = new String("John"); |
从中也可以看出,对于 string, 极不建议用构造对象的方式声明.
script 放在head 中还是 body 中
理论上讲,把JS放在哪都可以运行,但最近我个人在学习过程中就遇到了一个因放置位置而引起的问题。
就我个人编写的下面这个例子来说
1 |
|
如果是写在1处,那么结果是窗口弹出 null,但如果是2处,则正确取到了对象。google之后的结果是:放在 head 和 body 处各有千秋,不能一概而论。但至少如果是放在body里的话,能使 html 的加载在 js 前,相对而言,能使 html 免于因 js 加载受阻而造成影响。所以,在这里只能是先提个醒了,如果放在 head 中运行异常的话,可以试试放在 body 处。
a标签的文本如何不做跳转
少数时候不希望被 a 标签包围的文本被点击后做跳转, 只希望停留在当前页面, 也不是重新载入至当前页面.
此时需要在 a 标签的 href 属性里如下写:
1 | <a href="javascript:;">Text</a> |
删除元素应由其父级进行操作
在进行DOM操作时,如果要删除某一元素,如:
1 | <html> |
要删除 id 为 target 的 li 标签,那么应由其父级对他删除, 而获取其父级则可以通过调用其 parentNode 属性:
1 | var target = document.getElementById('target'); |
而以下是我初学是犯的低级错误:
1 | var target = document.getElementById('target'); |
参考资料 : w3schoold