基礎(chǔ)一

詞法結(jié)構(gòu)

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

類型, 值和變量

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

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

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

轉(zhuǎn)譯字符

轉(zhuǎn)義字符 | 含義
----|------|----
\o | NUL字符
\b | 退格符
\t| 水平制表符
\n| 換行符
\v| 垂直制表符
\f| 換頁符
\r| 回車符
"| 雙引號
'| 單引號
\|反斜線
\xXX| 由兩位十六進制數(shù)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首次出現(xiàn)的位置

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

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

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

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

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

布爾值

轉(zhuǎn)換為false的變量: undefined, null, NaN, 0, -0, ""

null和undefined

null代表空指針, 通常用來表示數(shù)字, 字符串和對象的"無值狀態(tài)"

undefined代表未初始化.

全局對象

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

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

構(gòu)造函數(shù): 比如Date(), RegExp(), String(), Object()和Array()

全局對象: 比如Math和JSON

包裝對象

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

var s = "hello world"

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

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

var s = "test"

s.len = 4 //給對象設(shè)置屬性

var t = s.len

t ==> undefined

而:

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

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

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

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

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

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的值本質(zhì)上并不相同, 因為o/p中存儲的是{x: 1}的引用, 而非具體的值. 而{x: 1}和另一個{x: 1}的引用是不相等的.

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

類型轉(zhuǎn)換
字符串 數(shù)字 布爾值 對象
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首字母必須大寫,不然認為是變量

轉(zhuǎn)換和相等性
進行"=="判斷時, JavaScript會進行類型轉(zhuǎn)換.

null == undefined ==> true

"0" == 0 ==> true

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

而"0" == 0, 是將數(shù)字0轉(zhuǎn)換為字符串"0", 然后再進行比較.

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

顯示類型轉(zhuǎn)換
JavaScript在需要字符串情況下, 會將變量轉(zhuǎn)換為字符串; 其次, 在需要數(shù)字情況下, 會將變量轉(zhuǎn)換為數(shù)字.

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

var n = 17

n.toString() ==> "17"

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

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

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

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

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

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

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(): 盡可能的將字符串轉(zhuǎn)換為整數(shù), 可接收第二個可選參數(shù), 這個參數(shù)指定數(shù)字轉(zhuǎn)換的基數(shù).

parseFloat(): 盡可能的將字符串轉(zhuǎn)換為浮點數(shù).

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

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

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

JavaScript中對象到字符串的轉(zhuǎn)換經(jīng)歷以下步驟:

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

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

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

對象到數(shù)字的轉(zhuǎn)換經(jīng)歷以下步驟:

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

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

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

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

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

var a = "hello"

b = "world" //相當(dāng)于給window對象添加了屬性b

delete a ==> false

delete b ==> true

a ==> "hello"

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

表達式和運算符

表達式

數(shù)組初始化時, 如果使用逗號(","), 則初始化為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"}

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

var arr = [12, 13, 14]

arr["1"] ==> 13

arr[1] ==> 13

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

var MY_APP_1 = function() {

  this.firstMethod = function() {};

  this.secondMethod = function() {};

};

 

var MY_APP_2 = {

  firstKey: functon() {},

  secondKey: function() {}

};

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

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

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

  2. 在創(chuàng)建具體實例后, 如果沒有綁定一個具體的對象, 則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運算符通常會根據(jù)操作數(shù)進行類型轉(zhuǎn)換, 所以"3" * "5"是合法的, 為數(shù)字15.
  2. 加號既可用于字符串連接, 也可用于數(shù)字的相加, 但優(yōu)先于字符串連接. 所以將數(shù)組轉(zhuǎn)換為字符串時, 我們可以編寫如下的代碼:
var arr = [1,2,3]

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

但我們?nèi)绻麅H僅將一個字符串轉(zhuǎn)換為數(shù)字, 也可以使用如下的技巧:

+"3" ==> 3

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

x typeof x
undefined "undefined"
null "object"
true 或false "boolean"
任意數(shù)字或NaN "number"
任意字符串 "string"
任意函數(shù) "function"
任意內(nèi)置對象(非函數(shù)) "object"
任意宿主對象 由編譯器自身決定
  1. delete用于刪除一個對象的屬性, 對數(shù)組來說相當(dāng)于賦值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]

語句

空語句(單獨一個分號)通常用在初始化一個數(shù)組中, 例如:
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循環(huán)并不會遍歷對象的所有屬性, 只有"可枚舉"的屬性才會遍歷到.

"use strict"

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

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

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

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

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