JavaScript入門——語言基礎(chǔ)(一)

1.1 該如何對待 JavaScript

JavaScript 就是 JavaScript。要用 JavaScript 的方式寫 JavaScript失受。不要強(qiáng)制使用任何范式,特別是 OOP纯续。

JavaScript 中最強(qiáng)大的兩點是對象和函數(shù)蔬充。JavaScript 的對象不需要類即可存在。多數(shù)情況下普通對象就可以完成任務(wù)笛匙。原型繼承(prototypal inheritance)也足以快速滿足常見需求侨把。真正的 OOP 語法、類妹孙、繼承只有在必要的使用才需要使用秋柄,且此時應(yīng)使用 class 語法,不要自己制造新語法糖蠢正。

JavaScript 函數(shù)是一等公民骇笔。JavaScript 是第一個主流的 lambda 語言。

1.2 基礎(chǔ)語法

兩種注釋:/* *///嚣崭。

除非必要笨触,否則不要使用分號。

1.3 變量定義

常量(ES6)

const MYCONSTANT = "After declaration no changing"

變量

定義變量雹舀,可以使用 let(ES6) 和 var芦劣。

二者的區(qū)別是 let 定義的變量具有塊級作用域,var 定義的變量具有詞法作用域(函數(shù)作用域)说榆。塊級作用域由塊級語句(if / for / while / try)或大括號({})形成虚吟。而函數(shù)作用域指一個函數(shù)內(nèi)都是同一個作用域,不管里面是否有嵌套的塊娱俺。

現(xiàn)在稍味,一律使用 let,不要使用 var荠卷。

例子模庐,下面兩個 x 是兩個獨(dú)立的變量,在各自的作用域中油宜。(內(nèi)層變量與外層同名是不好的習(xí)慣掂碱,這里僅是演示,不要這樣做I髟)

let x = 10
{
    let x = 20
    console.log(x) // 20
}
console.log(x) // 10

下面的代碼疼燥,兩個 a 實際是同一個。

function test() {
    var a = 10
    if(something) {
        var a = 20
    }
    console.log(a) // 20
}

上面的例子也說明蚁堤,var 允許在被一個作用域內(nèi)被重復(fù)定義醉者,但 let 不允許。

function test() {
    var b = 1
    var b = 2 // 可以
    let a = 10
    let a = 20 // 報錯!
}

varlet 還有一個區(qū)別撬即,var 允許定義在使用之后立磁,而 let 不允許。原因是剥槐,var 定義的變量在運(yùn)行時會被提到函數(shù)作用域的頂部先執(zhí)行唱歧,不管它出現(xiàn)的實際位置。比如

function test() {
    console.log(b) // undefined 但不報錯
    b = 20
    console.log(b) // 20
    var b = 10
    console.log("hello")
    var c = 20
}

因為在運(yùn)行時(或者說預(yù)編譯期)粒竖,所有 var 會被提到函數(shù)頂部(賦值不會提前)颅崩,效果相對于:

function test() {
    var b,c
    console.log(b) // undefined 但不報錯
    b = 20
    console.log(b) // 20
    b = 10
    console.log("hello")
    c = 20
}

因此過去,使用 var 的時代蕊苗,建議把所有的變量定義放在函數(shù)開始沿后,以免造成錯覺。(CoffeeScript 等方言編譯結(jié)果會自動這樣做朽砰。)

最后再強(qiáng)調(diào)得运,let 定義的變量必須先定義再使用。

1.4 JavaScript 類型概述

JavaScript 是弱類型的锅移、動態(tài)類型的。弱類型的意思是饱搏,定義變量時不需要指定變量類型非剃。動態(tài)類型的意思是,一個變量可以持有不同類型的值推沸,如:

let a = 10
a = "aaa"

狹義講备绽,JavaScript 類型包括:布爾、數(shù)字鬓催、字符串肺素、undefined、對象宇驾、函數(shù)倍靡。

注意 null、數(shù)組课舍、正則表達(dá)式的類型都是 "object"塌西。

typeof true  // "boolean"
typeof 1  // "number"
typeof "a"  // "string"

typeof (new Date())  // "object"
typeof null  // "object"

typeof undefined  // "undefined"

typeof [] //  "object"
typeof {} //  "object"
typeof /good/  // "object"

typeof function(){}  // "function"

布爾有兩個值 truefalse

對象通過引用來傳遞筝尾。它們永遠(yuǎn)不會被拷貝捡需。

字面量

字面量包括數(shù)字字面量、字符串字面量筹淫、對象字面量站辉、數(shù)組字面量、函數(shù)字面量、正則表達(dá)式字面量饰剥。

對象字面量殊霞,如:{a: 1, b: true}。數(shù)組字面量捐川,如:[1, 2, 'a', 4]脓鹃。

正則表達(dá)式字面量被兩個斜杠包圍。如:/(.*)[a-z]/古沥。

1.5 數(shù)字

JavaScript 只有一種數(shù)字類型瘸右。內(nèi)部表示為 64 位的浮點數(shù)。沒有單獨(dú)的整數(shù)岩齿,因此 1 和 1.0 是相同值太颤。

二進(jìn)制浮點數(shù)不能正確處理十進(jìn)制小數(shù)。因此 0.1 + 0.2 不等于 0.3盹沈。這是 JavaScript 經(jīng)常被報告的 BUG龄章,并且它是遵循二進(jìn)制浮點數(shù)算術(shù)標(biāo)準(zhǔn)(IEEE 754)而有意導(dǎo)致的結(jié)果。

幸好浮點運(yùn)算中的整數(shù)運(yùn)算是精確的乞封,可以通過擴(kuò)大精度避免小數(shù)做裙。如將貨幣單位設(shè)為分而不是元。

如果確定只有整數(shù)肃晚,可以直接使用 === > 等比較兩個變量或值是否相等锚贱。如果有小數(shù)部分,判斷相等最好使用插值法:

if( a - b > 1e-10 )...

NaNInfinity

JavaScript 在運(yùn)算發(fā)生上溢关串、下溢或除零操作時不會報錯拧廊。

當(dāng)運(yùn)算符結(jié)果超過了 JavaScript 所能表示的數(shù)字上限(溢出)(1.79769313486231570e+308),結(jié)果為一個特殊的無窮大的值晋修,即 Infinity吧碾。同樣的,當(dāng)負(fù)數(shù)超過能表示的范圍墓卦,結(jié)果為負(fù)無窮大倦春,用 -Infinity 表示。無窮大的值的加減乘除運(yùn)算的結(jié)果仍為無窮大趴拧。

下溢即運(yùn)算結(jié)果無限接近于零比 JavaScript 能表示的最小值還小的時候發(fā)生溅漾。此時 JavaScript 返回零。

被零整除并不報錯著榴,返回 Infinity-Infinity添履。

但零除以零是沒有意義的,結(jié)果是 NaN脑又。無窮大除以無窮大暮胧、給任意負(fù)數(shù)開方運(yùn)算或算數(shù)運(yùn)算符與不是數(shù)字或無法轉(zhuǎn)換為數(shù)字的操作數(shù)一起使用時都將返回 NaN锐借。typeof NaN === 'number'

只能使用 isNaN 函數(shù)判斷一個值是否為數(shù)字。NaN 不等于自己。

NaN === NaN    // false
NaN !== NaN    // true

isNaN(NaN)       // true
isNaN(0)         // false
isNaN('oops')    // true
isNaN('0')       // false

判斷一個值是否可用于數(shù)字運(yùn)算的最佳方式是使用 isFinite() 函數(shù)叶圃,因為它會篩選掉 NaNInfinity。不幸的是布轿,如果操作數(shù)不是數(shù)字,isFinite() 會試圖將操作數(shù)轉(zhuǎn)換為數(shù)字来颤。因此汰扭,最好定義函數(shù):

function isNumber(value) {
    return typeof value === 'number' && isFinite(value)
}

1.6 字符串

字符串字面量可以被包圍在單引號或雙引號中。

Javascript 沒有字符類型(只有字符串)福铅。

字符串有一個 length 屬性萝毛。

字符串是不可變的。

可以使用 + 連接字符串滑黔。

模板字符串(ES6)

`This is a pretty little template string.`

// 多行
`In ES5 this is
 not legal.`

// 插值
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

// 綜合例子:
GET`http://foo.org/bar?a=${a}&b=$笆包
    Content-Type: application/json
    X-Credentials: ${credentials}
    { "foo": ${foo},
      "bar": ${bar}}`(myOnReadyStateChangeHandler);

1.7 對象

對象字面量即通過 {} 定義的對象。

在對象字面量中略荡,若屬性名是一個合法的 JavaScript 標(biāo)識符且不是保留字庵佣,可以不使用引號括住屬性名 。例如汛兜,"first–name" 的引號是必需的秧了,first_name 可以不用引號。

ES5 允許對象字面量最后由一個多余的逗號序无,但在 IE 下會報錯。

增強(qiáng)的對象字面量(ES6)

簡寫 foo: foo 形式的賦值:

var a = 1
var obj = { a: a }
// 等價于
var obj = { a }

定義方法:

var obj = {
    work: function() {}
}
// 等價于
var obj = {
    work() {}
}

調(diào)用父類方法:

var obj = {
    toString() {
        return "d " + super.toString()
    }
}

計算的(動態(tài)的)屬性名:

var fieldName = "aaa"
var obj = {[fieldName]: 1}
// 等價于
var obj = {}
obj[fieldName] = 1

訪問字段

如果字符串是一個合法的 JavaScript 標(biāo)識符且非保留字衡创,可以使用 . 否則應(yīng)使用中括號帝嗡。

stooge["first-name"]
flight.departure.IATA

如果檢索的屬性不存在,返回 undefined璃氢;注意不是 null哟玷。

嘗試從不存在的對象(undefined)讀取字段將拋出 TypeError 異常∫灰玻可以使用 && 預(yù)作判斷巢寡。

flight.equipment // undefined
flight.equipment.model // throw "TypeError"
flight.equipment && flight.equipment.model // undefined

1.8 nullundefined

判斷一個值是否是 null,直接使用 ===

my_value === null

undefined 這個值盡量不要自己使用椰苟。但仍有時候值可能是 undefined抑月。比如訪問一個不存在的屬性,返回 undefined舆蝴。沒有返回值的方法谦絮,賦值給一個變量题诵,得到 undefined

要判斷一個屬性是否存在层皱,值為 null 也算存在性锭,可以用 in 運(yùn)算符:

var a = { b: 1, d: null }
"b" in a // true
"c" in a // false
"d" in a // true

如果一定要判斷值是否為 undefined,可以檢測 typeof v === "undefined"叫胖。

1.9 數(shù)組

JavaScript 中沒有真正的數(shù)組草冈,而是提供一些類數(shù)組的對象。它把數(shù)組下表轉(zhuǎn)換為字符串瓮增,用其作為屬性怎棱。它明顯比真正的數(shù)組慢。

JavaScript 本身對于數(shù)組和對象的區(qū)別是混亂的钉赁。typeof 運(yùn)算符報告數(shù)組的類型是 'object'蹄殃,這沒有什么意義。

數(shù)組字面量

方括號內(nèi)你踩,逗號分隔诅岩。

var empty = []
var numbers = [ 'zero', 'one', 'two', 'three', 'four' ]

empty[1]          // undefined
numbers[1]        // 'one'

empty.length      // 0
numbers.length    // 5

數(shù)組下標(biāo)以 0 開始。

數(shù)組字面量繼承自(原型是)Array.prototype带膜。

允許數(shù)組元素為混合類型(JavaScript 是弱類型):

var misc = [ 'string', 98.6, true, false, null, undefined, ['nested', 'array'] ]

JavaScript 沒有多維數(shù)組吩谦,但支持元素為數(shù)組的數(shù)組:

var matrix = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8]
];
matrix[2][1] // 7

讀寫數(shù)組元素

下標(biāo)運(yùn)算符 [] 將其中的表達(dá)式轉(zhuǎn)換為一個字符串,轉(zhuǎn)換使用表達(dá)式的 toString 方法膝藕。產(chǎn)生的字符串將作為屬性名式廷。

因為數(shù)字的下標(biāo)最終會被轉(zhuǎn)換為一個“鍵”。因此數(shù)組允許越界訪問芭挽,或者說任意訪問滑废。例如開始有:

var arr = ["a", "b"]

讀取 arr[10] 時,因為以 10 為鍵的元素不存在袜爪,因此得到 undefined蠕趁。

arr[10] = "xxx",給數(shù)組第 11 個元素賦值辛馆,相對于將數(shù)組長度擴(kuò)大到 11俺陋。此時 arr[2]arr[9] 都是 undefinedlength 屬性為 11昙篙。

直接給 length 賦值腊状,相當(dāng)于將數(shù)組設(shè)為指定大小。這個可以比原數(shù)組更大(相對于擴(kuò)大)或更刑伞(相對于截短)缴挖。

向數(shù)組最后追加元素的方法是 push()

numbers.push('go')
// numbers is ['zero', 'one', 'two', 'shi', 'go']

刪除

使用 delete 刪除數(shù)組元素,但會留下“空洞”焚辅。delete 不是從數(shù)組中移除一個元素(后續(xù)元素上提)醇疼,而是將指定位置上的值置為 undefined硕并。

delete numbers[2]
// numbers is ['zero', 'one', undefined, 'shi', 'go']

splice() 用于去除數(shù)組中一部分。第一個參數(shù)指定開始刪除的位置秧荆,第二個參數(shù)指定刪除個數(shù)倔毙。

numbers.splice(2, 1)
// numbers is ['zero', 'one', 'shi', 'go']

要對被刪除的元素之后的每個元素調(diào)整下標(biāo)值,對大數(shù)組來說效率很低乙濒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末陕赃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子颁股,更是在濱河造成了極大的恐慌么库,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甘有,死亡現(xiàn)場離奇詭異诉儒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)亏掀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門忱反,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人滤愕,你說我怎么就攤上這事温算。” “怎么了间影?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵注竿,是天一觀的道長。 經(jīng)常有香客問我魂贬,道長巩割,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任付燥,我火速辦了婚禮喂分,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘机蔗。我一直安慰自己,他們只是感情好甘萧,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布萝嘁。 她就那樣靜靜地躺著,像睡著了一般扬卷。 火紅的嫁衣襯著肌膚如雪牙言。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天怪得,我揣著相機(jī)與錄音咱枉,去河邊找鬼卑硫。 笑死,一個胖子當(dāng)著我的面吹牛蚕断,可吹牛的內(nèi)容都是我干的欢伏。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼亿乳,長吁一口氣:“原來是場噩夢啊……” “哼硝拧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起葛假,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤障陶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后聊训,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抱究,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年带斑,在試婚紗的時候發(fā)現(xiàn)自己被綠了鼓寺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡遏暴,死狀恐怖侄刽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情朋凉,我是刑警寧澤州丹,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站杂彭,受9級特大地震影響墓毒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜亲怠,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一所计、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧团秽,春花似錦主胧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至图毕,卻和暖如春夷都,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背予颤。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工囤官, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留冬阳,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓党饮,卻偏偏與公主長得像肝陪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子劫谅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line)见坑,也就是一...
    悟名先生閱讀 4,153評論 0 13
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,238評論 0 4
  • 前一天睡得很早,剛醒時狀態(tài)也不錯捏检,不過起床時還是有點困…… 今天基本沒啥活干荞驴,所以基本是摸魚的節(jié)奏,隨著自己的任務(wù)...
    真晝之月閱讀 105評論 0 0
  • 觀后感贯城,《我在故宮修文物》熊楼,很多人求而不得的生活美學(xué)。 這也許不是傳統(tǒng)意義上的好電影能犯,沒有故事鲫骗,沒有特效,沒有服化...
    孟園閱讀 150評論 0 0
  • http://www.chaishubang.com/memoirs/memoirsinfo/771
    Fly_Catkin閱讀 195評論 0 0