JavaScript学习笔记之应用技巧(转载)
2010-02-25 23:05 爱研究源码的javaer 阅读(332) 评论(0) 收藏 举报-
闭包(closure)
闭包指的是函数内的局部变量,当函数返回时此变量依然可用。
当你在函数内部定义另外一个函数时,你就创建了一个闭包,一个著名的例子:add(2)是一个函数,它可能获取外部函数的局部变量i。1functionadd(i) {2returnfunction() {3return++i;4};5}6add(2).toString();// "function () { return ++i; }"7add(2)();// 3
参考文章 - 私有变量
我们经常使用命名规范来标示一个变量是否为私有变量(最常用来标示):下划线前缀用来作为私有变量的约定,但是其他开发人员仍然可以调用此私有变量:1varperson = {2_name:'',3getName:function() {4returnthis._name ||'not defined';5}6};7person.getName();// "not defined"那么,如何在JavaScript中创建一个真正的私有变量呢?1person._name;// ""
主要技巧是使用匿名函数(anonymous function)和闭包(closure)。01varperson = {};02(function() {03var_name ='';04person.getName =function() {05return_name ||'not defined';06}07})();0809person.getName();// "not defined"10typeof(person._name);// "undefined" - JavaScript没有块级上下文(Scope)
JavaScript中块级代码没有上下文,实际上只有函数有自己的上下文。如果想创建一个上下文,可以使用自执行的匿名函数:1for(vari = 0; i < 2; i ++) {23}4i;// 21(function(){2for(vari = 0; i < 2; i ++) {34}5})();6typeof(i) ==='undefined';// true - 怪异的NaN
NaN用来表示一个值不是数字。
NaN在JavaScript中行为很怪异,是因为那NaN和任何值都不相等(包括它自己)。因为下面的代码可能会让一些人抓狂:1NaN === NaN;// false那么如何来检查一个值是否NaN?1parseInt('hello', 10);// NaN2parseInt('hello', 10) == NaN;// false3parseInt('hello', 10) === NaN;// false
可以使用window.isNaN来判断:1isNaN(parseInt('hello', 10));// true - 真值和假值
JavaScript中所有值都能隐式地转化为Boolean类型。
在条件判断中,下面这些值会自动转化为false:
null, undefined, NaN, 0, ‘’, false
因此,不需要做如下复杂的判断:而只需要这样做就行了:1if(obj === undefined || obj ===null) {2}1if(!obj) {23} - 修改arguments
比如,添加一个值到arguments中:这样会出错,因为arguments不是一个真正的数组,没有push方法。1functionadd() {2arguments.push('new value');3}4add();// error - arguments.push is not a function
解决办法:1functionadd() {2Array.prototype.push.call(arguments,'new value');3returnarguments;4}5add()[0];// "new value" - Boolean 和 new Boolean
我们可以把Boolean看做是一个函数,用来产生Boolean类型的值(Literal):所以,Boolean(0)和!!0是等价的。1Boolean(false) ===false;// true2Boolean('') ===false;// true
我们也可以把Boolean看做是一个构造函数,通过new来创建一个Boolean类型的对象:1newBoolean(false) ===false;// false2newBoolean(false) ==false;// true3typeof(newBoolean(false));// "object"4typeof(Boolean(false));// "boolean" - 快速字符串连接
我们经常使用+将较短的字符串连接为一个长字符串,这在大部分的情况下是没问题的。
但是如果有大量的字符串需要连接,这种做法将会遇到性能问题,尤其是在IE下。
1varstartTime =newDate();2varstr ='';3for(vari = 0; i < 50000; i++) {4str += i;5}6alert(newDate() - startTime);// Firefox - 18ms, IE7 - 2060ms1varstartTime =newDate();2vararr = [];3for(vari = 0; i < 100000; i++) {4arr.push(i);5}6varstr = arr.join("");7alert(newDate() - startTime);// Firefox - 38ms, IE7 - 280ms
可以看到Firefox似乎对+操作符进行了优化,而IE则表现的傻乎乎的。
- 一元操作符 +
- 在JavaScript中,我们可以在字符串之前使用一元操作符“+”。这将会把字符串转化为数字,如果转化失败则返回NaN。
-
-
12 +'1';// "21" -
22 + ( +'1');// 3
- 如果把 + 用在非字符串的前面,将按照如下顺序进行尝试转化:
- 调用valueOf()
- 调用toString()
- 转化为数字
-
1+newDate;// 1242616452016 -
2+newDate ===newDate().getTime();// true -
3+newDate() === Number(newDate)// true - 参考文章
- encodeURI和encodeURIComponent
window.encodeURI函数用来编码一个URL,但是不会对以下字符进行编码:“:”, “/”, “;”, “?”.
window.encodeURIComponent则会对上述字符进行编码。
我们通过一个例子来说明:因此,在对URL进行编码时我们经常会选择 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" - table.innerHTML在IE下是只读属性
我们经常通过节点的innerHTML属性来填充节点,比如:1<divid="container1"> </div>但是在IE下设置table.innerHTML将会导致错误:1document.getElementById('container1').innerHTML ="Hello World!";1<tableid="table1"> </table>实际上,table, thead, tr, select等元素的innerHTML属性在IE下都是只读的。1// works well in Firefox, but fail to work in IE2document.getElementById('table1').innerHTML ="<tr><td>Hello</td><td>World!</td></tr>";
那么如果动态的创建一个table呢,下面提供了一种可行的方法:1<divid="table1"> </div>1document.getElementById('table1').innerHTML ="<table><tr><td>Hello</td><td>World!</td></tr></table>";
- 0.1+0.2 != 0.3
JavaScript将小数作为浮点数对待,所以可能会产生一些四舍五入的错误,比如: -
10.1 + 0.2;// 0.30000000000000004 - 你可以通过toFixed方法指定四舍五入的小数位数:
-
1(0.1 + 0.2).toFixed();// "0"
|
|
转自:http://www.cnblogs.com/sanshi/archive/2009/08/30/1556677.html
浙公网安备 33010602011771号