JS基礎之基本概念2

相等操作符

最早的ECMAScript中的相等和不相等操作符會在執(zhí)行比較之前,先將對象轉換成相似的類型室谚。后來毡鉴,有人提出了這種轉換到底是否合理的質疑。最后ECMAScript的解決方案就是提供兩組操作符:相等和不相等-先轉換再比較秒赤,全等和不全等-僅比較而不轉換猪瞬。

在轉換不同的數據類型時,相等和不相等操作符遵循下列基本規(guī)則:
1.如果有一個操作數是布爾值倒脓,則在比較相等性之前現將其轉換為數值-false 轉換為0撑螺,true 轉換為1。
2.如果一個操作數是字符串崎弃,另一個操作數是數值甘晤,在比較相等性之前先將字符串轉換為數值。
3.如果一個操作數是數值饲做,另一個操作數不是线婚,則調用對象的valueOf方法,用得到的基本類型值按照前面的規(guī)則進行比較盆均;
基于第三點比較規(guī)則來說話塞弊,這兩個操作符在進行比較時則要遵循下列規(guī)則:
a:nullundefined是相等的
b:要比較相等性之前,不能將nullundefined轉換成其他任何值
c:如果有一個操作數是NaN泪姨,則相等操作符也返回false,而不相等操作符返回true游沿。重要提示:即使兩個操作數都是NaN,相等操作符也返回false肮砾,因為按照規(guī)則诀黍,NaN不等于NaN
d:如果兩個操作數都是對象,則比較它們是不是同一個對象仗处。如果兩個操作數都指向同一個對象眯勾,則相等操作符返回true枣宫,否則,返回false

break/continue/ return語句

break用于完全結束一個循環(huán)吃环,跳出循環(huán)體也颤。不管是哪種循環(huán),一旦在循環(huán)體中遇到break郁轻,系統將完全結束循環(huán)翅娶,開始執(zhí)行循環(huán)之后的代碼。break不僅可以結束其所在的循環(huán)好唯,還可結束其外層循環(huán)故觅。
continue語句會立即退出當前循環(huán),然后繼續(xù)執(zhí)行后面的循環(huán)渠啊,直到循環(huán)結束输吏。而break則是完全中止循環(huán)。
return關鍵字并不是專門用于跳出循環(huán)的替蛉,return的功能是結束一個方法贯溅。 一旦在循環(huán)體內執(zhí)行到一個return語句,return語句將會結束該方法躲查,循環(huán)自然也隨之結束它浅。與continuebreak不同的是,return直接結束整個方法镣煮,不管這個return處于多少層循環(huán)之內姐霍。
以下是三段代碼來表示三者的區(qū)別:

//break
var num = 0;
for(var = 1 ; i < 10 ; i++){
  if(i%5 == 0){
    break;  
  }
  num++;
}
alert(num);  //4
//continue
var num = 0;
for(var = 1 ; i < 10 ; i++){
  if(i%5 == 0){
    continue;  
  }
  num++;
}
alert(num);  //8
//return
function test(i){
    if(i == 3){
        return 
    }
    console.log(i)
}
for (var i = 0; i < 10 ; i++ ){
  test(i)
} // 0 1 2 4 5 6 7 8 9 
width語句

width語句在開發(fā)中很少會用到,本來不想寫它典唇,后來想了想镊折,其特殊的語法形式,也有必要寫下來介衔。
width語句的作用是將代碼的作用域設置到一個特定的環(huán)境中恨胚。定義width語句的目的主要為了簡化多次編寫同一個對象的工作。如下:

var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;

上面代碼塊多次用到location這個對象炎咖,如果使用width語句可以寫成如下所示:

width(location){
  var qs = serarch.substring(1);
  var hostName = hostname;
  var url = href;
}

使用width語句赃泡,從寫法上來說變的復雜了,將簡單的取值賦值語句包在了函數寫法中乘盼。再看一下以下的寫法:

width(window){
  var qs = window.location.serarch.substring(1);
  var hostName = window.location.hostname;
  var url = window.location.href;
}

這樣升熊,就好理解width語句真正的作用。
從運行環(huán)境上來說绸栅,width語句的代碼塊內部级野,每個變量首先被認為是一個局部變量,而如果在局部環(huán)境中找不到該變量的蒂尼阴幌,就會查詢location對象中是否有同名屬性勺阐。如果發(fā)現了同名屬性,則以location對象屬性的值作為變量的值矛双。
大量使用width語句會導致性能下降渊抽,也會讓調試代碼變得困難,而且在嚴格模式下不允許使用width語句议忽,否則將會視為語法錯誤懒闷。

理解函數的參數

在給一個函數傳遞參數時,我們可以顯式的傳參栈幸,也在不傳參的情況下愤估,用arguments這個對象來表示傳入到函數中的參數。
函數傳參有這么一條潛規(guī)則:你可以多傳參數速址,函數體內部可以不用玩焰,但是你不可以少傳參數,那函數體內部就會報錯芍锚。
從函數接受參數的情況來看昔园,函數接收到的參數在函數內部始終會用arguments這個對象來表示。arguments是一個類數組的對象并炮,但它并不是Array的實例默刚。你可以用數組的方法訪問arguments對象中的每一項,arguments[0],arguments[1]......逃魄。所以arguments的長度是由傳入的參數個數決定的荤西,沒有傳入參數就會自動被賦予undefined值。

function test(a,b){
    console.log(typeof arguments)
}
test(1,2)  //'object'

另外還有一點伍俘,arguments的類型是object邪锌,這一點別忘了。
最后還有一點癌瘾,arguments對象內部每一項的值都會與傳入的參數一一對應秃流,注意:是每一項的值。也就是說柳弄,傳入的參數值與arguments中對應的值會保持同步舶胀,不過,由于arguments這個對象始終存在并作用于函數體內部碧注,并且讀取傳入的參數值和讀取對應arguments對象內部的值并不是訪問相同的內存空間嚣伐,他們的內存空間是獨立的。

函數重載

首先理解什么是函數重載萍丐?
函數重載是函數的一種特殊情況轩端,允許在同一范圍中聲明幾個功能類似的同名函數,但是這些同名函數的[形式參數](指參數的個數逝变、類型或者順序)必須不同基茵,也就是說用同一運算符完成不同的運算功能奋构。這就是重載函數。重載函數常用來實現功能類似而所處理的數據類型不同的問題拱层。不能只有函數返回值類型不同弥臼。
但是在js中,函數是無法重載的根灯,例如:

function test(num){
  return num+100
}
function test(num){
  return num+200
}
var result = test(100); //300

不過径缅,由于函數中有arguments這個對象,我們可以根據它的長度烙肺,類型或者順序來實現函數重載纳猪。
這里說一個非常典型的案例:

我們現在有這樣的一個需求,有一個people對象桃笙,里面存著一些人名氏堤,如下:

var people = {
  values: ["Dean Edwards", "Sam Stephenson", "Alex Russell", "Dean Tom"]
};

我們希望people對象擁有一個find方法,當不傳任何參數時搏明,就會把people.values里面的所有元素返回來丽猬;當傳一個參數時,就把first-name跟這個參數匹配的元素返回來;當傳兩個參數時熏瞄,則把first-name和last-name都匹配的才返回來脚祟。因為find方法是根據參數的個數不同而執(zhí)行不同的操作的,所以强饮,我們希望有一個addMethod方法由桌,能夠如下的為people添加find的重載:

addMethod(people, "find", function() {}); /*不傳參*/
addMethod(people, "find", function(a) {}); /*傳一個*/
addMethod(people, "find", function(a, b) {}); /*傳兩個*/

還有一個問題,就是這個全局的addMethod方法該怎么實現呢邮丰?如下所示

function addMethod(object, name, fn) {
  var old = object[name]; //把前一次添加的方法存在一個臨時變量old里面
  object[name] = function() { // 重寫了object[name]的方法
    // 如果調用object[name]方法時行您,傳入的參數個數跟預期的一致,則直接調用
    if(fn.length === arguments.length) {
      return fn.apply(this, arguments);
    // 否則剪廉,判斷old是否是函數娃循,如果是,就調用old
    } else if(typeof old === "function") {
      return old.apply(this, arguments);
    }
  }
}

現在斗蒋,我們一起來分析一個這個addMethod函數捌斧,它接收3個參數,第一個為要綁定方法的對象泉沾,第二個為綁定的方法名稱捞蚂,第三個為需要綁定的方法(一個匿名函數)。函數體的的分析已經在注釋里面了跷究。
OK姓迅,現在這個addMethod方法已經實現了,我們接下來就實現people.find的重載啦!全部代碼如下:

//addMethod
function addMethod(object, name, fn) {
  var old = object[name];
  object[name] = function() {
    if(fn.length === arguments.length) {
      return fn.apply(this, arguments);
    } else if(typeof old === "function") {
      return old.apply(this, arguments);
    }
  }
}
 
 
var people = {
  values: ["Dean Edwards", "Alex Russell", "Dean Tom"]
};
 
/* 下面開始通過addMethod來實現對people.find方法的重載 */
 
// 不傳參數時肩杈,返回peopld.values里面的所有元素
addMethod(people, "find", function() {
  return this.values;
});
 
// 傳一個參數時解寝,按first-name的匹配進行返回
addMethod(people, "find", function(firstName) {
  var ret = [];
  for(var i = 0; i < this.values.length; i++) {
    if(this.values[i].indexOf(firstName) === 0) {
      ret.push(this.values[i]);
    }
  }
  return ret;
});
 
// 傳兩個參數時,返回first-name和last-name都匹配的元素
addMethod(people, "find", function(firstName, lastName) {
  var ret = [];
  for(var i = 0; i < this.values.length; i++) {
    if(this.values[i] === (firstName + " " + lastName)) {
      ret.push(this.values[i]);
    }
  }
  return ret;
});
 
// 測試:
console.log(people.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]
console.log(people.find("Dean")); //["Dean Edwards", "Dean Tom"]
console.log(people.find("Dean Edwards")); //["Dean Edwards"]
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末晕窑,一起剝皮案震驚了整個濱河市敞斋,隨后出現的幾起案子植捎,更是在濱河造成了極大的恐慌焰枢,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異低滩,居然都是意外死亡,警方通過查閱死者的電腦和手機昏兆,發(fā)現死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來死讹,“玉大人,你說我怎么就攤上這事愧旦。” “怎么了琼蚯?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長罚拟。 經常有香客問我赐俗,道長阻逮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上价捧,老公的妹妹穿的比我還像新娘脯倚。我一直安慰自己推正,他們只是感情好掌测,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布产园。 她就那樣靜靜地躺著汞斧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪什燕。 梳的紋絲不亂的頭發(fā)上粘勒,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音屎即,去河邊找鬼庙睡。 笑死,一個胖子當著我的面吹牛技俐,可吹牛的內容都是我干的乘陪。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼雕擂,長吁一口氣:“原來是場噩夢啊……” “哼啡邑!你這毒婦竟也來了?” 一聲冷哼從身側響起井赌,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤谤逼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后仇穗,有當地人在樹林里發(fā)現了一具尸體流部,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年纹坐,在試婚紗的時候發(fā)現自己被綠了枝冀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宾茂,靈堂內的尸體忽然破棺而出瓷马,到底是詐尸還是另有隱情,我是刑警寧澤跨晴,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布欧聘,位于F島的核電站窝撵,受9級特大地震影響夭禽,放射性物質發(fā)生泄漏拜马。R本人自食惡果不足惜壶硅,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一群叶、第九天 我趴在偏房一處隱蔽的房頂上張望纬霞。 院中可真熱鬧溉知,春花似錦圣蝎、人聲如沸焚鹊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽末患。三九已至研叫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間璧针,已是汗流浹背嚷炉。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留探橱,地道東北人申屹。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像隧膏,于是被迫代替她去往敵國和親哗讥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容

  • [愛心]心在哪里胞枕,收獲就在哪里杆煞。 人這一生能力有限,但是努力無限曲稼, 努力做一個善良的人索绪, 做一個心態(tài)陽光的人, 做...
    愛心客站閱讀 135評論 0 1
  • 分析暫時不介紹
    52_St閱讀 643評論 0 0
  • 昨晚老公跟他朋友喝酒喝到凌晨兩點到家贫悄,他把我叫醒瑞驱,看他心情極差。因為兒子最近學業(yè)很苦窄坦,他打電話給前妻唤反,希望對方來關...
    多多少少7閱讀 257評論 0 3