代码改变世界

JavaScript学习笔记之应用技巧(转载)

2010-02-25 23:05  爱研究源码的javaer  阅读(321)  评论(0编辑  收藏  举报
  1. 闭包(closure)
    闭包指的是函数内的局部变量,当函数返回时此变量依然可用。
    当你在函数内部定义另外一个函数时,你就创建了一个闭包,一个著名的例子:

    1 function add(i) {   
    2     return function() {   
    3         return ++i;   
    4     };   
    5 }   
    6 add(2).toString(); // "function () { return ++i; }"   
    7 add(2)(); // 3
    add(2)是一个函数,它可能获取外部函数的局部变量i
    参考文章


  2. 私有变量
    我们经常使用命名规范来标示一个变量是否为私有变量(最常用来标示):
    1 var person = {   
    2     _name: '',   
    3     getName: function() {   
    4         return this._name || 'not defined';   
    5     }   
    6 };   
    7 person.getName(); // "not defined"
    下划线前缀用来作为私有变量的约定,但是其他开发人员仍然可以调用此私有变量:
    1 person._name; // ""
    那么,如何在JavaScript中创建一个真正的私有变量呢?
    主要技巧是使用匿名函数(anonymous function)和闭包(closure)。
    01 var person = {};   
    02 (function() {   
    03     var _name = '';   
    04     person.getName = function() {   
    05         return _name || 'not defined';   
    06     }   
    07 })();   
    08   
    09 person.getName(); // "not defined"   
    10 typeof(person._name); // "undefined"


  3. JavaScript没有块级上下文(Scope)
    JavaScript中块级代码没有上下文,实际上只有函数有自己的上下文。
    1 for(var i = 0; i < 2; i ++) { 
    2   
    3
    4 i;  // 2
    如果想创建一个上下文,可以使用自执行的匿名函数:
    1 (function (){ 
    2     for(var i = 0; i < 2; i ++) { 
    3       
    4     }
    5 })(); 
    6 typeof(i) === 'undefined'// true


  4. 怪异的NaN
    NaN用来表示一个值不是数字。
    NaN在JavaScript中行为很怪异,是因为那NaN和任何值都不相等(包括它自己)。
    1 NaN === NaN; // false
    因为下面的代码可能会让一些人抓狂:
    1 parseInt('hello', 10); // NaN 
    2 parseInt('hello', 10) == NaN; // false 
    3 parseInt('hello', 10) === NaN; // false
    那么如何来检查一个值是否NaN?
    可以使用window.isNaN来判断:
    1 isNaN(parseInt('hello', 10)); // true


  5. 真值和假值
    JavaScript中所有值都能隐式地转化为Boolean类型。
    在条件判断中,下面这些值会自动转化为false:
    null, undefined, NaN, 0, ‘’, false
    因此,不需要做如下复杂的判断:
    1 if(obj === undefined || obj === null) { 
    2 }
    而只需要这样做就行了:
    1 if(!obj) { 
    2   
    3 }


  6. 修改arguments
    比如,添加一个值到arguments中:
    1 function add() { 
    2     arguments.push('new value'); 
    3
    4 add(); // error - arguments.push is not a function
    这样会出错,因为arguments不是一个真正的数组,没有push方法。
    解决办法:
    1 function add() { 
    2     Array.prototype.push.call(arguments, 'new value'); 
    3     return arguments; 
    4
    5 add()[0]; // "new value"


  7. Boolean 和 new Boolean
    我们可以把Boolean看做是一个函数,用来产生Boolean类型的值(Literal):
    1 Boolean(false) === false; // true 
    2 Boolean('') === false; // true
    所以,Boolean(0)!!0是等价的。
    我们也可以把Boolean看做是一个构造函数,通过new来创建一个Boolean类型的对象:
    1 new Boolean(false) === false; // false 
    2 new Boolean(false) == false; // true 
    3 typeof(new Boolean(false)); // "object" 
    4 typeof(Boolean(false)); // "boolean"


  8. 快速字符串连接
    我们经常使用+将较短的字符串连接为一个长字符串,这在大部分的情况下是没问题的。
    但是如果有大量的字符串需要连接,这种做法将会遇到性能问题,尤其是在IE下。
    1 var startTime = new Date();
    2 var str = '';
    3 for (var i = 0; i < 50000; i++) {
    4     str += i;
    5 }
    6 alert(new Date() - startTime);  // Firefox - 18ms, IE7 - 2060ms
    1 var startTime = new Date();
    2 var arr = [];
    3 for (var i = 0; i < 100000; i++) {
    4     arr.push(i);
    5 }
    6 var str = arr.join("");
    7 alert(new Date() - startTime); // Firefox - 38ms, IE7 - 280ms

    可以看到Firefox似乎对+操作符进行了优化,而IE则表现的傻乎乎的。

    1. 一元操作符 +
      1. 在JavaScript中,我们可以在字符串之前使用一元操作符“+”。这将会把字符串转化为数字,如果转化失败则返回NaN。
    2. 1 2 + '1'; // "21"
    3. 2 2 + ( +'1'); // 3
    1. 如果把 + 用在非字符串的前面,将按照如下顺序进行尝试转化:
    2. 调用valueOf()
    3. 调用toString()
    4. 转化为数字
    1. 1 +new Date; // 1242616452016
    2. 2 +new Date === new Date().getTime(); // true
    3. 3 +new Date() === Number(new Date) // true
    4. 参考文章


    5. encodeURI和encodeURIComponent
      window.encodeURI函数用来编码一个URL,但是不会对以下字符进行编码:“:”, “/”, “;”, “?”.
      window.encodeURIComponent则会对上述字符进行编码。
      我们通过一个例子来说明:
      1 'index.jsp?page='+encodeURI('/page/home.jsp');  // "index.jsp?page=/page/home.jsp"
      2 'index.jsp?page='+encodeURIComponent('/page/home.jsp');  // "index.jsp?page=%2Fpage%2Fhome.jsp"
      因此,在对URL进行编码时我们经常会选择 encodeURIComponent。


    6. table.innerHTML在IE下是只读属性
      我们经常通过节点的innerHTML属性来填充节点,比如:
      1 <div id="container1"> </div>
      1 document.getElementById('container1').innerHTML = "Hello World!";
      但是在IE下设置table.innerHTML将会导致错误:
      1 <table id="table1"> </table>
      1 // works well in Firefox, but fail to work in IE
      2 document.getElementById('table1').innerHTML = "<tr><td>Hello</td><td>World!</td></tr>";
      实际上,table, thead, tr, select等元素的innerHTML属性在IE下都是只读的。

      那么如果动态的创建一个table呢,下面提供了一种可行的方法:
      1 <div id="table1"> </div>
      1 document.getElementById('table1').innerHTML = "<table><tr><td>Hello</td><td>World!</td></tr></table>";


    1. 0.1+0.2 != 0.3
      JavaScript将小数作为浮点数对待,所以可能会产生一些四舍五入的错误,比如:
    2. 1 0.1 + 0.2; // 0.30000000000000004
    3. 你可以通过toFixed方法指定四舍五入的小数位数:
    4. 1 (0.1 + 0.2).toFixed(); // "0"
    1. 2
    1. (0.1 + 0.2).toFixed(1); // "0.3"

  • 转自:http://www.cnblogs.com/sanshi/archive/2009/08/30/1556677.html