簡單談?wù)刯avascript高級特性
js中沒有class的概念,我們可以使用function來模擬。
惰性載入函數(shù)
例如我們通常使用以下的js代碼創(chuàng)建ajax:
function createXHR () {
var xhr = null;
try{
xhr = new XMLHttpRequest(); // FF、Opera、Safari、IE7
} catch(e) {
handlerError(e);
try{
xhr = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try{
xhr = ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
xhr = null;
}
}
}
return xhr;
}
function handlerError (err) {
var errXHR = err;
// ...
}
在現(xiàn)代的網(wǎng)絡(luò)技術(shù)中ajax技術(shù)早已是爛大街了,一個網(wǎng)頁通常包含很多的ajax——也就導(dǎo)致了頻繁創(chuàng)建xhr從而導(dǎo)致內(nèi)存泄露。我們可以采用惰性載入函數(shù)來動態(tài)生成xhr。
/* 惰性函數(shù)(第二次生效) */
function createXHR () {
var xhr = null;
if (typeof XMLHttpRequest != 'undefined') {
xhr = new XMLHttpRequest();
createXHR = function () {
return new XMLHttpRequest();
}
} else {
try{
xhr = new ActiveXObject('Msxml2.XMLHTTP');
createXHR = function () {
return new ActiveXObject('Msxml2.XMLHTTP');
}
} catch (e){
try{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
createXHR = function () {
return new ActiveXObject('Microsoft.XMLHTTP');
}
} catch (e){
createXHR = function () {
return null;
}
}
}
}
return xhr;
}
我們調(diào)用以上的方法創(chuàng)建xhr,在運(yùn)行第二次的時候就不用每次都判斷了,直接返回xhr。
函數(shù)柯里化
函數(shù)的柯里化(curry)把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。,簡而言之就是兩個函數(shù)的參數(shù)的合并。例如:
function curry(fn) {
var args = Array.prototype.slice.call(arguments,1); // 取curry的參數(shù)并將其變?yōu)閿?shù)組[100]
console.log(args); // [100]
return function () {
var innerArgs = Array.prototype.slice.call(arguments); // 匿名函數(shù)的參數(shù)列表[1,2]
console.log(innerArgs); // [1,2]
var finalArgs = args.concat(innerArgs); // 合并數(shù)組(參數(shù)合并)
console.log(finalArgs); // [100,1,2]
return fn.apply(null, finalArgs);
}
}
function add(num1,num2,num3) {
return num1 + num2 + num3;
}
var t = curry(add,100)(1,2);
console.info(t);

級聯(lián)函數(shù)
級聯(lián)就是一個對象將其所有有關(guān)的東西連接到了一起。如:以下的對象。
// 人:手、腿、嘴
function classPerson(){
this.hand = "";
this.foot = "";
this.leg = "";
}
classPerson.prototype = {
setHand:function(){
this.hand = '大手';
},
setLeg:function () {
this.leg = '長腿歐巴';
},
setMouse:function () {
this.mouse = '櫻桃小嘴';
}
}
var person = new classPerson();
person.setHand();
person.setMouse();
person.setLeg();
console.log(person);

我們知道造人是一個整體(不可能先造手、再造腿、最后造嘴),我們現(xiàn)在的需求是一旦實(shí)例化人這個對象,該有的都有了。
簡單修改以上代碼:
function classPerson(){
this.hand = "";
this.foot = "";
this.leg = "";
}
classPerson.prototype = {
setHand:function(){
this.hand = '大手';
return this;
},
setLeg:function () {
this.leg = '長腿歐巴';
return this;
},
setMouse:function () {
this.mouse = '櫻桃小嘴';
return this;
}
}
var person = new classPerson();
person.setHand().setMouse().setLeg(); // 調(diào)用函數(shù)
console.log(person);
我們在每個setter中添加了return this將原有對象返回(避免無返回值的函數(shù)執(zhí)行完之后是undefined)。我們可以驚奇的發(fā)現(xiàn)常用的JQuery的鏈?zhǔn)秸{(diào)用就是一種級聯(lián)調(diào)用:
$(‘#id').show().hide().show().hide().show().hide();
javascript中的正則表達(dá)式
一般來說//在js中表示的是單行注釋,但是一旦我們向斜杠中間加入了內(nèi)容,例如:/TEST/它就神奇地變成了正則。
模式串的聲明
var patt1 = new RegExp('hello'); // 方式一
var patt2 = /word/; // 方式二
test方法
我們得到了模式串(模式對象)后可以調(diào)用該方法匹配字符串,返回指定值(true or false)。
var patt = /my/; var str = 'this is my code...'; console.log(patt.test(str)); // true
exec方法
類似于字符串的match方法,但是當(dāng)模式串指定為全局的時候兩者表現(xiàn)不同,沒有匹配返回null。
/hello/.exec('oh hello world'); // ["hello"]
以上兩個方法都是字符串對象本身的方法,下面的幾個方法是字符串中的有關(guān)正則的方法。
match方法
模式匹配。函數(shù)原型是str.mattch(pattern),將匹配的結(jié)果以數(shù)組返回。
console.log('test 123'.match(/test/g)); // [test]
replace方法
字符串替換,注意:該方法生成一個新的臨時字符串副本。如圖所示:

split方法
將字符串拆分成按照模式拆分成數(shù)組。
console.log('Hello world,hello everyone'.split(/\s+/)); // ["Hello", "world,hello", "everyone"]
console.log('Hello world,hello everyone'.split(' ')); // 等效于上面的方法
正則的類型
/pattern/attributes
attributes是可選字符串,常用的屬性是“g”(全局匹配)、“i”(大小寫不敏感)和"m"(多行匹配)
console.log('Hello world,hello everyone'.match(/hEllO/gi)); // 全局查找hello并忽略大小寫 ["Hello", "hello"]
在實(shí)際的開發(fā)中我們可以借助在線正則調(diào)試工具來調(diào)試我們的正則,其實(shí)里面內(nèi)置了大量常用的正則。如果我們在開發(fā)中分析不出別人的正則的含義可以借助正則分析網(wǎng)站,將會以有限自動機(jī)圖解的方式顯示。

正則中的元字符
正則中的元字符必須進(jìn)行轉(zhuǎn)義處理:
( [ { ^ $ | ) ? * + .]}
需要注意的是正則有2種創(chuàng)建形式:字符串字面量和new RegExp()的方式.由于RegExp的構(gòu)造函數(shù)是字符串,所以某些情況下需要進(jìn)行雙重轉(zhuǎn)義.

__PROTO__
__proto__使得繼承變得更加容易:
function Super(){};
function Sub(){};
Sub.prototype.__proto__ = Super.prototype;
這是一個非常有用的特性,可以免去如下的工作:
借助中間構(gòu)造器
無需引入第三方模塊來進(jìn)行基于原型繼承的聲明
訪問器
可以調(diào)用方法來定義屬性,如其名有:__defineGetter__、__defineSetter__。例如為Date對象定義一個ago的屬性,返回以自然語言描述的日期間隔(例如:某件事發(fā)生在3秒之前)。例如:
Date.prototype.__defineGetter__('ago',function(){
var diff = ((Date.now() - this.getTime()) / 1000)
day_diff = Math.floor(diff / 86400)
return day_diff == 0 && (diff < 60 && 'just now' )
|| diff < 120 && '1 minute ago'
|| diff < 3600 && Math.floor(diff / 60) + 'minutes ago'
|| diff < 7200 && '1 hour ago'
|| diff < 86400 && Math.floor(diff / 3600) + 'hours ago'
|| day_diff == 1 && 'Yesterday'
|| diff < 7 && day_diff + ' days ago'
|| Math.ceil(day_diff / 7) + ' weeks ago'
})
var d = new Date('12/12/1990')
console.log(d.ago)
相關(guān)文章
JavaScript內(nèi)置對象math,global功能與用法實(shí)例分析
這篇文章主要介紹了JavaScript內(nèi)置對象math,global功能與用法,結(jié)合實(shí)例形式分析了javascript中內(nèi)置對象math與global的基本概念、功能及使用方法,需要的朋友可以參考下2019-06-06
基于Bootstrap使用jQuery實(shí)現(xiàn)輸入框組input-group的添加與刪除
這篇文章主要介紹了基于Bootstrap使用jQuery實(shí)現(xiàn)輸入框組input-group的添加與刪除的相關(guān)資料,需要的朋友可以參考下2016-05-05
JavaScript中使用typeof運(yùn)算符需要注意的幾個坑
這篇文章主要介紹了JavaScript中使用typeof運(yùn)算符需要注意的幾個坑,本文總結(jié)了4個使用typeof運(yùn)算符要注意的問題,需要的朋友可以參考下2014-11-11
jsvascript圖像處理—(計算機(jī)視覺應(yīng)用)圖像金字塔
上一篇文章,我們講解了邊緣梯度計算函數(shù),這篇文章我們來了解圖像金字塔;圖像金字塔被廣泛用于計算機(jī)視覺應(yīng)用中;圖像金字塔是一個圖像集合,集合中所有的圖像都源于同一個原始圖像,而且是通過對原始圖像連續(xù)降采樣獲得的2013-01-01
點(diǎn)擊頁面任何位置隱藏div的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄c(diǎn)擊頁面任何位置隱藏div的實(shí)現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09
JavaScript學(xué)習(xí)筆記之?dāng)?shù)組基本操作示例
這篇文章主要介紹了JavaScrip學(xué)習(xí)筆記之?dāng)?shù)組基本操作,結(jié)合實(shí)例形式分析了javascript數(shù)組的基本定義、添加、刪除、修改、連接、排序等操作技巧,需要的朋友可以參考下2019-01-01
javascript點(diǎn)擊才出現(xiàn)驗證碼
用javascript[js]實(shí)現(xiàn)的必須經(jīng)過點(diǎn)擊才能出現(xiàn)嚴(yán)重碼效果代碼2008-04-04

