{"id":56,"date":"2013-07-27T21:36:21","date_gmt":"2013-07-27T13:36:21","guid":{"rendered":"http:\/\/ufqi.com\/blog\/?p=56"},"modified":"2014-10-30T14:23:19","modified_gmt":"2014-10-30T06:23:19","slug":"javascript-tidbits","status":"publish","type":"post","link":"https:\/\/ufqi.com\/blog\/javascript-tidbits\/","title":{"rendered":"JavaScript tidbits"},"content":{"rendered":"<div>\u5982\u4e0b\u662f\u4eceGoogle JavaScript Style Guide\u91cc\u6458\u5f55\u7684\uff0c\u611f\u5174\u8da3\u7684\u540c\u5b66\u53ef\u4ee5\u7ffb\u8bd1\u4e00\u4e0b\u3002<\/div>\n<div><\/div>\n<div><strong><span style=\"font-size: 16px;\">True and False Boolean Expressions<\/span><\/strong><\/div>\n<div>\n<div id=\"Tips_and_Tricks__body\">\n<p>The following are all false in boolean expressions:<\/p>\n<ul>\n<li><code>null<\/code><\/li>\n<li><code>undefined<\/code><\/li>\n<li><code>''<\/code>\u00a0the empty string<\/li>\n<li><code>0<\/code>\u00a0the number<\/li>\n<\/ul>\n<p>But be careful, because these are all true:<\/p>\n<ul>\n<li><code>'0'<\/code>\u00a0the string<\/li>\n<li><code>[]<\/code>\u00a0the empty array<\/li>\n<li><code>{}<\/code>\u00a0the empty object<\/li>\n<\/ul>\n<p>This means that instead of this:<\/p>\n<div>\n<pre>while (x != null) {<\/pre>\n<\/div>\n<p>you can write this shorter code (as long as you don&#8217;t expect x to be 0, or the empty string, or false):<\/p>\n<div>\n<pre>while (x) {<\/pre>\n<\/div>\n<p>And if you want to check a string to see if it is null or empty, you could do this:<\/p>\n<div>\n<pre>if (y != null &amp;&amp; y != '') {<\/pre>\n<\/div>\n<p>But this is shorter and nicer:<\/p>\n<div>\n<pre>if (y) {<\/pre>\n<\/div>\n<p>Caution: There are many unintuitive things about boolean expressions. Here are some of them:<\/p>\n<ul>\n<li><code>Boolean('0') == true<br \/>\n'0' != true<\/code><\/li>\n<li><code>0 != null<br \/>\n0 == []<br \/>\n0 == false<\/code><\/li>\n<li><code>Boolean(null) == false<br \/>\nnull != true<br \/>\nnull != false<\/code><\/li>\n<li><code>Boolean(undefined) == false<br \/>\nundefined != true<br \/>\nundefined != false<\/code><\/li>\n<li><code>Boolean([]) == true<br \/>\n[] != true<br \/>\n[] == false<\/code><\/li>\n<li><code>Boolean({}) == true<br \/>\n{} != true<br \/>\n{} != false<\/code><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>Conditional (Ternary) Operator (?:)<\/strong><\/p>\n<p>Instead of this:<\/p>\n<div>\n<pre>if (val != 0) {\r\n  return foo();\r\n} else {\r\n  return bar();\r\n}<\/pre>\n<\/div>\n<p>you can write this:<\/p>\n<div>\n<pre>return val ? foo() : bar();<\/pre>\n<\/div>\n<p>The ternary conditional is also useful when generating HTML:<\/p>\n<div>\n<pre>var html = '&lt;input type=\"checkbox\"' +\r\n    (isChecked ? ' checked' : '') +\r\n    (isEnabled ? '' : ' disabled') +\r\n    ' name=\"foo\"&gt;';<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><strong>&amp;&amp; and ||<\/strong><\/p>\n<p>These binary boolean operators are short-circuited, and evaluate to the last evaluated term.<\/p>\n<p>&#8220;||&#8221; has been called the &#8216;default&#8217; operator, because instead of writing this:<\/p>\n<div>\n<pre>\/** @param {*=} opt_win *\/\r\nfunction foo(opt_win) {\r\n  var win;\r\n  if (opt_win) {\r\n    win = opt_win;\r\n  } else {\r\n    win = window;\r\n  }\r\n  \/\/ ...\r\n}<\/pre>\n<\/div>\n<p>you can write this:<\/p>\n<div>\n<pre>\/** @param {*=} opt_win *\/\r\nfunction foo(opt_win) {\r\n  var win = opt_win || window;\r\n  \/\/ ...\r\n}<\/pre>\n<\/div>\n<p>&#8220;&amp;&amp;&#8221; is also useful for shortening code. For instance, instead of this:<\/p>\n<div>\n<pre>if (node) {\r\n  if (node.kids) {\r\n    if (node.kids[index]) {\r\n      foo(node.kids[index]);\r\n    }\r\n  }\r\n}<\/pre>\n<\/div>\n<p>you could do this:<\/p>\n<div>\n<pre>if (node &amp;&amp; node.kids &amp;&amp; node.kids[index]) {\r\n  foo(node.kids[index]);\r\n}<\/pre>\n<\/div>\n<p>or this:<\/p>\n<div>\n<pre>var kid = node &amp;&amp; node.kids &amp;&amp; node.kids[index];\r\nif (kid) {\r\n  foo(kid);\r\n}<\/pre>\n<\/div>\n<p>However, this is going a little too far:<\/p>\n<div>\n<pre>node &amp;&amp; node.kids &amp;&amp; node.kids[index] &amp;&amp; foo(node.kids[index]);<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><strong>Iterating over Node Lists<\/strong><\/p>\n<p>Node lists are often implemented as node iterators with a filter. This means that getting a property like length is O(n), and iterating over the list by re-checking the length will be O(n^2).<\/p>\n<div>\n<pre>var paragraphs = document.getElementsByTagName('p');\r\nfor (var i = 0; i &lt; paragraphs.length; i++) {\r\n  doSomething(paragraphs[i]);\r\n}<\/pre>\n<\/div>\n<p>It is better to do this instead:<\/p>\n<div>\n<pre>var paragraphs = document.getElementsByTagName('p');\r\nfor (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {\r\n  doSomething(paragraph);\r\n}<\/pre>\n<\/div>\n<p>This works well for all collections and arrays as long as the array does not contain things that are treated as boolean false.<\/p>\n<p>In cases where you are iterating over the childNodes you can also use the firstChild and nextSibling properties.<\/p>\n<div>\n<pre>var parentNode = document.getElementById('foo');\r\nfor (var child = parentNode.firstChild; child; child = child.nextSibling) {\r\n  doSomething(child);\r\n}<\/pre>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u5982\u4e0b\u662f\u4eceGoogle JavaScript Style Guide\u91cc\u6458\u5f55\u7684\uff0c\u611f\u5174 &hellip; <a href=\"https:\/\/ufqi.com\/blog\/javascript-tidbits\/\">\u7ee7\u7eed\u9605\u8bfb <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,2],"tags":[],"_links":{"self":[{"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/posts\/56"}],"collection":[{"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/comments?post=56"}],"version-history":[{"count":3,"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/posts\/56\/revisions"}],"predecessor-version":[{"id":702,"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/posts\/56\/revisions\/702"}],"wp:attachment":[{"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/media?parent=56"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/categories?post=56"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ufqi.com\/blog\/wp-json\/wp\/v2\/tags?post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}