摘要:調(diào)用函數(shù)時(shí),被綁定到全局對(duì)象。如果使用構(gòu)造器調(diào)用有前綴,且返回不是一個(gè)對(duì)象,則返回該新對(duì)象。閉包會(huì)導(dǎo)致原有作用域鏈不釋放,造成內(nèi)存泄漏。當(dāng)采用構(gòu)造器調(diào)用模式,函數(shù)執(zhí)行的方式會(huì)被修改。
內(nèi)容
ECMAScript核心語(yǔ)法結(jié)構(gòu):一、語(yǔ)法 1.類(lèi)型、值和變量
1.語(yǔ)法
2.對(duì)象
3.函數(shù)
4.繼承
5.數(shù)組
6.正則表達(dá)式
7.方法
8.附錄A-毒瘤
9.附錄B-糟粕
1) 類(lèi)型:區(qū)分?jǐn)?shù)據(jù)類(lèi)型
在JS中使用var關(guān)鍵詞聲明變量,變量的類(lèi)型會(huì)根據(jù)其所賦值來(lái)決定(動(dòng)態(tài)類(lèi)型)。 JS中數(shù)據(jù)類(lèi)型分為原始數(shù)據(jù)類(lèi)型(5種)和引用數(shù)據(jù)類(lèi)型(Object類(lèi)型)。
原始數(shù)據(jù)類(lèi)型(5):Number、String、Boolean、Undefined、Null。需要注意的是JS中字符串屬于原始數(shù)據(jù)類(lèi)型。
typeof返回值(6):number、string、boolean、undefined、object、function 。null返回object
instanceof:解決引用類(lèi)型判斷問(wèn)題 詳解
3) 變量
變量:局部變量和全局變量
變量提升:
函數(shù)及變量的聲明都將被提升到函數(shù)的最頂部。
變量可以在使用后聲明,也就是變量可以先使用再聲明。
1) 條件語(yǔ)句
if:
switch:
2)循環(huán)語(yǔ)句
while
for
do
3)強(qiáng)制跳轉(zhuǎn)語(yǔ)句
continue:跳出單次循環(huán)
break:跳出單層循環(huán)
return:函數(shù)返回語(yǔ)句,但是返回的同時(shí)也將函數(shù)停止
throw:創(chuàng)建或拋出異常
4)應(yīng)用
1.label應(yīng)用-跳出多層循環(huán)
var obj={ "last-name":"yue",//"-"是不合法的,必須使用引號(hào) firstName:"su" }2.檢索
1)檢索對(duì)象里包含的值:
obj["last-name"] //yue obj.firstName //su
2)用||填充默認(rèn)值
var name=obj.name||"susu";
3)用&&避免錯(cuò)誤
obj.likeInfo.model// throw "TypeError" obj.likeInfo && obj.likeInfo.model //undefined3.更新
通過(guò)賦值語(yǔ)句更新,如果有值則替換,沒(méi)有值則新增
obj.firstName="susu"4.引用
對(duì)象通過(guò)引用來(lái)傳遞。它們永遠(yuǎn)不會(huì)被復(fù)制
var x=obj; x.nick="aaa"; console.log(obj.nick);//aaa // x,obj指向同一個(gè)對(duì)象的引用 var a={},b={},c={}//a,b,c每個(gè)都引用一個(gè)不同的空對(duì)象 var a=b=c={};//a,b,c引用同一個(gè)空對(duì)象5.原型
每個(gè)對(duì)象都連接到一個(gè)原型對(duì)象,并從中繼承屬性
通過(guò)字面量創(chuàng)建的對(duì)象都連接到Object.prototype
object的create方法可以選擇某個(gè)對(duì)象作為它的原型
if(typeof Object.beget!=="function"){ Object.create=function(proto){ function F(){}; F.prototype=proto; return new F(); } } var a=Object.create(obj); // 當(dāng)對(duì)a對(duì)象做出改變時(shí),不會(huì)影響該對(duì)象的原型6.反射
檢查對(duì)象并確定對(duì)象的屬性
刪除不需要的屬性:
1) 檢查并丟棄值是函數(shù)的屬性
typeof obj.toString // "function"
2) hasOwnProperty 檢查對(duì)象自己的屬性,不會(huì)檢查原型鏈
obj.hasOwnProperty("toString") //false7.枚舉
for in:遍歷對(duì)象中的所有屬性名,包含原型中自己添加的屬性
注意:屬性名出現(xiàn)的順序是不確定的,(可以創(chuàng)建包含屬性名的數(shù)組,再用for循環(huán)來(lái)解決)
delete :刪除對(duì)象的屬性,不會(huì)觸及原型鏈中的任何對(duì)象
如果存在該屬性,則被移除,并返回true;
如果不存在該屬性,返回undefined;
// 不會(huì)影響原型 Object.prototype.name="1111111"; delete name;//true obj.name;//11111119.減少全局變量污染
最小化使用全局變量的方法之一:只創(chuàng)建一個(gè)唯一的全局變量
var local={ data:{}, methods:{ test(){ console.log(123) } } } local.methods.test();//123三、函數(shù) 1.函數(shù)對(duì)象
函數(shù)對(duì)象連接到Function.prototype(該原型對(duì)象本身連接到Object.prototype)
每個(gè)函數(shù)在創(chuàng)建時(shí)會(huì)附加兩個(gè)隱藏屬性:函數(shù)的上下文和實(shí)現(xiàn)函數(shù)行為的代碼。
每個(gè)函數(shù)對(duì)象在創(chuàng)建時(shí)也隨配有一個(gè)prototype屬性。它的值是一個(gè)擁有controctor屬性且值即為該函數(shù)的對(duì)象。
這和隱藏連接到Function.prototype完全不同。
函數(shù)對(duì)象通過(guò)函數(shù)字面量來(lái)創(chuàng)建:
var add=function(a,b){ return a+b; }
函數(shù)字面量包含四個(gè)部分:
1) 保留字function
2) 函數(shù)名:可以省略(匿名函數(shù)),可以用來(lái)遞歸調(diào)用自己,
3)參數(shù):
4) 函數(shù)主體
調(diào)用時(shí)每個(gè)函數(shù)接收兩個(gè)附加參數(shù):this,arguments。
調(diào)用模式:這些模式在如何初始化this上存在差異
1) 方法調(diào)用模式
當(dāng)一個(gè)函數(shù)被保存為對(duì)象的一個(gè)屬性時(shí),我們稱(chēng)它為一個(gè)方法。
當(dāng)方法調(diào)用時(shí),this被綁定到該對(duì)象
var myObj={ value:0, increment:function(inc){ this.value+=typeof inc==="number"?inc:1; } } myObj.increment(2); console.log(myObj.value);//3
2) 函數(shù)調(diào)用模式
當(dāng)一個(gè)函數(shù)并非一個(gè)對(duì)象的屬性時(shí),那么它就是被當(dāng)作函數(shù)來(lái)調(diào)用的。
調(diào)用函數(shù)時(shí),this被綁定到全局對(duì)象。
var sum=add(3,4); //7
解決this指向:在外部函數(shù)中定義that=this,那么內(nèi)部函數(shù)可以通過(guò)that訪問(wèn)外部的對(duì)象。
3) 構(gòu)造器調(diào)用模式
如果在一個(gè)函數(shù)前面帶上new來(lái)調(diào)用,那么背地里將會(huì)創(chuàng)建一個(gè)連接到該函數(shù)的prototype成員的新對(duì)象,
同時(shí)this會(huì)被綁定到新對(duì)象上。會(huì)改變r(jià)eturn語(yǔ)句的行為。
var Obj=function(str){ this.status=str; } Obj.prototype.get_status=function(){ return this.status; } var myobj=new Obj("aaa"); myobj.get_status();//aaa
4) apply調(diào)用模式
aplly(綁定給this的值,參數(shù)數(shù)組):構(gòu)建一個(gè)參數(shù)數(shù)組傳遞給調(diào)用函數(shù)
var statusObj={ status:123 } Obj.prototype.get_status.apply(statusObj);//1234.參數(shù)
當(dāng)函數(shù)調(diào)用時(shí),會(huì)接受一個(gè)附加參數(shù)arguments數(shù)組(類(lèi)數(shù)組:有l(wèi)ength屬性,但沒(méi)有數(shù)組的任何方法)。
可以編寫(xiě)一個(gè)無(wú)須指定參數(shù)個(gè)數(shù)的函數(shù)。
var sum=function(){ var sum=0; for(var i=0;i5.返回 return語(yǔ)句可用來(lái)使函數(shù)提前返回。
6.異常
如果使用構(gòu)造器調(diào)用(有new前綴),且返回不是一個(gè)對(duì)象,則返回this(該新對(duì)象)。異常是干擾程序的正常流程的不尋常
throw語(yǔ)句中斷函數(shù)的執(zhí)行,并拋出exception對(duì)象,該對(duì)象會(huì)被傳遞到try語(yǔ)句的catch從句。var add=function(a,b){ if(typeof a!=="number"||typeof b !=="number"){ throw{ name:"TypeError", message:"必須是數(shù)字" } } return a+b; } try{ add(1,"aaa") }catch(e){ console.log(e.name,e.message);//TypeError 必須是數(shù)字 }7.擴(kuò)充類(lèi)型的功能通過(guò)給基本類(lèi)型增加方法,新的方法立刻被賦予到所有對(duì)象的實(shí)例上,提高語(yǔ)言的表現(xiàn)力。
Function.prototype.method=function(name,func){ if(!this.prototype[name]){ this.prototype[name]=func; } return this; } Number.method("interge",function(){ return Math[this<0?"ceil":"floor"](this); }); 2.3.interge();//28.遞歸遞歸函數(shù)就是會(huì)直接或間接的調(diào)用自身的一種函數(shù)。
遞歸函數(shù)操作樹(shù)形結(jié)構(gòu),如瀏覽器端的文檔對(duì)象模型(DOM)// 漢諾塔游戲 var hanoi=function(n,from,ass,to){ if(n>0){ hanoi(n-1,from,to,ass); console.log("移動(dòng)第"+n+"個(gè)從"+from+"到"+to); hanoi(n-1,ass,from,to); } } hanoi(2,"A","B","C"); // 移動(dòng)次數(shù) function moveTimes(n){ if(n==1){ return 1; } return 2*moveTimes(n-1)+1; }9.作用域作用域控制著變量與參數(shù)的可見(jiàn)性及生命周期,它減少了名稱(chēng)沖突,并提供了自動(dòng)內(nèi)存管理。
10.閉包
優(yōu)點(diǎn):內(nèi)部函數(shù)可以訪問(wèn)定義它們的外部函數(shù)的參數(shù)和變量(除了this和arguments)。當(dāng)內(nèi)部函數(shù)被保存到外部時(shí),將會(huì)生成閉包。閉包會(huì)導(dǎo)致原有作用域鏈不釋放,造成內(nèi)存泄漏。
閉包可以訪問(wèn)它被創(chuàng)建時(shí)所處的上下文環(huán)境。// 避免在循環(huán)中創(chuàng)建函數(shù),可以在循環(huán)之外創(chuàng)建一個(gè)輔助函數(shù), // 讓這個(gè)輔助函數(shù)再返回一個(gè)綁定了當(dāng)前i值的函數(shù) var add_handlers=function(nodes){ var helper=function(i){ return function(){ console.log(i); } } for(var i=0;i11.回調(diào) 發(fā)起異步請(qǐng)求時(shí),提供一個(gè)當(dāng)服務(wù)器的響應(yīng)到達(dá)時(shí)隨即觸發(fā)的回調(diào)函數(shù),異步函數(shù)立即返回,這樣客戶端就不會(huì)被阻塞。
12.模塊使用函數(shù)和閉包來(lái)構(gòu)造模塊。
模塊模式利用了函數(shù)作用域和閉包來(lái)創(chuàng)建被綁定對(duì)象與私有成員的關(guān)聯(lián)。
一般形式:一個(gè)定義了私有變量和函數(shù)的函數(shù);利用閉包創(chuàng)建可以訪問(wèn)私有變量和函數(shù)的特權(quán)函數(shù);最后返回這個(gè)特權(quán)函數(shù),或者保存到一個(gè)可訪問(wèn)到的地方。String.method("deentityify",function(){ // 字符實(shí)體表,若放在函數(shù)內(nèi)部每次執(zhí)行函數(shù)時(shí)該字面量都會(huì)被求值一次,會(huì)帶來(lái)運(yùn)行時(shí)的損耗, var entity={ quot:""", lt:"<", gt:">", } return function(){ return this.replace(/&([^&;]+);/g,function(a,b){ var r=entity[b]; return typeof r==="string"?r:a; }) } }()) ">"<".deentityify(); // >"<13.級(jí)聯(lián)如果方法返回this,就會(huì)啟用級(jí)聯(lián)。
14.柯里化
在一個(gè)級(jí)聯(lián)中,可以在多帶帶一條語(yǔ)句中依次調(diào)用同一個(gè)對(duì)象的很多方法。柯里化允許我們把函數(shù)與傳遞給它的參數(shù)相結(jié)合,產(chǎn)生一個(gè)新的函數(shù)。
Function.method("curry",function(){ var slice=Array.prototype.slice, args=slice.apply(arguments); that=this; return function(){ return that.apply(null,args.concat(slice.apply(arguments))); } }); function add(a,b){ return a+b; } var add1=add.curry(1); var res=add1(6);//715.記憶記憶:函數(shù)可以將先前操作的結(jié)果記錄在某個(gè)對(duì)象里,從而避免無(wú)謂的重復(fù)運(yùn)算。
// memo:初始數(shù)組; formula:函數(shù) 公式 var memoizer=function(memo,formula){ var recur=function(n){ result=memo[n]; if(typeof result !=="number"){ result=formula(recur,n); memo[n]=result; } return result; } return recur; } var fibonacci=memoizer([0,1],function(recur,n){ return recur(n-1)+recur(n-2); }); var res=fibonacci(10);四、繼承 1.偽類(lèi)缺點(diǎn):沒(méi)有私有環(huán)境,所有的屬性都是公開(kāi)的。
// 當(dāng)采用構(gòu)造器調(diào)用模式,函數(shù)執(zhí)行的方式會(huì)被修改。 // 如果new運(yùn)算符是一個(gè)方法,它可能會(huì)像這樣執(zhí)行 Function.method("new",function(){ // 創(chuàng)建一個(gè)新對(duì)象,它繼承自構(gòu)造器的原型對(duì)象 var that=Object.create(this.prototype); // 調(diào)用構(gòu)造器函數(shù),綁定this到新對(duì)象上 var other=this.apply(that,arguments); // 如果它的返回值不是一個(gè)對(duì)象,就返回改新對(duì)象 return (typeof other=="object"&& other)||that; })可以構(gòu)造一個(gè)偽類(lèi)來(lái)繼承父類(lèi),這是通過(guò)定義它的constructor函數(shù)并替換它的prototype為一個(gè)父類(lèi)的實(shí)例來(lái)實(shí)現(xiàn)
Function.method("inherits",function(Parent){ this.prototype=new Parent(); return this; })2.對(duì)象說(shuō)明符在編寫(xiě)構(gòu)造器時(shí)讓它接受一個(gè)簡(jiǎn)單的對(duì)象說(shuō)明符。
多個(gè)參數(shù)可以按任何順序排列,如果構(gòu)造器使用默認(rèn)值,一些參數(shù)可以忽略,代碼易閱讀。var obj=testFn({ first:f, middle:m, last:l });3.原型一個(gè)新對(duì)象可以繼承一個(gè)舊對(duì)象的屬性
用Object.create(parent)構(gòu)造出更多的實(shí)例
差異化繼承:通過(guò)定制一個(gè)新對(duì)象,我們指明它與所基于的基本對(duì)象的區(qū)別// 作用域繼承,內(nèi)部作用域繼承外部作用域遇到一個(gè)左花括號(hào)時(shí)block函數(shù)被調(diào)用, var block=function(){ // 記住當(dāng)前作用域,構(gòu)造一個(gè)包含了當(dāng)前作用域中所有對(duì)象的新作用域 var oldScope=scope; scope=Object.create(oldScope); // 傳遞左花括號(hào)作為參數(shù)調(diào)用advance advance("{"); // 使用新的作用域進(jìn)行解析 parse(scope); // 傳遞左花括號(hào)作為參數(shù)調(diào)用advance并拋棄新作用域,恢復(fù)原來(lái)老的作用域。 advance("}"); scope=oldScope; }4.函數(shù)化應(yīng)用模塊模式解決私有變量和私有函數(shù)
函數(shù)化構(gòu)造器步驟:
1)創(chuàng)建一個(gè)新對(duì)象
2)有選擇的定義私有實(shí)例變量和方法。
3)給這個(gè)對(duì)象擴(kuò)充方法,這些方法擁有特權(quán)去訪問(wèn)參數(shù)。
4)返回那個(gè)新對(duì)象// 偽代碼模板 var constructor=function(spec,my){ var that,其他的私有實(shí)例變量 my=my||{}; 把共享的變量和函數(shù)添加到my中 that=一個(gè)新對(duì)象 添加給that的特權(quán)方法 return that; }// 處理父類(lèi)的方法 Object.method("superior",function(name){ var that=this, method=that[name]; return function(){ return method.apply(that,arguments); } })//例子 var mammal=function(spec){ var that={}; that.get_name=function(){ return "hello"+spec.name; } return that; } var cat=function(spec){ var that=mammal(spec); var super_get_name=that.superior("get_name") that.get_name=function(){ return spec.name+"like"+super_get_name(); } return that; } var my=cat({name:"su"}); console.log(my.get_name());//su like hello su5.部件從一套部件中把對(duì)象組裝出來(lái)。
五、數(shù)組 1.定義:字面量: var arr=[1,2,3];
構(gòu)造方法: new Array(length/content);
2.屬性constructor: 返回創(chuàng)建此對(duì)象的數(shù)組函數(shù)的引用。
length:設(shè)置或返回?cái)?shù)組中元素的長(zhǎng)度。
prototype:向?qū)ο筇砑訉傩院头椒?/p> 3.刪除
1)delete 會(huì)在數(shù)組中留下一個(gè)空洞
2)splice 可以刪除元素并替換為其他元素var arr=["a","b","c","d"]; delete arr[1]; console.log(arr);//["a", empty, "c", "d"] // 對(duì)于大型數(shù)據(jù),可能效率會(huì)不高 var arr1=["a","b","c","d"]; arr1.splice(2,1) console.log(arr1);//["a", "b", "d"]4.方法
Array.method("reduce",function(f,value){ for(var i=0;iObject.create方法用在數(shù)組是沒(méi)有意義的,因?yàn)樗a(chǎn)生一個(gè)對(duì)象,而不是一個(gè)數(shù)組。
5.指定初始值
產(chǎn)生的對(duì)象將繼承這個(gè)數(shù)組的值和方法,但是它沒(méi)有那個(gè)特殊的length屬性。// fill 初始化 var arr=new Array(5); arr.fill(0);//[0, 0, 0, 0, 0] // 初始化一維數(shù)組 Array.dim=function(dimension,initial){ var a=[]; for(var i=0;i6.原型-方法 1).改變?cè)瓟?shù)組:
push:向數(shù)組的末尾添加一個(gè)或更多元素,并返回新的長(zhǎng)度。
pop:刪除并返回?cái)?shù)組的最后一個(gè)元素
shift: 刪除并返回?cái)?shù)組的第一個(gè)元素
unshift:向數(shù)組開(kāi)頭添加一個(gè)或多個(gè)元素,并返回新的長(zhǎng)度。
reverse:逆轉(zhuǎn)順序,并返回新數(shù)組
sort:排序,返回排序后的數(shù)組
splice:(從第幾位開(kāi)始,截取多少的長(zhǎng)度,在切口處添加新的數(shù)據(jù)) 刪除元素,并向數(shù)組添加新元素,返回被截取元素的數(shù)組
fill(value, start, end) 將一個(gè)固定值替換數(shù)組的元素。
2).不改變?cè)瓟?shù)組
concat: 連接兩個(gè)或更多的數(shù)組,并返回結(jié)果。
slice:(從該位開(kāi)始截取,截取到該位] 截取,返回被截取元素的數(shù)組
join:通過(guò)指定的分隔符(默認(rèn)逗號(hào))進(jìn)行分隔,返回字符串
toString:把數(shù)組轉(zhuǎn)換為字符串,并返回結(jié)果。
7.原型-循環(huán)方法1)參數(shù)相同 (回調(diào)函數(shù)(當(dāng)前元素,當(dāng)前元素的索引,原數(shù)組),this)
forEach: 代替普通for循環(huán),沒(méi)有返回值
map:通過(guò)指定函數(shù)處理數(shù)組的每個(gè)元素,并返回處理后的數(shù)組。
filter:過(guò)濾 ,返回符合條件所有元素的數(shù)組。
every:檢測(cè)數(shù)值中的每個(gè)元素是否都符合條件。返回true或false
some:檢測(cè)數(shù)組中是否有元素符合條件。返回true或false
5.應(yīng)用1.數(shù)組-參考手冊(cè)
六、正則表達(dá)式 1.結(jié)構(gòu)
2.數(shù)組,類(lèi)數(shù)組
3.forEach,for in ,for of的區(qū)別1)創(chuàng)建RegExp對(duì)象:
字面量 var my_reg=/[A-Z]/g;
構(gòu)造器,適用于必須在運(yùn)行時(shí)動(dòng)態(tài)生成正則表達(dá)式的情形。var my_reg=new RegExp("[A-Z]","g");
創(chuàng)建字符串時(shí)需要注意,因?yàn)榉葱备茉谡齽t表達(dá)式和字符串中含義不同,通常需要雙寫(xiě)反斜杠,以及對(duì)引號(hào)進(jìn)行轉(zhuǎn)義2)正則表達(dá)式標(biāo)識(shí)
標(biāo)識(shí) 含義 g 全局的(匹配多次;不同的方法對(duì)g標(biāo)識(shí)的處理各不相同) i 大小寫(xiě)不敏感(忽略字符大小寫(xiě)) m 多行(^和$能匹配行結(jié)束符) 3)RegExp對(duì)象的屬性
2.元素
屬性 用法 global 如果標(biāo)識(shí)g被使用,值為true ignoreCase 如果標(biāo)識(shí)i被使用,值為true multiline 如果標(biāo)識(shí)m被使用,值為true lastIndex 下一次exec匹配開(kāi)始的索引。初始值為0 source 正則表達(dá)式源碼文本 1)正則表達(dá)式分支
一個(gè)正則表達(dá)式包含一個(gè)或多個(gè)正則表達(dá)式序列。
這些序列被|(豎線)字符分隔,如果這些字符中的任何一項(xiàng)符合匹配條件,那么這個(gè)選擇就被匹配。
它常是按順序依次匹配這些序列項(xiàng)// 因?yàn)閕n已被成功匹配,所以不會(huì)匹配int var a="into".match(/in|int/);//["in"]2)正則表達(dá)式序列
一個(gè)正則表達(dá)式序列包含一個(gè)或多個(gè)正則表達(dá)式因子。
每個(gè)因子能選擇是否跟隨一個(gè)量詞,這個(gè)量詞決定著這個(gè)因子被允許出現(xiàn)的次數(shù)。
如果沒(méi)有指定這個(gè)量詞,那么該因子只會(huì)被匹配一次3)正則表達(dá)式因子
一個(gè)正則表達(dá)式因子可以是一個(gè)字符、一個(gè)由圓括號(hào)包圍的組、一個(gè)字符類(lèi),或是一個(gè)轉(zhuǎn)義序列
這些字符需要轉(zhuǎn)義: / { } ? + * | . ^ $4)正則表達(dá)式轉(zhuǎn)義
反斜杠字符在正則表達(dá)式因子和在字符串中均表示轉(zhuǎn)義,但在正則表達(dá)式因子中有點(diǎn)不同
d : [0-9],D:[^d]
s : [tnrvf ] 空白字符, S:[^s]
w : [0-9A-Za-z_] ,W:[^w]
: 單詞邊界 B:[^b]
1 : 指向分組1所捕獲到的文本的一個(gè)引用。 如:2,35)正則表達(dá)式分組
捕獲型: 一個(gè)捕獲型分組是一個(gè)被包圍在圓括號(hào)找那個(gè)的正則表達(dá)式分支。每個(gè)捕獲型分組都被指定了一個(gè)數(shù)組。
任何匹配這個(gè)分組的字符都會(huì)被匹配。
在正則表達(dá)式中第一個(gè)捕獲(的是分組1,第二個(gè)捕獲(的是分組2。非捕獲型: 非捕獲型分組有一個(gè)(?:前綴,僅做簡(jiǎn)單的匹配,并不會(huì)捕獲所匹配的文本,不會(huì)干擾捕獲型分組的編號(hào)。
向前正向匹配: 向前正向匹配分組有一個(gè)(?=前綴,類(lèi)似非捕獲型分組,
但在這個(gè)組匹配后,文本會(huì)倒回到它開(kāi)始的地方,實(shí)際上并不匹配任何東西。向前負(fù)向匹配: 向前負(fù)向匹配分組有一個(gè)(?!前綴,類(lèi)似向前正向匹配分組,
但只有當(dāng)它匹配失敗時(shí)它才繼續(xù)向前進(jìn)行匹配6)正則表達(dá)式字符集
正則表達(dá)式字符集是一種指定一組字符的便利方式。
如果匹配一個(gè)元音字母,可以寫(xiě)成(?:a|e|i|o|u),
但可以更方便的寫(xiě)成一個(gè)類(lèi)[aeiou], 類(lèi)的求反 [^aeiou]7)正則表達(dá)式量詞
正則表達(dá)式因子可以用一個(gè)正則表達(dá)式量詞后綴來(lái)決定這個(gè)因子應(yīng)該被匹配的次數(shù)。
七、方法 1.Array
包圍在一對(duì)花括號(hào)中的一個(gè)數(shù)組表示這個(gè)因子被匹配的次數(shù)。
n+ : {1,} 1到多個(gè)
n* : {0,}
n? : {0,1}
n{X} : X個(gè)
n{X,Y} : X-Y個(gè)
n{X,} : X到多個(gè)
?=n : 匹配其后緊接n 的字符串
?!n : 匹配其后沒(méi)有緊接n 的字符串
如果只有一個(gè)量詞,表示趨向于進(jìn)行貪婪性匹配,即匹配盡可能多的副本直至達(dá)到上限。
如果這個(gè)量詞附加一個(gè)后綴?,表示趨向于進(jìn)行非貪婪性匹配,即只匹配必要的副本就好。數(shù)組-參考手冊(cè)
2.Functionfunction.apply(thisArg,argArray)
apply方法調(diào)用function,傳遞一個(gè)會(huì)被綁定到this上的對(duì)象和一個(gè)可選的數(shù)組作為參數(shù)Function.method("bind",function(that){ var method=this; var slice=Array.prototype.slice; var args=slice.apply(arguments,[1]) return function(){ return method.apply(that,args.concat(slice.apply(arguments))); } }) var test=function(){ return this.value+":"+Array.prototype.slice.apply(arguments); }.bind({value:666},1,2); console.log(test(3));//666:1,2,33.NumberNumber-參考手冊(cè)
4.ObjectObject.hasOwnProperty(name)不會(huì)檢查原型鏈中的屬性
var a={member:true}; var b=Object.create(a); var c=a.hasOwnProperty("member");//true var d=b.hasOwnProperty("member");//false var e=b.member;//true5.RegExpRegExp-參考手冊(cè)
1.regExp.exec(string)
如果通過(guò)循環(huán)去查詢一個(gè)匹配模式在字符串中發(fā)生了幾次,需要注意:如果提前退出了循環(huán),再次進(jìn)入這個(gè)循環(huán)前必須把
RegExp.lastIndex重置為0,而且,^僅匹配RegExp.lastIndex為0的情況。
如果帶有g(shù)全局標(biāo)識(shí),查找不是從這個(gè)字符串的起始位置開(kāi)始,而是從regExp.lastIndex位置開(kāi)始。var reg1=/ab/g; var str="ababab"; console.log(reg1.exec(str),reg1.lastIndex) console.log(reg1.exec(str),reg1.lastIndex) console.log(reg1.exec(str),reg1.lastIndex) console.log(reg1.exec(str),reg1.lastIndex) console.log(reg1.exec(str),reg1.lastIndex) // 打印結(jié)果: ["ab", index: 0, input: "ababab", groups: undefined] 2 ["ab", index: 2, input: "ababab", groups: undefined] 4 ["ab", index: 4, input: "ababab", groups: undefined] 6 null 0 ["ab", index: 0, input: "ababab", groups: undefined] 22.regExp.test(string)
// 如果這個(gè)方法使用g標(biāo)識(shí),會(huì)改變lastIndex的值 var reg=/[A-Z]/g; var arr=["Asdsd","BsdsCds","Dasas","E1212"]; for(var i=0;i6.String 字符串-參考手冊(cè)
附錄A-毒瘤 1.全局變量全局變量使得在同一個(gè)程序中運(yùn)行獨(dú)立的子程序變得更難。
因?yàn)槿肿兞靠梢员怀绦虻娜魏尾糠衷谌我鈺r(shí)間修改,使程序的行為變得極度復(fù)雜,降低程序的可靠性// 定義全局變量的方法 var foo=value; window.foo=value; foo=value;2.作用域沒(méi)有塊級(jí)作用域,代碼塊中聲明的變量在包含此代碼塊的函數(shù)的任何位置都是可見(jiàn)的。
3.自動(dòng)插入分號(hào)
更好的方式:在每個(gè)函數(shù)的開(kāi)頭部分聲明所有變量有一個(gè)自動(dòng)修復(fù)機(jī)制,它試圖通過(guò)自動(dòng)插入分號(hào)來(lái)修正有缺損的程序.
它可能會(huì)掩蓋更為嚴(yán)重的錯(cuò)誤。// 在return語(yǔ)句后自動(dòng)插入分號(hào)導(dǎo)致的后果 function test1(){ return{ name:"aaa" } } function test2(){ return { name:"aaa" } } console.log(test1(),test2());//{name: "aaa"} undefined4.保留字保留字不能被用來(lái)命名變量或參數(shù)。
當(dāng)保留字被用做對(duì)象字面量的鍵值時(shí),它們必須被引號(hào)括起來(lái),不能用在點(diǎn)表示法中,必須使用括號(hào)表示法。var case;//非法,都不支持 // ie8及以下不支持 非法的寫(xiě)法 var obj={case:"123"};//非法 var a=obj.case//非法 var object={"case":"1212"};//ok var b=object["case"];//ok5.UnicodeUnicode把一對(duì)字符視為一個(gè)單一的字符,而js認(rèn)為一對(duì)字符是兩個(gè)不同的字符
6.typeoftypeof null返回object
正則表達(dá)式,返回object,在safari(3.x版本)中返回function// 區(qū)分null與對(duì)象 if(value&& typeof value=="object"){ //value是一個(gè)對(duì)象或數(shù)組 }7.parseIntparseInt把字符串轉(zhuǎn)換為整數(shù),
// 遇到非數(shù)字時(shí)會(huì)停止解析 parseInt("16")==parseInt("16aa123");//ture // ie8及以下會(huì)出現(xiàn)以下問(wèn)題: // 如果字符串第一個(gè)字符是0,那么字符串會(huì)基于八進(jìn)制來(lái)求值,() // 會(huì)導(dǎo)致程序解析日期和時(shí)間時(shí)出現(xiàn)問(wèn)題,可以用parseInt的第二個(gè)參數(shù)作為基數(shù)解決 console.log(parseInt("08"),parseInt("09"));//0 0 console.log(parseInt("08",10),parseInt("09",10));//8 98.++運(yùn)算符可以用于加法運(yùn)算或字符串連接,如何執(zhí)行取決于其參數(shù)的類(lèi)型
9.浮點(diǎn)數(shù)
加法運(yùn)算:兩個(gè)運(yùn)算數(shù)都是數(shù)字
字符串連接:其中一個(gè)運(yùn)算數(shù)是空字符串,則另一個(gè)運(yùn)算數(shù)被轉(zhuǎn)換成字符串進(jìn)行連接。二進(jìn)制的浮點(diǎn)數(shù)不能正確處理十進(jìn)制的小數(shù)。
0.1+0.2 //0.30000000000000004 //浮點(diǎn)數(shù)中的整數(shù)運(yùn)算是正確的,所以小數(shù)表現(xiàn)出來(lái)的錯(cuò)誤可以通過(guò)指定精度來(lái)避免 (0.1*10+0.2*10)/10 //0.310.NaNNaN是一個(gè)特殊的數(shù)量值。它表示的不是一個(gè)數(shù)字,但是 typeof NaN==="number"
該值會(huì)在試圖把非數(shù)字形式的字符串轉(zhuǎn)化為數(shù)字時(shí)產(chǎn)生,如:Number("12px") //NaN
NaN===NaN //fales// 區(qū)分?jǐn)?shù)字與NaN isNaN(NaN);//true isNaN("aaa");//true判斷一個(gè)值是否可用做數(shù)字使用isFinite函數(shù),因?yàn)樗鼤?huì)篩掉NaN和Infinity
但是它會(huì)試圖把運(yùn)算數(shù)轉(zhuǎn)換為一個(gè)數(shù)字,isFinite("10")//truevar isNumber=function(value){ return typeof value==="number"&&isFinite(value) } isNumber("10");//false11.偽數(shù)組// 辨別數(shù)組 // arguments是一個(gè)類(lèi)數(shù)組,返回[object Arguments] if(Object.prototype.toString.apply(value)==="[object Array]"){ //value是一個(gè)數(shù)組 }12.假值以下這些值全部等同于假,但它們是不可互換的
13.hasOwnProperty
值 類(lèi)型 0 Number NaN(非數(shù)字) Number ""(空字符串) String false Boolean null Object undefined Undefined hasOwnProperty可以解決for in的隱患
但它是一個(gè)方法,在任何對(duì)象中,它可能會(huì)被一個(gè)不同的函數(shù)甚至一個(gè)非函數(shù)的值所替換var name,obj={}; obj.hasOwnProperty=null;//地雷 for(name in obj){ if(obj.hasOwnProperty(name)){//觸雷 console.log(name,obj[name]) } }14.對(duì)象js對(duì)象永遠(yuǎn)不會(huì)是真的空對(duì)象,因?yàn)樗梢詮脑椭腥〉贸蓡T屬性
// 如果字符串里面包含constructor,會(huì)返回{hello: 3, word: 1, constructor: "function Object() { [native code] }1"} // 可以用hasOwnProperty處理 返回{hello: 1, word: 1, constructor: 1} var text="hello word hello,Hello constructor"; var words=text.toLowerCase().split(/[s,.]+/); var count={},word; for(var i=0;i附錄B-糟粕 1.== ==,!=運(yùn)算符只有在兩個(gè)運(yùn)算類(lèi)型一致時(shí)才會(huì)做出正確的判斷,如果兩個(gè)運(yùn)算數(shù)是不同的類(lèi)型,它們?cè)噲D去強(qiáng)制轉(zhuǎn)換值的類(lèi)型
==,!=運(yùn)算符缺乏傳遞性,所以使用===和!=="" == "0"http://false 0 == "0" //true false == "false"http://false false == "0" //true false == undefined //false false == null //fasle null == undefined //true " " == 0 //true2.with語(yǔ)句with語(yǔ)句本意是用來(lái)快捷的訪問(wèn)對(duì)象的屬性,但有時(shí)不可預(yù)料,所以應(yīng)該避免使用它
嚴(yán)重影響了js處理器的速度,因?yàn)樗钄嗔俗兞棵脑~法作用域綁定with(obj){ a=b; } // 和下面的代碼做的是同樣的事情 if(obj.a===undefined){ a = obj.b === undefined ? b : obj.b; }else{ obj.a = obj.b === undefined ? b : obj.b; } // 所以,它等同于這些語(yǔ)句中的某一條: a = b; a = obj.b; obj.a = b; obj.a = obj.b;3.evaleval函數(shù)傳遞一個(gè)字符串給javaScript編輯器,并且執(zhí)行結(jié)果
4.continue語(yǔ)句
1)使用eval形式的代碼更加難以閱讀,這種形式使得性能顯著降低,因?yàn)樗枰\(yùn)行編譯器,但也許只是為了執(zhí)行一個(gè)賦值語(yǔ)句。
2)它會(huì)讓JSLint失效,讓此工具檢測(cè)問(wèn)題的能力大打折扣
3)減弱了應(yīng)用程序的安全性,因?yàn)樗磺笾档奈谋臼谟枇颂嗟臋?quán)利,與with語(yǔ)句執(zhí)行方式一樣,降低語(yǔ)言的性能
4)Function構(gòu)造器是eval的另一種形式,應(yīng)該避免使用(new Function ([arg1[, arg2[, ...argN]],] functionBody))
5)setTimeout,setInterval當(dāng)接收字符串參數(shù)時(shí),也會(huì)像eval那樣處理,應(yīng)避免使用字符串參數(shù)continue語(yǔ)句跳到循環(huán)的頂部
但是如果一段代碼通過(guò)重構(gòu)移除continue語(yǔ)句之后,性能都會(huì)得到改善console.time(111) var sum=0; for(var i=0;i<100;i++){ if(i==50){ continue; } sum+=i; } console.timeEnd(111);//0.051025390625ms console.time(222) var sum=0; for(var i=0;i<100;i++){ if(i!=50){ sum+=i; } } console.timeEnd(222);// 0.02099609375ms5.switch穿越除非你明確地中斷流程,否則每次條件判斷后都穿越到下一個(gè)case條件。
6.缺少塊的語(yǔ)句if,while,do,for語(yǔ)句可以接受一個(gè)括在花括號(hào)找那個(gè)的代碼塊,也可以接受單行語(yǔ)句
但是單行語(yǔ)句模糊了程序的結(jié)構(gòu),使得在隨后的操作代碼中可能很容易插入錯(cuò)誤//容易導(dǎo)致錯(cuò)誤 if(ok) t=true; advance()7.++這兩個(gè)運(yùn)算符鼓勵(lì)了一種不夠謹(jǐn)慎的變成風(fēng)格,大多數(shù)的緩沖區(qū)溢出的錯(cuò)誤所造成的安全漏洞,都是由像這樣的代碼導(dǎo)致的
8.位運(yùn)算符
并且它會(huì)使代碼變得過(guò)于擁擠,復(fù)雜和隱晦在java里,位運(yùn)算符處理的是整數(shù),但是js沒(méi)有整數(shù)類(lèi)型,只有雙精度的浮點(diǎn)數(shù),因此,位操作符把它們的數(shù)字運(yùn)算數(shù)先轉(zhuǎn)換成整數(shù),在執(zhí)行運(yùn)算,然后在轉(zhuǎn)換回去。
9.function語(yǔ)句對(duì)比f(wàn)unction表達(dá)式
在大多數(shù)語(yǔ)言中,位運(yùn)算符接近于硬件處理,所以非???。但js的執(zhí)行環(huán)境一般接觸不到硬件,所以非常慢,js很少被用來(lái)執(zhí)行位操作function語(yǔ)句在解析時(shí)會(huì)發(fā)生被提升的情況,不管function被放置在哪里,它會(huì)被移動(dòng)到被定義時(shí)所在作用域的頂層,
這放寬了函數(shù)先聲明后使用的要求,這會(huì)導(dǎo)致混亂function foo(){ } // foo是一個(gè)包含一個(gè)函數(shù)值的變量,函數(shù)就是數(shù)值 var foo=function(){ }一個(gè)語(yǔ)句不能以一個(gè)函數(shù)表達(dá)式開(kāi)頭,但可以把函數(shù)調(diào)用括在一個(gè)圓括號(hào)之中
(function(){ var a=1; // 這個(gè)函數(shù)可能對(duì)環(huán)境有一些影響,但不會(huì)引入新的全局變量 })()10.類(lèi)型的包裝對(duì)象new Boolean,new Number,new String會(huì)返回一個(gè)對(duì)象,該對(duì)象有一個(gè)valueOf方法會(huì)返回被包裝的值
11.new
避免使用new Array和new Object,可使用[]和{}來(lái)代替1)new運(yùn)算符創(chuàng)建一個(gè)繼承于其構(gòu)造器函數(shù)的原型的新對(duì)象,然后調(diào)用該構(gòu)造器函數(shù),把新創(chuàng)建的對(duì)象綁定給this,
12.void
這給構(gòu)造器函數(shù)一個(gè)機(jī)會(huì)在返回給請(qǐng)求者前自定義新創(chuàng)建的對(duì)象
2)如果忘記new運(yùn)算符,就是一個(gè)普通的函數(shù)調(diào)用,this被綁定到全局對(duì)象,而不是創(chuàng)建一個(gè)新對(duì)象。污染全局變量
3)構(gòu)造器函數(shù)應(yīng)該以首字母大寫(xiě)的形式命名,并且首字母大寫(xiě)的形式應(yīng)該只用于來(lái)命名構(gòu)造器函數(shù)在很多語(yǔ)言中,void是一種類(lèi)型,表示沒(méi)有值
但在js中,void是一個(gè)運(yùn)算符,它接受一個(gè)運(yùn)算數(shù)并返回undefined,這沒(méi)有什么用,應(yīng)避免使用它//當(dāng)用戶鏈接時(shí),void(0) 計(jì)算為 0,但 Javascript 上沒(méi)有任何效果。 單擊此處什么也不會(huì)發(fā)生
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/54750.html
摘要:調(diào)用函數(shù)時(shí),被綁定到全局對(duì)象。如果使用構(gòu)造器調(diào)用有前綴,且返回不是一個(gè)對(duì)象,則返回該新對(duì)象。閉包會(huì)導(dǎo)致原有作用域鏈不釋放,造成內(nèi)存泄漏。當(dāng)采用構(gòu)造器調(diào)用模式,函數(shù)執(zhí)行的方式會(huì)被修改。 內(nèi)容 ECMAScript核心語(yǔ)法結(jié)構(gòu):1.語(yǔ)法2.對(duì)象3.函數(shù)4.繼承5.數(shù)組6.正則表達(dá)式7.方法8.附錄A-毒瘤9.附錄B-糟粕 一、語(yǔ)法 1.類(lèi)型、值和變量 1) 類(lèi)型:區(qū)分?jǐn)?shù)據(jù)類(lèi)型 在JS中使...
摘要:前端入門(mén)的門(mén)檻相對(duì)較低,學(xué)習(xí)曲線是越來(lái)越陡峭,由淺入深,可以分為四個(gè)階段。第二階段高級(jí)程序設(shè)計(jì)有的書(shū)是用來(lái)成為經(jīng)典的,比如犀牛書(shū)還有些書(shū)是用來(lái)超越經(jīng)典的,顯然這本書(shū)就是。接下來(lái)可以看看教程,看看源代碼,嘗試著寫(xiě)一寫(xiě)這些效果。 前端入門(mén)的門(mén)檻相對(duì)較低,學(xué)習(xí)曲線是越來(lái)越陡峭,由淺入深,可以分為四個(gè)階段。 第一階段:《JavaScript DOM編程藝術(shù)》 看這本書(shū)之前,請(qǐng)先確認(rèn)你對(duì)J...
摘要:本文最早為雙十一而作,原標(biāo)題雙大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在上。發(fā)布完本次預(yù)告后,捕捉到了一個(gè)友善的吐槽讀書(shū)清單也要收費(fèi)。這本書(shū)便從的異步編程講起,幫助我們?cè)O(shè)計(jì)快速響應(yīng)的網(wǎng)絡(luò)應(yīng)用,而非簡(jiǎn)單的頁(yè)面。 本文最早為雙十一而作,原標(biāo)題雙 11 大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在 GitChat 上。發(fā)布之后在讀者圈群聊中和讀者進(jìn)行了深入的交流,現(xiàn)免費(fèi)分享到這里,不足之處歡迎指教...
摘要:本文最早為雙十一而作,原標(biāo)題雙大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在上。發(fā)布完本次預(yù)告后,捕捉到了一個(gè)友善的吐槽讀書(shū)清單也要收費(fèi)。這本書(shū)便從的異步編程講起,幫助我們?cè)O(shè)計(jì)快速響應(yīng)的網(wǎng)絡(luò)應(yīng)用,而非簡(jiǎn)單的頁(yè)面。 本文最早為雙十一而作,原標(biāo)題雙 11 大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在 GitChat 上。發(fā)布之后在讀者圈群聊中和讀者進(jìn)行了深入的交流,現(xiàn)免費(fèi)分享到這里,不足之處歡迎指教...
閱讀 3071·2021-09-22 15:52
閱讀 2939·2019-08-30 15:55
閱讀 2730·2019-08-30 15:53
閱讀 2486·2019-08-30 13:21
閱讀 1655·2019-08-30 13:10
閱讀 2516·2019-08-26 12:09
閱讀 2604·2019-08-26 10:33
閱讀 1837·2019-08-23 18:06