基礎一

詞法結構

  1. JavaScript程序是用Unicode字符集編寫的
  1. JavaScript是區分大小寫的, 而HTML不區分大小寫.
  2. JavaScript會忽略程序中標識之間的空格.
  3. JavaScript支持"http://"和"/.../"兩種注釋.
  4. 直接量: 程序中直接使用的數據值. JavaScript中的直接量為: 數值, 字符串, 布爾型和正則表達式.
  5. JavaScript的標識符必須以字母, 下劃線或者美元符號開始, 后續跟字母, 數字, 下劃線或者美元符號.
  6. JavaScript中關于填補分號的規則: 只要在缺少了分號就無法正確解析代碼的時候, JavaScript才會填補分號.

類型, 值和變量

概述
  1. JavaScript的數據類型分為兩類: 原始類型和對象類型. JavaScript的原始類型包括數字, 字符串和布爾值. 而對象是屬性的集合, 每個屬性都由"名/值對"組成.
  2. JavaScript中有兩個特殊的原始值:** null和undefined**, 它們不是數字,字符串和布爾值. 它們通常分別代表了各自特殊類型的唯一的成員. 原始類型, null和undefined均為不可變類型.
  3. 普通的JavaScript對象是"命名值"的無序集合, 可以使用Object.keys()獲取其keys(新版本可以使用Object.values()獲取其values). 而JavaScript定義了一種有序集合, 為數組.
var o={
            name:'張三',
            sex:'男',
            sayHello:function(){
                conosle.log("sayHello");
            }
        };
        console.log(Object.keys(o));
        console.log(Object.values(o));

結果:
Array [ "name", "sex", "sayHello" ]
Array [ "張三", "男", o.sayHello() ]

  1. JavaScript定義了另一種特殊對象--函數. 函數是具有與它相關聯的可執行代碼的對象, 通過調用函數來運行可執行代碼, 并返回運算結果.
  2. 如果函數用來初始化(使用new運算符)一個新建的對象, 我們稱之為構造函數. 每個構造函數定義了一類對象--由構造函數初始化的對象組成. 類可以看做是對象類型的子類型. 除了數組類和函數類之外, JavaScript語言核心還定義了三種有用的類: 日期(Date)類定義了代表日期的對象. 正則(RegExp)類定義了表示正則表達式的對象. 錯誤(Error)類定義了那些表示JavaScript程序中運行時錯誤和語法錯誤的對象.
  3. JavaScript解釋器有自己的內存管理機制, 可以自動對內存進行垃圾回收.
  4. JavaScript變量是無類型的, 變量可以被賦予任何類型的值. 使用var關鍵字來聲明變量, JavaScript采用詞法作用域, 不在任何函數內聲明的變量稱作全局變量, 它在JavaScript程序中的任何地方都是可見的. 在函數內聲明的變量具有函數作用域, 并且只在函數內可見.
數字
  1. JavaScript不區分整數值和浮點數值,** 所有數字均以浮點數值表示.**
  2. JavaScript中除以0并不報錯, 只是返回無窮大(Infinity)/負無窮大(-Infinity). 而0 / 0是沒有任何意義的, 所以用NaN表示(NaN代表非數字, 可用isNaN()判斷, 例如isNaN("hello")為true).
  3. JavaScript中浮點數依舊存在精度問題:(不能去比較浮點數是否相等)
        var x=0.3-0.2;
        var y=0.2-0.1;
        console.log(x);//0.09999999999999998
        console.log(y);//0.1
        x == y -->false
        x == 0.1-->false
        y == 0.1-->true
        0.07*100-->7.000000000000001
文本

轉譯字符

轉義字符 | 含義
----|------|----
\o | NUL字符
\b | 退格符
\t| 水平制表符
\n| 換行符
\v| 垂直制表符
\f| 換頁符
\r| 回車符
"| 雙引號
'| 單引號
\|反斜線
\xXX| 由兩位十六進制數xx指定的Latin-1字符
\uXXXX| 由四位十六進制XXXX指定的Unicode字符

字符串的使用
var s = "hello world"

  • s.charAt(0) ==> "h": 第一個字符

  • s.charAt(s.length - 1) ==> "d": 最后一個字符

  • s.substring(1, 4) ==> "ell": 第2~4個字符

  • s.slice(1, 4) ==> "ell": 同上

  • s.slice(-3) ==> "rld": 最后三個字符

  • s.indexOf("l") ==> 2: 字符l首次出現的位置

  • s.lastIndexOf("l") ==> 9: 字符l最后出現的位置

  • s.indexOf("l", 3) ==> 3: 在位置3及之后首次出現字符l的位置.

  • s.split(" ") ==> ["hello", "world"]: 分割字符串

  • s.replace("h", "H") ==> "Hello world": 替換

  • s.toUpperCase() ==> "HELLO WORLD": 轉換成大寫

布爾值

轉換為false的變量: undefined, null, NaN, 0, -0, ""

null和undefined

null代表空指針, 通常用來表示數字, 字符串和對象的"無值狀態"

undefined代表未初始化.

全局對象

全局屬性: 比如undefined, Infinity和NaN

全局函數: 比如isNaN(), parseInt()和eval()

構造函數: 比如Date(), RegExp(), String(), Object()和Array()

全局對象: 比如Math和JSON

包裝對象

對于字符串, 以下代碼是正確的:

var s = "hello world"

var word = s.substring(1, 4)
//此時s已被封裝成了對象,但是這句話執行完后,該對象立即銷毀

既然字符串不是對象, 它為什么會有substring方法呢? 因為引用字符串s的屬性, JavaScript就會將字符串通過調用new String(s)的方式裝換成對象, 一旦屬性引用結束, 這個新創建的對象就會銷毀(同理于Number()和Boolean()):

var s = "test"

s.len = 4 //給對象設置屬性

var t = s.len

t ==> undefined

而:

"hello" == new String("hello") ==> true//自動封裝

"hello" === new String("hello") ==> false//全等,一個值,一個是對象
不可變的原始值和可變的對象引用

原始值: undefined, null, 數字, 布爾值, 字符串. 它們均不可改變.
對象: 數組和函數, 可改變

原始值的比較只要通過"=="即可(原始值所存儲的內存地址是相同的, 而"=="是用于比較值是否相同, 所以對于原始值來說, 值相同+地址相同 == 它們相同)

對象的本質是引用, 所以只有引用同一個基對象(相同的內存地址)時, 它們才相同:

var o = {x: 1}, p = {x: 1}

o === p ==> false

o == p ==> false

q = o ==> Object {x: 1}//將o的引用賦值給q,此時他們指向同一個對象

q["y"] = 2 //q對象增加一個y=2的屬性,此時0對象也會增加該屬性

q === o ==> true

這里會造成一個困惑是: 為什么 o == p ==> false?

因為o和p的值本質上并不相同, 因為o/p中存儲的是{x: 1}的引用, 而非具體的值. 而{x: 1}和另一個{x: 1}的引用是不相等的.

備注: 我們一般比較對象是否具有某個屬性, in代表屬性存在于實例+原型中, 而hasOwnProperty代表屬性是否存在于實例中.

類型轉換
字符串 數字 布爾值 對象
undefined "undefined" NaN false throws TypeError
null "null" 0 false throws TypeError
true "true" 1 new Boolean(true)
false "false" 0 new Boolean(false)
"" 0 false new String("")
"1.2" 1.2 true new String("1.2")
"one" NaN true new String("one")
0 "0" false new Number(0)
-0 "0" false new Number(-0)
NaN "NaN" false new Number(NaN)
Infinity "Infinity" true new Number(Infinity)
-Infinity "-Infinity" true new Number(-Infinity)
1 "1" true new Number(1)
{} 后面解釋 后面解釋 true
[] "" 0 true
[9] "9" 9 true
['a'] 使用join方法 NaN true
['a','b'] "a,b" NaN true
function(){} 后面解釋 NaN true

注意:無窮大Infinity首字母必須大寫,不然認為是變量

轉換和相等性
進行"=="判斷時, JavaScript會進行類型轉換.

null == undefined ==> true

"0" == 0 ==> true

這里類型轉換代表的意思是: a == b, 則a轉換為b類型, 或者b轉換為a類型, 再次進行比較. 所以對于null == undefined, 本質上是undefined轉換為一個Object, 然后在和null進行比較.

而"0" == 0, 是將數字0轉換為字符串"0", 然后再進行比較.

但可以成功進行類型轉換, 不一定表示它們相等, 如undefined可轉換為false, 但undefined == false的結果為false.

顯示類型轉換
JavaScript在需要字符串情況下, 會將變量轉換為字符串; 其次, 在需要數字情況下, 會將變量轉換為數字.

Number類定義的toString()方法可以接收表示轉換基數的可選參數. 如果不指定此參數, 轉換規則將是基于十進制:

var n = 17

n.toString() ==> "17"

n.toString(2) ==> "10001"

n.toString(8) ==> "21"

n.toString(16) ==> "11"

toFixed(): 根據小數點后的指定位數將數字轉換為字符串, 它從不使用指數計數法.

toExponential(): 使用指數計數法將數字轉換為指數形式的字符串, 其中小數點前只有一位, 小數點后的位數則由參數指定.

toPrecision(): 根據指定的有效數字位數將數字轉換成字符串. 如果有效數字的位數少于數字部分的位數, 則轉為為指數形式.

var n = 123456.789

n.toFixed(0) ==> "123457"

n.toFixed(2) ==> "123456.79"

n.toFixed(5) ==> "123456.78900"

n.toExponential(1) ==> "1.2e+5"

n.toExponential(3) ==> "1.235e+5"

n.toPrecision(4) ==> "1.235e+5"

n.toPrecision(7) ==> "123456.8"

n.toPrecision(10) ==> "123456.7890"

parseInt(): 盡可能的將字符串轉換為整數, 可接收第二個可選參數, 這個參數指定數字轉換的基數.

parseFloat(): 盡可能的將字符串轉換為浮點數.

console.log(parseInt("111ads"))  //111

對象轉換為原始值
toString(): 返回一個反映這個對象的字符串.

valueOf(): 如果存在任意原始值, 它就默認將對象轉換為表示它的原始值.

JavaScript中對象到字符串的轉換經歷以下步驟:

如果對象具有toString()方法, 則調用這個方法. 如果它返回一個原始值, JavaScript將這個值轉換為字符串, 并返回這個字符串結果.
如果對象沒有toString()方法, 或者這個方法并不返回一個原始值, 那么JavaScript會調用valueOf()方法, 如果存在這個方法, 則JavaScript調用它. 如果返回值是原始值, JavaScript將這個值轉換為字符串, 并返回這個字符串結果.
否則, JavaScript拋出類型錯誤.

var o={
            toString:function(){
                return 9;
            },
            valueOf:function(){
                return 10;
            }
        };

        console.log(""+o);//結果是“10”

對象到數字的轉換經歷以下步驟:

如果對象具有valueOf()方法, 返回一個原始值, 則JavaScript將這個原始值轉換為數字.
否則, 如果對象具有toString()方法, 返回一個原始值, 則JavaScript將其轉換并返回(如果返回的原始值是boolean類型,會轉成0或1)
否則, JavaScript拋出類型錯誤.

var o={
            toString:function(){
                return 9;
            },
            valueOf:function(){
                return 10;
            }
        };

        console.log(+o);//結果是10

變量和作用域
JavaScript沒有塊級作用域, 它使用了函數作用域.

在JavaScript中, 使用var聲明的全局變量是不可配置的(變量本身具有屬性, 如是否可刪除, 編輯, 是否只讀等):

var a = "hello"

b = "world" //相當于給window對象添加了屬性b

delete a ==> false

delete b ==> true

a ==> "hello"

b ==> VM920:1 Uncaught ReferenceError: b is not defined(…)

表達式和運算符

表達式

數組初始化時, 如果使用逗號(","), 則初始化為undefined:

var arr = [1,,,2]

arr.length ==> 4

arr ==> [1, undefined × 2, 2]

如果針對對象來說, 使用字面量來初始化, 那么其key/value中的key代表的是字符串:

var key = "hello"

var d1 = {key: "world"}

d1 ==> Object {key: "world"}

這里d1的聲明等價于:

var d1 = {"key": "world"}

但如果使用索引來初始化, 則不一樣:

var key = "hello"

var d2 = {}

d2[key] = "world"

d2 ==> Object {hello: "world"}

數組本身就是一個支持下表索引的對象:

var arr = [12, 13, 14]

arr["1"] ==> 13

arr[1] ==> 13

使用new構造出一個對象不同于使用字面量構造出一個對象, 考慮如下的代碼:

var MY_APP_1 = function() {

  this.firstMethod = function() {};

  this.secondMethod = function() {};

};

 

var MY_APP_2 = {

  firstKey: functon() {},

  secondKey: function() {}

};

主要的不同點在于: 通過new, 我們可以創建多個MY_APP_1實例, 而每個實例均綁定到內部的this; 而對于MY_APP_2來說, 它僅僅只是一個變量而已.

針對MY_APP_1來說, 還有以下特殊的幾點:

  1. firstMethod/secondMethod是綁定到具體的實例上, 非綁定狀態下它們并不存在.

  2. 在創建具體實例后, 如果沒有綁定一個具體的對象, 則this默認綁定到window對象上:

var app1 = new MY_APP_1();

app1.firstMethod();

// ERROR

// window.firstMethod();

var app2 = MY_APP_1();

// ERROR

// app2.firstMethod();

window.firstMethod();

運算符

  1. JavaScript運算符通常會根據操作數進行類型轉換, 所以"3" * "5"是合法的, 為數字15.
  2. 加號既可用于字符串連接, 也可用于數字的相加, 但優先于字符串連接. 所以將數組轉換為字符串時, 我們可以編寫如下的代碼:
var arr = [1,2,3]

"" + arr ==> "1,2,3"

但我們如果僅僅將一個字符串轉換為數字, 也可以使用如下的技巧:

+"3" ==> 3

1.in運算符用于判斷屬性是否存在于對象實例+原型中.
2.instanceof運算符用于判斷左邊對象是否為右邊類的實例.
3.typeof運算符用于判斷對象的類型:

x typeof x
undefined "undefined"
null "object"
true 或false "boolean"
任意數字或NaN "number"
任意字符串 "string"
任意函數 "function"
任意內置對象(非函數) "object"
任意宿主對象 由編譯器自身決定
  1. delete用于刪除一個對象的屬性, 對數組來說相當于賦值undefined:
var o = {x: 1, y:2}

delete o.x

o ==> Object {y: 2}

var arr = [11, 12, 13]

delete arr[1]

arr ==> [11, undefined × 1, 13]

語句

空語句(單獨一個分號)通常用在初始化一個數組中, 例如:
for (var i = 0; i < a.length; a[i++] = 0) ;
var和function都是用來聲明語句的, 而function通常有兩種寫法:

var f = function(x) { return x + 1; } //將表達式賦值給一個變量

function f(x) { return x + 1; }

for/in循環并不會遍歷對象的所有屬性, 只有"可枚舉"的屬性才會遍歷到.

"use strict"

  1. 在嚴格模式中禁止使用with語句.
  2. 在嚴格模式中, 所有的變量都要先聲明, 否則將會拋出一個引用錯誤異常.
  3. 在嚴格模式中, 調用的函數中的一個this值是undefined.
  4. 在嚴格模式中, 當通過call()/apply()來調用函數時, 其中的this值就是通過call()或apply()傳入的第一個參數(在非嚴格模式中, null和undefined值被全局對象和轉換為對象的非對象值所代替)
  5. 在嚴格模式中, 給只讀屬性賦值和給不可擴展的對象創建新成員都將拋出一個類型錯誤異常.
  6. 在嚴格模式中, 傳入eval()的代碼不能在調用程序所在的上下文中聲明變量或定義函數, 而在非嚴格模式中是可以這樣做的.
  7. 在嚴格模式中, 函數里的arguments對象擁有傳入函數值的靜態副本, 即不可修改:
"use strict"

 

function f(arr) {

  f.arguments[0][0] = 11;

}

var arr = [1, 2, 3];

f(arr);

console.log(arr);

這里代碼將會報錯.

針對delete, 后跟非法的標識符將拋出一個語法錯誤異常; 如果試圖刪除一個不可配置的屬性將會拋出一個類型錯誤異常.

參考文獻:https://my.oschina.net/voler/blog/807507

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容

  • 第5章 引用類型(返回首頁) 本章內容 使用對象 創建并操作數組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,262評論 0 4
  • 1.HTML DOM (Document Object Model) document.getElementByI...
    廖馬兒閱讀 1,435評論 0 17
  • 我們在感嘆歲月的老去的時候,也該感謝時光對我們的給予。自古最難是兩全,許下的諾言沒有實現便就是欠下的債,我們經常在...
    流年_9df3閱讀 295評論 0 1
  • 沈華立,天貝車業,盛和塾224期學員,【日精打卡第110天】 《六項精進》1遍共210遍 《大學》1遍共210遍 ...
    沈華立閱讀 111評論 0 0
  • 這是我在簡書的第一篇小文,手機夜打 去年年底,也就是幾天前,我表白了 很開心,并不是因為結果(結果是婉拒(不過婉拒...
    現在就是哦哈哈閱讀 114評論 0 1