写博客真是一个好事情,自已花了一天弄了这篇,加深了很多印象。可以时不时复习一下,也希望能够帮助到他人。
一、HTML5的语义化标签:大概有<header><nav><article><section><aside><footer>,比<div class="">更直观,也方便搜索引擎。
二、正则,这是一大块,项目中也常用到。(有时用js有时用C#,虽然规则是一样的,但命令常搞混)
(资料参考:http://blog.csdn.net/zaifendou/article/details/5746988
http://www.blogjava.net/onejavaer/articles/79070.html
http://www.jb51.net/article/25313.htm)
1、exec()
var regx=/a(d+)(A)c/; var result = regx.exec("a123Acddd"); result
result是["a123Ac","123","A"] ,其中第一个是匹配到的值,后面两个是括号里的值。
但console.log(result)却是 ["a123Ac", "123", "A", index: 0, input: "a123Acddd"],有时调试时要注意,不要搞混了
var regx=/ad+c/; var result=regx.exec("a123cddd");
没有括号,result是["a123c"]
var regx=/userd/g; var rs=regx.exec("ddduser1dsfuser2dd"); var rs1=regx.exec("ddduser1dsfuser2dd"); console.log(rs); console.log(rs1);
得到rs1是["user1"],rs2是["user2"]。。。这是个坑,以前都没注意到。
不符合条件的话,是返回null
2、test()
var regx=/userd+/g; var flag=regx.test("user12dd"); console.log(flag);
得到true,其实用其它方法不符合时就会返回null,就可以判断了,一般都不用专门test()来判断
============以上两个是regx的方法,后面的是string的方法,常弄混==============
3、match()
var regx=/userd/g; var str="user13userddduser345"; var rs=str.match(regx); console.log(rs)
显示 ["user1", "user3"],这会又没后面那个什么Index,Input了。。。不知为何exec在console.log时会附带那些东西。
regx加了/g,是显示全部,不加/g是第一个,如果不匹配,是返回null。
4、search()
var regx=/userd/g; var str="ABCuser13userddduser345"; var rs=str.search(regx);
rs是3,如果不符合条件,得到-1。
和indexOf()非常类似
var regx=/userd/g; var str="ABCuser13userddduser345"; str.indexOf("user");
得到的也是3,查不到也是-1。但indexOf()只能查具体的字符串,不能查正则。
5、replace(expr,str)
var regx=/user/g var str="user13userddduser345"; var rs=str.replace(regx,"ABC");
得到rs是"ABC13ABCdddABC345"
如果不加/g,或直接是字符串"user",则仅替换第一个
var regx=/user/ //或var regx="user" var str="user13userddduser345"; var rs=str.replace(regx,"ABC");
得到的都是 "ABC13userddduser345"
6、split(expr)
不管是否加/g,或直接是字符串,效果都是一样的。这点和replace有所不同,也是个坑
var regx=/user/g; //或 var regx="user" var str="user13userddduser345"; var rs=str.split(regx);
得到的都是 ["", "13", "ddd", "345"]
7、转义
需要转义的有 * . ? + $ ^ [ ] ( ) { } | /
8、预定义
. IE下[^
],其它[^
] 匹配除换行符之外的任何一个字符
d [0-9] 匹配数字
D [^0-9] 匹配非数字字符
s [
fx0B] 匹配一个空白字符
S [^
fx0B] 匹配一个非空白字符
w [a-zA-Z0-9_] 匹配字母数字和下划线
W [^a-zA-Z0-9_] 匹配除字母数字下划线之外的字符
9、/g是全局,/i是忽略大小写,/m是多行查找。
另有RegExp.$n (n为1~99),表示第几个匹配项
var r = /(d+)-(w+)/; var b=r.exec("1234-abcd-b"); console.log(RegExp.$1+"~"+RegExp.$2); b = r.test("1234-abcd"); console.log(RegExp.$1+"~"+RegExp.$2);
得到的均为 1234~abcd
10、匹配方式
*是零次或多次,+是一次或多次,?是零次或一次,而且在量词后面加?就变成惰性模式,即匹配尽量少(默认是贪婪模式,即匹配尽量多)。
var str = "abc"; var re = /w+/; //将匹配abc var result = re.exec(str) console.log(result) re = /w+?/;//将匹配a result = re.exec(str) console.log(result)
基本上就这些,其它高级用法一时也没法列全,在项目中可以边试边用,面试时这些应该就差不多了。
三、原型,扩展原型方法,项目中有用过String.Format(),就是像C#的string.Format("xxx{0}",str)一样用法。
if (!String.prototype.format) { String.prototype.format = function () { var args = arguments; return this.replace(/{(d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); }; }
四、阻止冒泡:preventDefault(阻止事件默认行为)、stopPropagation(阻止冒泡)、return false(相当于前面两个都执行)。
五、兼容
var e = window.event || evt; var tag = e.target || e.srcElement; var keyCode = evt.keyCode || evt.which;
判断浏览器(顺序不能错)就记住关键词window.navigator.userAgent,然后顺序IE、火狐、谷歌、欧朋、苹果
function getExplorer() { var explorer = window.navigator.userAgent ; if (explorer.indexOf("MSIE") != -1) { console.log("ie"); } else if (explorer.indexOf("Firefox") != -1) { console.log("Firefox"); } else if(explorer.indexOf("Chrome") != -1){ console.log("Chrome"); } else if(explorer.indexOf("Opera") != -1){ console.log("Opera"); } else if(explorer.indexOf("Safari") != -1){ console.log("Safari"); } }
六、作用域(配合this、闭包),经常有坑,一般是function声明会提到最前,且function内部有定义变量的,就不会再去找上一级,但是定义的变量又未执行到,还是undefined
http://mianshiti.diandian.com/post/2013-04-05/40048538140这一题比较有代表性
var foo = 'hello'; (function() { var foo = foo || 'world'; console.log(foo); })(); //显示world var foo = 'hello'; (function() { console.log(foo); var foo = foo || 'world'; })(); //显示undefined var foo = 'hello'; (function(f) { var foo = f || 'world'; console.log(foo); })(foo); //显示hello
var i=9; function fo(){ var i=0; return function(n){ return n+(++i); } }; var f=fo(); var a = f(15);console.log(a) var b = fo()(15); console.log(b) var c = fo()(20); console.log(c) var d = f(20);console.log(d)
分别得到16 16 21 22
珠峰有一题比较复杂 http://www.iqiyi.com/w_19rr1au1fh.html
var number=2; var obj={ number:4, fn1:(function(){ this.number *= 2; number=number*2; var number=3; return function(){ this.number *= 2; number *= 3; console.log("inside:"+number); } })(), db2:function(){this.number *= 2} }; console.log("Only Define,number is:"+number); var fn1=obj.fn1; console.log("After Assign,number is:"+number); console.log("Run fn1():"); fn1(); console.log("After Run fn1(),number is:"+number); console.log("Run obj.fn1():"); obj.fn1(); console.log("After Run obj.fn1(),number is:"+number); console.log("window.number is:"+window.number); console.log("obj.number is:"+obj.number)
Only Define,number is:4 //在定义中,fn1的方法是立即执行的(function(){})(),里面的this.number,是执行时的window,所以window.number*2 = 4
After Assign,number is:4 //赋值只是引用对象一下,不改变什么
Run fn1():
inside:9 //fn1() ->obj.fn1() ->执行闭包里面的函数,里面的number就是上一级的 var number = 3,所以最后是3*3==9
After Run fn1(),number is:8 //这时的window.number,在一开始已经变成4了,再执行一次,又*2,变成8了
Run obj.fn1():
27 //和前面的fn1()是一样的,相当于再执行一次,而闭包不释放,上次又经是9了,再*3=27
After Run obj.fn1(),number is:8
window.number is:8
obj.number is:8
有些难搞懂,要配合下面这个再测一下 ,为了不混淆,把各参数都改成质数,虽然数字看着有些大,但能弄清问题实际
var number=3; var obj={ number:5, fn1:(function(){ this.number *= 7; console.log("this.number *= 7,this.number="+this.number);console.log(this) number=number*11; console.log("number=number*11;,number="+number); var number=13; return function(){ this.number *= 17; console.log("this.number *= 17,this.number="+this.number); console.log(this) number *= 19; console.log("number *= 19,number="+number); console.log("inside:"+number); } })(), db2:function(){this.number *= 23; console.log("this.number *= 23,this.number="+this.number);} }; console.log("var fn1=obj.fn1;"); var fn1=obj.fn1; console.log("obj.fn1();") obj.fn1(); console.log("obj.fn1() 1times, number is:"+number); console.log("obj.fn1() 1times, obj.number is:"+obj.number); obj.fn1(); console.log("obj.fn1() 2times, number is:"+number); console.log("obj.fn1() 2times, obj.number is:"+obj.number); obj.fn1(); console.log("obj.fn1() 3times, number is:"+number); console.log("obj.fn1() 3times, obj.number is:"+obj.number); fn1(); console.log("fn1() 1times, number is:"+number); console.log("fn1() 1times, obj.number is:"+obj.number); fn1(); console.log("fn1() 2times, number is:"+number); console.log("fn1() 2times, obj.number is:"+obj.number); fn1(); console.log("fn1() 3times, number is:"+number); console.log("fn1() 3times, obj.number is:"+obj.number);
this.number *= 7,this.number=21
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
number=number*11;,number=NaN
此时是仅定义时输出的。因为是(function(){})()这种直接执行的形式,所以定义时就执行了。以后都是执行return里面的返回值。
此时的this指向window,把全局的number变成3*7=21了。而number=number*11,此时的number在fn1中有定义var number=13,但未执行到,所以此时还是undefined(这是个坑)
===================
var fn1=obj.fn1; //仅是引用赋值,未引发输出
obj.fn1(); //执行obj.fn1()
this.number *= 17,this.number=85
Object {number: 85}db2: ()fn1: ()number: 24565__proto__: Object
number *= 19,number=247
inside:247
此时的this指向obj,obj.number=5,所以obj.number ->5*17=85。
而number会去找上下文,发现obj.fn1有定义var number=13,所以number*=19 -> 13*19=247
obj.fn1() 1times, number is:21
obj.fn1() 1times, obj.number is:85
所以此时输出全局number是21,obj.number是85
===================
//第二次执行
this.number *= 17,this.number=1445
Object {number: 1445}
number *= 19,number=4693
inside:4693
同理this依然指向obj,而上一次obj.number已经变成85了,所以此次85*17=1445
number继续是obj.fn1.number,所以number -> 247*19=4693
obj.fn1() 2times, number is:21
obj.fn1() 2times, obj.number is:1445
全局number=21一直没变
//第三次执行,和前两次一样分析即可
this.number *= 17,this.number=24565
Object {number: 24565}
number *= 19,number=89167
inside:89167
obj.fn1() 3times, number is:21
obj.fn1() 3times, obj.number is:24565
//第一次执行fn1()
this.number *= 17,this.number=357
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
number *= 19,number=1694173
inside:1694173
this指向了window,这也是个坑。所以window.number ->21*17=357,而obj.number就不会再变化了。
fn1() 1times, number is:357
fn1() 1times, obj.number is:24565
//第二次执行fn1()
this.number *= 17,this.number=6069
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
number *= 19,number=32189287
inside:32189287
主要就是this指向了window,现在this.number就是window.number。而内部的number一直是*19
fn1() 2times, number is:6069
fn1() 2times, obj.number is:24565
//第三次执行fn1(),和前两次一样分析即可
this.number *= 17,this.number=103173
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
number *= 19,number=611596453
inside:611596453
fn1() 3times, number is:103173
fn1() 3times, obj.number is:24565
这题比较绕,能搞清楚的话,就把闭包、作用域之类的全搞懂了,关键是fn1()指向了window。也不知道我理解的对不对,暂时先这样吧。
七、符号在html中表现
< < > > & & " " 空格
八、js异步加载(而不是在页头直接引用,增加页面载入速度)
function loadScript(url,callback){ var script=document.creatElement("script"); script.type="text/javascript"; if(script.readyState){ script.onreadystatechange=function(){ if(script.readyState=="loaded"||script.readyState=="complete"){ script.onreadystatechange=null; callback(); } } }else{ script.onload=function(){ callback(); } } script.src=url; document.getElementsByName("head")[0].appendChild(script); }
1.直接document.write"); <script> document.write("<script src="test.js"></script>"); </script> 2.动态改变已有script的src属性 <script src="" id="s1"><script> <script> s1.src="test.js" </script> 3.动态创建script元素 <script> var oHead=document.getElementsByTagName("HEAD").item(0); var oScript=document.createElement("script"); oScript.type="text/javascript"; oScript.src="test.js"; oHead.appendChild(oScript); </script>