Javascript學(xué)習(xí)筆記-語法和補(bǔ)充

Javascript語法和補(bǔ)充.png

1. 語句和表達(dá)式

Javascript中語句相當(dāng)句子,表達(dá)式相當(dāng)于短語,例如:var a = 1;,整個這一個包含兩個表達(dá)式var a, a = 1 , 合起來組成了一個語句

1.1 語句結(jié)果值

對于每一個語句存在一個結(jié)果值,通常結(jié)果值是undefined,實際上結(jié)果是最后一個語句的最后一個外部變量相關(guān)表達(dá)式的值,在Chrome控制臺中可以看到:

// 直接輸出1,因為是操作外部變量a的表達(dá)式
if (true) {
  a = 1;
} 
// 控制臺輸出undefined,因為a并不是語句外部的變量
if (true) {
  var a = 1;
}
// 控制臺輸出2,因為最后一個是語句2,是操作語句2的一個外部變量a的表達(dá)式
if (true) { // 語句1
    a = 1;
    if (true) { // 語句2
        var a = 2;
    }
}
// 這個時候控制臺輸出undefined,因為最后一個是語句2,a不是語句2的外部變量
if (true) { // 語句1
    a = 1;
    if (true) { // 語句2
        a = 2;
    }
}

如果我們想獲取到當(dāng)前的語句結(jié)果值,可以使用eval函數(shù)獲取,其中ES7規(guī)范提供了新的do表達(dá)式獲?。ú]有進(jìn)行測試)

var b = eval('if(true){ a = 2}');
console.log(b); // 2;
var c = do { if(true) { a = 2}};
console.log(c); // 2;

1.2 表達(dá)式的副作用

表達(dá)式在使用的過程中可能會產(chǎn)生副作用,也就是會改變變量的值

var a = 1;
var b = a++;
console.log(b); // 1
console.log(a); // 2

上面的例子中a首先將值賦給了b,然后進(jìn)行了自增,對自身的值進(jìn)行了改變,這里b只能獲取到a自增之前的值,如果想在一個賦值語句中讓b賦值為a自增后的值,除了在a自增后進(jìn)行再次進(jìn)行賦值以外,可以可以使用,來簡化寫法

var a = 1;
var b = (a++, a);
console.log(b); // 2
console.log(a); // 2;

1.3 代碼塊

  • 使用大括號{}可以創(chuàng)建字面量的對象,也可以創(chuàng)建一個代碼塊,并創(chuàng)建一個標(biāo)簽,結(jié)合breakcontinue,使得語句運(yùn)行可以跳到這個定義的標(biāo)簽處,如果使用continue label,會繼續(xù)執(zhí)行下一次語句,如果用break label,則會直接跳過當(dāng)前語句

// 如果使用continue
{
    label: for(let i = 0; i< 2; i++){
      for(let j = 0; j < 2; j++) {
        console.log(`i:${i}-j:${j}`);
        if(j === 1) {
          continue label; 
        }
      }
    }
 }
// 上面的輸出為
// i:0-j:0 
// i:0-j:1
// i:1-j:0
// i:1-j:1

// 如果使用break
{
    label: for(let i = 0; i< 2; i++){
      for(let j = 0; j < 2; j++) {
        console.log(`i:${i}-j:${j}`);
        if(j === 1) {
          break label; 
        }
      }
    }
 }
// 上面的輸出為
// i:0-j:0 
// i:0-j:1
  • 使用大括號{}在進(jìn)行運(yùn)算的時候,如果大括號在語句的最前端,則它會被解析為一個代碼塊,從而會忽略掉該部分內(nèi)容

{} + '2' === 2; // 語句結(jié)果值為true, 相當(dāng)于執(zhí)行了一元運(yùn)算符 +'2' 操作
  • ES6中運(yùn)用大括號{}可以進(jìn)行解構(gòu)賦值操作

// 對于對象賦值解構(gòu)
var obj = {a: 1, b: 2};
var {a, b} = obj;
console.log(a); // 1
console.log(b): // 2
// 對于函數(shù)參數(shù)解構(gòu)
function f({a, b, c}){
  console.log(a, b, c);
}
f({a:1, b: 2, c: 3}); // 1 2 3

1.4 try finally語句

try finallyfinally語句中的代碼一定會進(jìn)行執(zhí)行,但是如果finally存在拋出異?;蛘叻祷刂担敲丛镜姆祷刂禃粡U棄/覆蓋,最終結(jié)果為finally中的返回值

function f() {
  try {
      return 1;
  } finally {
      // throw Error('err');
      return 2; 
  }
}
console.log(f()); // 2,原本返回值1被覆蓋

1.5 switch語句

switch語句中的case比較為嚴(yán)格比較(===比較),如果需要使用寬松比較(==),可以將switch值設(shè)置為true,在case條件中使用寬松比較

var a = '2';
switch(a) {
  case 1:
    console.log('case 1');
    break;
  default:
    console.log('default');
}
// 輸出 default
var a = '1';
switch(true) {
  case a == 1:
    console.log('case 1');
    break;
  default:
    console.log('default');
}
// 輸出 case 1

2. 運(yùn)算符

2.1 優(yōu)先級

運(yùn)算符的優(yōu)先級影響不同運(yùn)算符之間的組合規(guī)則,優(yōu)先級越高的,越先組合在一起,其中&& > || > ?:

var a = false ? 3 : 4 && 5; 
console.log(a); // 5 由于&&優(yōu)先級大于?: , 所以相當(dāng)于false ? 3: (4 && 5)

2.2 關(guān)聯(lián)

運(yùn)算符的關(guān)聯(lián)影響相同運(yùn)算符之間的組合規(guī)則,&&|| 是左關(guān)聯(lián),也就是左邊先組合,?: 是右關(guān)聯(lián),也就是右邊先組合

var a = 1 && 2 && 3;
console.log(a); // 3 相當(dāng)于 (1 && 2) && 3
var a = true ? true: false ? false: true
console.log(a); // true 相當(dāng)于 true ? true: (false ? false: true);

3. 其他

3.1 自動分號ASI

Javascript為了提高容錯率,如果在每一行換行處缺少分號,會自動在換行后增加分號

3.2 函數(shù)中的arguments

函數(shù)中的arguments在非嚴(yán)格模式下和形參存在關(guān)聯(lián),修改后會對形參進(jìn)行修改,在嚴(yán)格模式下,則不存在關(guān)聯(lián)關(guān)系,不會影響到形參的值

function f(a) {
  arguments[0] = 2;
  console.log(a);
  console.log(arguments[0]);
}
f(1); // 2 2
'use strict'
function f(a) {
  arguments[0] = 2;
  console.log(a);
  console.log(arguments[0]);
}
f(1); // 1 2

3.3 宿主環(huán)境

宿主環(huán)境是指Javascript的運(yùn)行環(huán)境,不同的宿主環(huán)境中會有不同的內(nèi)置對象,例如:瀏覽器中有HTMLDivElement,而node環(huán)境中則沒有;瀏覽器中全局變量為window,而node環(huán)境中為global
同時控制臺對象(console對象)也是根據(jù)宿主環(huán)境進(jìn)行變化的,瀏覽器中是開發(fā)者控制臺輸出,而node中是標(biāo)準(zhǔn)的輸出

3.4 全局DOM變量

在瀏覽器環(huán)境中,HTML的節(jié)點(diǎn)中定義id屬性,會創(chuàng)建一個全局變量

// html中
<input id="a"/>
// js中
console.log(a); // 會直接打印該DOM節(jié)點(diǎn)對象

3.5 原生函數(shù)

Javascript的內(nèi)置函數(shù),不建議直接操作內(nèi)置函數(shù)(包括增加新的屬性和原型鏈擴(kuò)展),如果實在需要進(jìn)行擴(kuò)展,可以加上判斷條件后會相對安全

(function(){
  if(!Array.prototype.a) {
      Array.prototype.a = function() {};
  }
})()

但是即使加上判斷條件也無法確保該方法執(zhí)行結(jié)果一定為我們所想要的擴(kuò)展方法,所以,可以加上測試代碼來確保擴(kuò)展方法的正確性。

(function(){
  if(!Array.prototype.a) {
      Array.prototype.a = function() { return 1};
      return;
  } else { // 例如我們想要a方法返回1
      var a = [];
      if (a.a === 1) { // 等于1的時候滿足我們的需求
        return;
      }
  }
  throw Error('error');
})()

3.6 <script>元素

<script>元素之間共享一個全局變量:

<script>
    var a = 1;
</script>
<script>
    console.log(a); // 1
</script>

但是變量聲明的提升作用不會跨<script>提升到最前:

<script>
    console.log(a); // 拋出異常
</script>
<script>
    var a = 1;
</script>

每個運(yùn)行過程是獨(dú)立的,一個出錯不會導(dǎo)致其他的停止運(yùn)行:

<script>
    throw Error('error');
</script>
<script>
    var a = 1;
    console.log(1); // 仍然會執(zhí)行輸出結(jié)果
</script>

script中的語句不能包含</script>字符串,否則會作為script的結(jié)束標(biāo)簽解析而結(jié)束

3.7 保留字

Javascript中關(guān)鍵字,預(yù)留關(guān)鍵字,基本類型等不能作為變量名使用

3.8 限制

Javascript對于一些數(shù)據(jù)存在限制,例如字符串的最大長度,函數(shù)的參數(shù)最大個數(shù),變量名的最大長度,阻塞的最大時常等

4. 參考

《你不知道的Javascript(中卷)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容