JavaScript基礎(chǔ)知識(一)

嘗試匯總下JavaScript的基礎(chǔ)知識

本文包括:

  • JavaScript簡介(1)
  • <script>標(biāo)簽(2)
  • 數(shù)據(jù)類型(3)
  • 變量與作用域(4)
  • 引用類型(5)

JavaScript簡介

1.JavaScript的組成:

一個完整的JavaScript由以下三部分組成:

  • 核心(ECMAScript)
  • 文檔對象模型(DOM)
  • 瀏覽器對象模型(BOM)
    image

1.1核心(ECMAScript)

1.2文檔對象模型(DOM)

DOM級別:

DOM級別可以分為四個:DOM0級寒锚、DOM1級、DOM2級和DOM3級违孝。
DOM1 級(DOM Level 1)于 1998 年 10 月成為 W3C 的推薦標(biāo)準(zhǔn)刹前。DOM1 級由兩個模塊組成:DOM核心(DOM Core)和 DOM HTML。其中雌桑,DOM 核心規(guī)定如何映射基于 XML 的文檔結(jié)構(gòu)喇喉,以便簡化對文檔中任意部分的訪問和操作。DOM HTML 模塊則在 DOM 核心的基礎(chǔ)上加以擴展校坑,添加了針對 HTML 的對象和方法拣技。DOM1 級的目標(biāo)主要是映射文檔的結(jié)構(gòu)。DOM2 級在原來 DOM 的基礎(chǔ)上又?jǐn)U充了(DHTML 一直都支持的)鼠標(biāo)和用戶界面事件耍目、范圍、遍歷(迭代 DOM文檔的方法)等細分模塊邪驮,而且通過對象接口增加了對 CSS(Cascading Style Sheets莫辨,層疊樣式表)的支持。DOM2 級引入了下列新模塊盘榨,也給出了眾多新類型和新接口的定義。

  • DOM 視圖(DOM Views):定義了跟蹤不同文檔(例如草巡,應(yīng)用 CSS 之前和之后的文檔)視圖的接口;
  • DOM 事件(DOM Events):定義了事件和事件處理的接口捷犹;
  • DOM 樣式(DOM Style):定義了基于 CSS 為元素應(yīng)用樣式的接口;
  • DOM 遍歷和范圍(DOM Traversal and Range):定義了遍歷和操作文檔樹的接口冕末。

DOM3 級則進一步擴展了 DOM,引入了以統(tǒng)一方式加載和保存文檔的方法——在 DOM 加載和保存(DOM Load and Save)模塊中定義档桃;新增了驗證文檔的方法——在 DOM 驗證(DOM Validation)模塊中定義。DOM3 級也對 DOM 核心進行了擴展藻肄,開始支持 XML 1.0 規(guī)范,涉及 XML Infoset嘹屯、XPath和 XML Base。除了 DOM 核心和 DOM HTML 接口之外州弟,另外幾種語言還發(fā)布了只針對自己的 DOM 標(biāo)準(zhǔn)钧栖。下面列出的語言都是基于 XML 的,每種語言的 DOM 標(biāo)準(zhǔn)都添加了與特定語言相關(guān)的新方法和新接口:

  • SVG(Scalable Vector Graphic婆翔,可伸縮矢量圖)1.0拯杠;
  • MathML(Mathematical Markup Language,數(shù)學(xué)標(biāo)記語言)1.0啃奴;
  • SMIL(Synchronized Multimedia Integration Language潭陪,同步多媒體集成語言)。

還有一些語言也開發(fā)了自己的 DOM 實現(xiàn)最蕾,例如 Mozilla 的 XUL(XML User Interface Language依溯,XML
用戶界面語言)。但是瘟则,只有上面列出的幾種語言是 W3C 的推薦標(biāo)準(zhǔn)誓沸。

DOM事件:

DOM事件分為3個級別:DOM0級事件處理,DOM2級事件處理和DOM3級事件處理壹粟。
1.DOM0級事件
最早的html的事件處理方式如下:

<button type="button" onclick="showFn()"></button>

<script>
    function showFn() {
        alert('Hello World');
    }
</script>

以上代碼直接在HTML代碼里定義了一個onclick觸發(fā)showFn方法拜隧,這樣的事件處理程序缺點就是HTML于JS強耦合宿百,我們一旦需要修改函數(shù)名就得修改兩個地方。當(dāng)然其優(yōu)點是不需要操作DOM來完成事件的綁定洪添。

DOM0級事件就是將一個函數(shù)賦值給一個事件處理屬性垦页,比如:

<button id="btn" type="button"></button>

<script>
    `var btn = document.getElementById('btn');`
    
    btn.onclick = function() {
        alert('Hello World');
    }
    
    // btn.onclick = null; 解綁事件 `
</script>

以上代碼我們給button定義了一個id,通過JS獲取到了這個id的按鈕干奢,并將一個函數(shù)賦值給了一個事件處理屬性onclick痊焊,這樣的方法便是DOM0級處理事件的體現(xiàn)。我們可以通過給事件處理屬性賦值null來解綁事件忿峻。

DOM0級事件處理程序的缺點在于一個處理程序無法同時綁定多個處理函數(shù)薄啥,比如我還想在按鈕點擊事件上加上另外一個函數(shù)。
2.DOM2級事件
DOM2級事件在DOM0級事件的基礎(chǔ)上彌補了一個處理程序無法同時綁定多個處理函數(shù)的缺點逛尚,允許給一個處理程序添加多個處理函數(shù)垄惧。代碼如下:

<button id="btn" type="button"></button>`
<script>
    var btn = document.getElementById('btn');
    function showFn() {
        alert('Hello World');
    }
    btn.addEventListener('click', showFn, false);
    // btn.removeEventListener('click', showFn, false); 解綁事件 
</script>

DOM2級事件定義了addEventListener和removeEventListener兩個方法,分別用來綁定和解綁事件绰寞,方法中包含3個參數(shù)到逊,分別是綁定的事件處理屬性名稱(不包含on)噪服、處理函數(shù)和是否在捕獲時執(zhí)行事件處理函數(shù)译仗。如果我們還需要添加一個鼠標(biāo)移入的方法,只需要:

btn.addEventListener('mouseover', showFn, false);
這樣點擊按鈕和鼠標(biāo)移入時都將觸發(fā)showFn方法缝裤。

需要注意的是IE8級以下版本不支持addEventListener和removeEventListener件缸,需要用attachEvent和detachEvent來實現(xiàn):

btn.attachEvent('onclick', showFn); // 綁定事件 
btn.detachEvent('onclick', showFn); // 解綁事件 

這里我們不需要傳入第三個參數(shù)铜靶,因為IE8級以下版本只支持冒泡型事件。

3.DOM3級事件
DOM3級事件在DOM2級事件的基礎(chǔ)上添加了更多的事件類型他炊,全部類型如下:

  • UI事件旷坦,當(dāng)用戶與頁面上的元素交互時觸發(fā),如:load旗芬、scroll
  • 焦點事件疮丛,當(dāng)元素獲得或失去焦點時觸發(fā),如:blur誊薄、focus
  • 鼠標(biāo)事件,當(dāng)用戶通過鼠標(biāo)在頁面執(zhí)行操作時觸發(fā)如:dbclick切心、mouseup
  • 滾輪事件,當(dāng)使用鼠標(biāo)滾輪或類似設(shè)備時觸發(fā)协屡,如:mousewheel
  • 文本事件全谤,當(dāng)在文檔中輸入文本時觸發(fā),如:textInput
  • 鍵盤事件补憾,當(dāng)用戶通過鍵盤在頁面上執(zhí)行操作時觸發(fā)盈匾,如:keydown子刮、keypress
  • 合成事件,當(dāng)為IME(輸入法編輯器)輸入字符時觸發(fā)葵孤,如:compositionstart
  • 變動事件尤仍,當(dāng)?shù)讓覦OM結(jié)構(gòu)發(fā)生變化時觸發(fā)狭姨,如:DOMsubtreeModified

同時DOM3級事件也允許使用者自定義一些事件。

DOM事件流
上文中講到了addEventListener的第三個參數(shù)為指定事件是否在捕獲階段執(zhí)行赡模,設(shè)置為true表示事件在捕獲階段執(zhí)行师抄,而設(shè)置為false表示事件在冒泡階段執(zhí)行叨吮。那么什么是事件冒泡和事件捕獲呢?可以用下圖來解釋:

事件冒泡與事件捕獲
1.事件冒泡
所謂事件冒泡就是事件像泡泡一樣從最開始生成的地方一層一層往上冒锋玲,比如上圖中a標(biāo)簽為事件目標(biāo)涵叮,點擊a標(biāo)簽后同時也會觸發(fā)p、li上的點擊事件剿干,一層一層向上直至最外層的html或document。下面是代碼示例:

<div id="box">
    <a id="child">事件冒泡</a>
</div>


<script>
 `var box = document.getElementById('box'),
 child = document.getElementById('child');

child.addEventListener('click', function() {
    alert('我是目標(biāo)事件');
 }, false);

 box.addEventListener('click', function() {
    alert('事件冒泡至DIV');
 }, false);
</script>

上面的代碼運行后我們點擊a標(biāo)簽杠步,首先會彈出'我是目標(biāo)事件'提示幽歼,然后又會彈出'事件冒泡至DIV'的提示谬盐,這便說明了事件自內(nèi)而外向上冒泡了。

那么我們?nèi)绾巫柚故录芭菽鼗市停窟@里就涉及事件的Event對象中的stopPropagation方法砸烦,如下:

child.addEventListener('click', function(e) {
    alert('我是目標(biāo)事件');
    e.stopPropagation();
}, false);

加上stopPropagation方法后,我們再次點擊a標(biāo)簽就不會觸發(fā)div上的click事件了唬格。

2.事件捕獲
和事件冒泡相反颜说,事件捕獲是自上而下執(zhí)行门粪,我們只需要將addEventListener的第三個參數(shù)改為true就行。

<div id="box">
    <a id="child">事件冒泡</a>
</div>

<script>
` var box = document.getElementById('box'),
 child = document.getElementById('child');

 child.addEventListener('click', function() {
     alert('我是目標(biāo)事件');
 }, true);

 box.addEventListener('click', function() {
    alert('事件冒泡至DIV');
 }, true);
</script>

此時我們點擊a標(biāo)簽乾吻,首先彈出的是'事件冒泡至DIV'措近,其次彈出的是'我是目標(biāo)事件'瞭郑,正好與事件冒泡相反屈张。


image

1.3瀏覽器對象模型(BOM)

Internet Explorer 3 和 Netscape Navigator 3 有一個共同的特色,那就是支持可以訪問和操作瀏覽器窗口的瀏覽器對象模型(BOM碳抄,Browser Object Model)场绿。開發(fā)人員使用 BOM 可以控制瀏覽器顯示的頁面以外的部分。而 BOM 真正與眾不同的地方(也是經(jīng)常會導(dǎo)致問題的地方)璧尸,還是它作為 JavaScript 實現(xiàn)的一部分但卻沒有相關(guān)的標(biāo)準(zhǔn)爷光。這個問題在 HTML5 中得到了解決澎粟,HTML5 致力于把很多 BOM 功能寫入正式規(guī)范。HTML5 發(fā)布后徐裸,很多關(guān)于 BOM 的困惑煙消云散瓣颅。
從根本上講宫补,BOM 只處理瀏覽器窗口和框架;但人們習(xí)慣上也把所有針對瀏覽器的 JavaScript 擴展算作 BOM 的一部分健民。下面就是一些這樣的擴展:

  • 彈出新瀏覽器窗口的功能贫贝;
  • 移動、縮放和關(guān)閉瀏覽器窗口的功能崇堵;
  • 提供瀏覽器詳細信息的 navigator 對象鸳劳;
  • 提供瀏覽器所加載頁面的詳細信息的 location 對象也搓;
  • 提供用戶顯示器分辨率詳細信息的 screen 對象涵紊;
  • 對 cookies 的支持摸柄;
  • 像 XMLHttpRequest 和 IE 的 ActiveXObject 這樣的自定義對象既忆。

由于沒有 BOM 標(biāo)準(zhǔn)可以遵循,因此每個瀏覽器都有自己的實現(xiàn)电媳。雖然也存在一些事實標(biāo)準(zhǔn)匾乓,例如要有 window 對象和 navigator 對象等又谋,但每個瀏覽器都會為這兩個對象乃至其他對象定義自己的屬性和方法。現(xiàn)在有了 HTML5彰亥,BOM 實現(xiàn)的細節(jié)有望朝著兼容性越來越高的方向發(fā)展。

2.<script>標(biāo)簽

HTML 頁面中插入 JavaScript 的主要方法任斋,就是使用<script>元素。使用<script>元素的方式有兩種:直接在頁面中嵌入 JavaScript 代碼和包含外部 JavaScript文件瘟檩。這個元素由 Netscape 創(chuàng)造并在 Netscape Navigator 2 中首先實現(xiàn)澈蟆。后來,這個元素被加入到正式的 HTML 規(guī)范中睹簇。

2.1<script>標(biāo)簽的屬性

HTML 4.01 為
<script>定義了下列 6 個屬性太惠。

  • async:可選。表示應(yīng)該立即下載腳本凿渊,但不應(yīng)妨礙頁面中的其他操作嗽元,比如下載其他資源或
  • 等待加載其他腳本剂癌。只對外部腳本文件有效翰绊。
  • charset:可選。表示通過 src 屬性指定的代碼的字符集谐檀。由于大多數(shù)瀏覽器會忽略它的值桐猬,
  • 因此這個屬性很少有人用刽肠。
  • defer:可選。表示腳本可以延遲到文檔完全被解析和顯示之后再執(zhí)行音五。只對外部腳本文件有
  • 效躺涝。IE7 及更早版本對嵌入腳本也支持這個屬性。
  • language:已廢棄夯膀。原來用于表示編寫代碼使用的腳本語言(如 JavaScript惶傻、JavaScript1.2
  • 或 VBScript)。大多數(shù)瀏覽器會忽略這個屬性涂佃,因此也沒有必要再用了辜荠。
  • src:可選抓狭。表示包含要執(zhí)行代碼的外部文件。
  • type:可選午笛∫┗牵可以看成是 language 的替代屬性;表示編寫代碼使用的腳本語言的內(nèi)容類型(也稱為 MIME 類型)癌佩。雖然 text/javascript 和 text/ecmascript 都已經(jīng)不被推薦使用围辙,但人們一直以來使用的都還是 text/javascript。實際上矫俺,服務(wù)器在傳送 JavaScript 文件時使用的MIME 類型通常是 application/x–javascript掸冤,但在 type 中設(shè)置這個值卻可能導(dǎo)致腳本被忽略。另外催烘,在非IE瀏覽器中還可以使用以下值:application/javascript和application/只ecmascript缎罢。考慮到約定俗成和最大限度的瀏覽器兼容性舰始,目前 type 屬性的值依舊還是text/javascript丸卷。不過询刹,這個屬性并不是必需的,如果沒有指定這個屬性沐兰,則其默認(rèn)值仍為text/javascript住闯。在使用<script>元素嵌入 JavaScript 代碼時,只須為<script>指定 type 屬性插佛。包含在<script>元素內(nèi)部的 JavaScript 代碼將被從上至下依次解釋朗涩。
    如果要通過<script>元素來包含外部 JavaScript 文件,那么 src 屬性就是必需的兄一。這個屬性的值是一個指向外部 JavaScript 文件的鏈接.
    需要注意的是,帶有 src 屬性的<script>元素不應(yīng)該在其<script></script>標(biāo)簽之間再包含額外的 JavaScript 代碼造壮。如果包含了嵌入的代碼耳璧,則只會下載并執(zhí)行外部腳本文件旨枯,嵌入的代碼會被忽略混驰。另外,通過<script>元素的 src 屬性還可以包含來自外部域的JavaScript 文件昆汹。這一點既讓<script>元素倍顯強大婴栽,又讓它備受爭議愚争。在這一點上轰枝,<script><img>元素非常相似劫扒,即它的 src屬性可以是指向當(dāng)前 HTML 頁面所在域之外的某個域中的完整 URL.

2.2<noscript>

早期瀏覽器都面臨一個特殊的問題沟饥,即當(dāng)瀏覽器不支持 JavaScript 時如何讓頁面平穩(wěn)地退化广料。對這個問題的最終解決方案就是創(chuàng)造一個<noscript>元素幼驶,用以在不支持 JavaScript 的瀏覽器中顯示替代的內(nèi)容盅藻。這個元素可以包含能夠出現(xiàn)在文檔<body>中的任何 HTML 元素,<script>元素除外。包含在<noscript>元素中的內(nèi)容只有在下列情況下才會顯示出來:

  • 瀏覽器不支持腳本勃蜘;
  • 瀏覽器支持腳本缭贡,但腳本被禁用阳惹。

符合上述任何一個條件眶俩,瀏覽器都會顯示<noscript>中的內(nèi)容颠印。而在除此之外的其他情況下嗽仪,瀏覽器不會呈現(xiàn)<noscript>中的內(nèi)容闻坚。

3.基本數(shù)據(jù)類型

ECMAScript 中有 6 種簡單數(shù)據(jù)類型(也稱為基本數(shù)據(jù)類型):Undefined窿凤、Null、Boolean雳殊、Number橘沥,String,Symbol夯秃。ECMAScript不支持任何創(chuàng)建自定義類型的機制座咆,而所有值痢艺,最終都可以用這7(加上object) 種數(shù)據(jù)類型來表示。

3.1 typeof 操作符

鑒于 ECMAScript 是松散類型的介陶,因此需要有一種手段來檢測給定變量的數(shù)據(jù)類型——typeof 就是負(fù)責(zé)提供這方面信息的操作符堤舒。對一個值使用 typeof 操作符可能返回下列某個字符串:

  • "undefined"——如果這個值未定義;
  • "boolean"——如果這個值是布爾值哺呜;
  • "string"——如果這個值是字符串舌缤;
  • "number"——如果這個值是數(shù)值;
  • "object"——如果這個值是對象或 null某残;
  • "function"——如果這個值是函數(shù)介牙。
    下面是幾個使用 typeof 操作符的例子:
var message = "some string";
alert(typeof message); // "string"
alert(typeof(message)); // "string"
alert(typeof 95); // "number"

這幾個例子說明赏酥,typeof 操作符的操作數(shù)可以是變量(message),也可以是數(shù)值字面量呵晨。注意粱哼,typeof 是一個操作符而不是函數(shù)胯舷,因此例子中的圓括號盡管可以使用,但不是必需的讨便。

3.2 Undefined

Undefined 類型只有一個值,即特殊的 undefined傲霸。在聲明變量但未對其加以初始化時寸五,這個變量的值就是 undefined。

3.3 Null

Null 類型是第二個只有一個值的數(shù)據(jù)類型叛溢,這個特殊的值是 null。從邏輯角度來看,null 值表示一個空對象指針草雕,而這也正是使用 typeof 操作符檢測 null 值時會返回"object"的原因嘴纺。實際上尖坤,undefined 值是派生自 null 值的场梆,因此 ECMA-262 規(guī)定對它們的相等性測試要返回 true:

alert(null == undefined); //true

這里驰唬,位于 null 和 undefined 之間的相等操作符(==)總是返回 true,不過要注意的是卷谈,這個操作符出于比較的目的會轉(zhuǎn)換其操作數(shù)

3.4 Boolean

Boolean 類型是 ECMAScript 中使用得最多的一種類型污淋,該類型只有兩個字面值:true 和 false浊吏。這兩個值與數(shù)字值不是一回事,因此 true 不一定等于 1,而 false 也不一定等于 0。需要注意的是挫剑,Boolean 類型的字面值 true 和 false 是區(qū)分大小寫的哲戚。也就是說,True 和 False(以及其他的混合大小寫形式)都不是 Boolean 值令宿,只是標(biāo)識符癞松。雖然 Boolean 類型的字面值只有兩個枫甲,但 ECMAScript 中所有類型的值都有與這兩個 Boolean 值等價的值话浇。要將一個值轉(zhuǎn)換為其對應(yīng)的 Boolean 值吉嫩,可以調(diào)用轉(zhuǎn)型函數(shù) Boolean()椒功,如下例所示:

var message = "Hello world!";
var messageAsBoolean = Boolean(message);

在這個例子中旱眯,字符串 message 被轉(zhuǎn)換成了一個 Boolean 值妈拌,該值被保存在messageAsBoolean變量中。可以對任何數(shù)據(jù)類型的值調(diào)用 Boolean()函數(shù)私股,而且總會返回一個 Boolean 值。至于返回的這個值是 true 還是 false偿曙,取決于要轉(zhuǎn)換值的數(shù)據(jù)類型及其實際值稿壁。

3.5 Number

3.5.1基礎(chǔ)number

根據(jù) ECMAScript 標(biāo)準(zhǔn),JavaScript 數(shù)字類型基于 IEEE 754 標(biāo)準(zhǔn)的雙精度 64 位二進制格式的值(-(253 -1) 到 253 -1)。它并沒有為整數(shù)給出一種特定的類型蛉威。除了能夠表示浮點數(shù)外,還有一些帶符號的值:+Infinity谈秫,-Infinity 和 NaN (非數(shù)值拟烫,Not-a-Number)。

要檢查值是否大于或小于 +/-Infinity拇囊,你可以使用常量 Number.MAX_VALUE 和 Number.MIN_VALUE寂拆。另外在 ECMAScript 6 中涉波,你也可以通過 Number.isSafeInteger() 方法還有 Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 來檢查值是否在雙精度浮點數(shù)的取值范圍內(nèi)窗声。 超出這個范圍苍苞,JavaScript 中的數(shù)字不再安全了,也就是只有 second mathematical interger 可以在 JavaScript 數(shù)字類型中正確表現(xiàn)送火。

數(shù)字類型中只有一個整數(shù)有兩種表示方法: 0 可表示為 -0 和 +0("0" 是 +0 的簡寫)拳话。 在實踐中,這也幾乎沒有影響种吸。 例如 +0 === -0 為真弃衍。 但是,你可能要注意除以0的時候:

42 / +0; // Infinity
42 / -0; // -Infinity

3.5.2 BigInt類型

BigInt類型是 JavaScript 中的一個基礎(chǔ)的數(shù)值類型坚俗,可以用任意精度表示整數(shù)镜盯。使用 BigInt,您可以安全地存儲和操作大整數(shù)猖败,甚至可以超過數(shù)字的安全整數(shù)限制速缆。BigInt是通過在整數(shù)末尾附加 n 或調(diào)用構(gòu)造函數(shù)來創(chuàng)建的。
末尾增加n:console.log(9007199254740995n)
構(gòu)造函數(shù):BigInt(9007199254740995)
通過使用常量Number.MAX_SAFE_INTEGER恩闻,您可以獲得可以用數(shù)字遞增的最安全的值艺糜。通過引入 BigInt,您可以操作超過Number.MAX_SAFE_INTEGER的數(shù)字幢尚。您可以在下面的示例中觀察到這一點破停,其中遞增Number.MAX_SAFE_INTEGER會返回預(yù)期的結(jié)果:

const x = 2n ** 53n;
9007199254740992n
const y = x + 1n;
9007199254740993n

可以對BigInt使用運算符+、尉剩、-真慢、 * 和 %,就像對數(shù)字一樣理茎。

BigInt 嚴(yán)格來說并不等于一個數(shù)字晤碘,但它是松散的。在將BigInt轉(zhuǎn)換為Boolean時功蜓,它的行為類似于一個數(shù)字:if园爷、||、&&式撼、Boolean 和!童社。

BigInt不能與數(shù)字互換操作。否則著隆,將拋出TypeError扰楼。

console.log(10n===10)false
console.log(10n==10)true

除了一元+號之外,所有運算符都可以用于BigInt美浦。
因為隱式轉(zhuǎn)換可能會丟失信息弦赖,所以不允許在Number和BigInt之間進行混合操作。

3.5.3NaN

NaN浦辨,即非數(shù)值(Not a Number)是一個特殊的數(shù)值蹬竖,這個數(shù)值用于表示一個本來要返回數(shù)值的操作數(shù)未返回數(shù)值的情況(這樣就不會拋出錯誤了)。例如,在其他編程語言中币厕,任何數(shù)值除以 0都會導(dǎo)致錯誤列另,從而停止代碼執(zhí)行。但在 ECMAScript中旦装,任何數(shù)值除以 0會返回 NaN①页衙,因此不會影響其他代碼的執(zhí)行。NaN 本身有兩個非同尋常的特點阴绢。首先店乐,任何涉及 NaN 的操作(例如 NaN/10)都會返回 NaN,這個特點在多步計算中有可能導(dǎo)致問題呻袭。其次响巢,NaN 與任何值都不相等,包括 NaN 本身棒妨。例如踪古,下面的代
碼會返回 false:

alert(NaN == NaN); //false

針對 NaN 的這兩個特點,ECMAScript 定義了 isNaN()函數(shù)券腔。這個函數(shù)接受一個參數(shù)伏穆,該參數(shù)可以是任何類型,而函數(shù)會幫我們確定這個參數(shù)是否“不是數(shù)值”纷纫。isNaN()在接收到一個值之后枕扫,會嘗試將這個值轉(zhuǎn)換為數(shù)值。某些不是數(shù)值的值會直接轉(zhuǎn)換為數(shù)值辱魁,例如字符串"10"或 Boolean 值烟瞧。而任何不能被轉(zhuǎn)換為數(shù)值的值都會導(dǎo)致這個函數(shù)返回 true。請看下面的例子:

alert(isNaN(NaN)); //true
alert(isNaN(10)); //false(10 是一個數(shù)值)
alert(isNaN("10")); //false(可以被轉(zhuǎn)換成數(shù)值 10)
alert(isNaN("blue")); //true(不能轉(zhuǎn)換成數(shù)值)
alert(isNaN(true)); //false(可以被轉(zhuǎn)換成數(shù)值 1)

3.6 String

String 類型用于表示由零或多個 16 位 Unicode 字符組成的字符序列染簇,即字符串参滴。字符串可以由雙引號(")或單引號(')表示。ECMAScript 中的字符串是不可變的锻弓,也就是說砾赔,字符串一旦創(chuàng)建,它們的值就不能改變青灼。要改變某個變量保存的字符串暴心,首先要銷毀原來的字符串,然后再用另一個包含新值的字符串填充該變量

var lang = "Java";
lang = lang + "Script";

以上示例中的變量 lang 開始時包含字符串"Java"杂拨。而第二行代碼把 lang 的值重新定義為"Java"與"Script"的組合专普,即"JavaScript"。實現(xiàn)這個操作的過程如下:首先創(chuàng)建一個能容納 10 個字符的新字符串弹沽,然后在這個字符串中填充"Java"和"Script"檀夹,最后一步是銷毀原來的字符串"Java"和字符串"Script"筋粗,因為這兩個字符串已經(jīng)沒用了。

3.7 Symbol

Symbol 值通過Symbol函數(shù)生成击胜。這就是說亏狰,對象的屬性名現(xiàn)在可以有兩種類型役纹,一種是原來就有的字符串偶摔,另一種就是新增的 Symbol 類型。凡是屬性名屬于 Symbol 類型促脉,就都是獨一無二的辰斋,可以保證不會與其他屬性名產(chǎn)生沖突。

let s = Symbol();

typeof s
// "symbol"

上面代碼中宫仗,變量s就是一個獨一無二的值藕夫。typeof運算符的結(jié)果枯冈,表明變量s是 Symbol 數(shù)據(jù)類型尘奏,而不是字符串之類的其他類型。

注意瑰煎,Symbol函數(shù)前不能使用new命令俗孝,否則會報錯赋铝。這是因為生成的 Symbol 是一個原始類型的值柬甥,不是對象。也就是說卤橄,由于 Symbol 值不是對象臂外,所以不能添加屬性喇颁『炕酰基本上,它是一種類似于字符串的數(shù)據(jù)類型姐叁。

Symbol函數(shù)可以接受一個字符串作為參數(shù)洗显,表示對 Symbol 實例的描述,主要是為了在控制臺顯示处窥,或者轉(zhuǎn)為字符串時玄组,比較容易區(qū)分俄讹。

let s1 = Symbol('foo');
let s2 = Symbol('bar');

s1 // Symbol(foo)
s2 // Symbol(bar)

s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"

上面代碼中颅悉,s1和s2是兩個 Symbol 值剩瓶。如果不加參數(shù),它們在控制臺的輸出都是Symbol()豌鹤,不利于區(qū)分布疙。有了參數(shù)以后灵临,就等于為它們加上了描述趴荸,輸出的時候就能夠分清,到底是哪一個值发钝。

如果 Symbol 的參數(shù)是一個對象顿涣,就會調(diào)用該對象的toString方法,將其轉(zhuǎn)為字符串涛碑,然后才生成一個 Symbol 值。

const obj = {
  toString() {
    return 'abc';
  }
};
const sym = Symbol(obj);
sym // Symbol(abc)

注意蒲障,Symbol函數(shù)的參數(shù)只是表示對當(dāng)前 Symbol 值的描述,因此相同參數(shù)的Symbol函數(shù)的返回值是不相等的晌涕。

// 沒有參數(shù)的情況
let s1 = Symbol();
let s2 = Symbol();

s1 === s2 // false

// 有參數(shù)的情況
let s1 = Symbol('foo');
let s2 = Symbol('foo');

s1 === s2 // false

上面代碼中滋捶,s1和s2都是Symbol函數(shù)的返回值痛悯,而且參數(shù)相同余黎,但是它們是不相等的载萌。

Symbol 值不能與其他類型的值進行運算扭仁,會報錯。

let sym = Symbol('My symbol');

"your symbol is " + sym
// TypeError: can't convert symbol to string
`your symbol is ${sym}`
// TypeError: can't convert symbol to string

但是,Symbol 值可以顯式轉(zhuǎn)為字符串仰迁。

let sym = Symbol('My symbol');

String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'

另外,Symbol 值也可以轉(zhuǎn)為布爾值徐许,但是不能轉(zhuǎn)為數(shù)值雌隅。

let sym = Symbol();
Boolean(sym) // true
!sym  // false

if (sym) {
  // ...
}

Number(sym) // TypeError
sym + 2 // TypeError

4.變量與作用域

ECMAScript 變量可能包含兩種不同數(shù)據(jù)類型的值:基本類型值和引用類型值「孜郑基本類型值指的是簡單的數(shù)據(jù)段恰起,而引用類型值指那些可能由多個值構(gòu)成的對象。在將一個值賦給變量時趾牧,解析器必須確定這個值是基本類型值還是引用類型值检盼。了 5 種基本數(shù)據(jù)類型:Undefined、Null武氓、Boolean梯皿、Number 和 String仇箱。這 5 種基本數(shù)據(jù)類型是按值訪問的,因為可以操作保存在變量中的實際的值东羹。引用類型的值是保存在內(nèi)存中的對象剂桥。與其他語言不同,JavaScript 不允許直接訪問內(nèi)存中的位置属提,也就是說不能直接操作對象的內(nèi)存空間权逗。在操作對象時,實際上是在操作對象的引用而不是實際的對象冤议。為此斟薇,引用類型的值是按引用訪問的。
我們不能給基本類型的值添加屬性恕酸,盡管這樣做不會導(dǎo)致任何錯誤堪滨。比如:

var name = "Nicholas";
name.age = 27;
alert(name.age); //undefined

在這個例子中,我們?yōu)樽址?name 定義了一個名為 age 的屬性蕊温,并為該屬性賦值 27袱箱。但在下一行訪問這個屬性時,發(fā)現(xiàn)該屬性不見了义矛。這說明只能給引用類型值動態(tài)地添加屬性发笔,以便將來使用。在從一個變量向另一個變量復(fù)制基本類型值和引用類型值時凉翻,也存在不同了讨。如果從一個變量向另一個變量復(fù)制基本類型的值,會在變量對象上創(chuàng)建一個新值制轰,然后把該值復(fù)制到為新變量分配的位置上前计。來看一個例子:

var num1 = 5;
var num2 = num1;

在此,num1 中保存的值是 5艇挨。當(dāng)使用 num1 的值來初始化 num2 時残炮,num2 中也保存了值 5。但 num2中的 5 與 num1 中的 5 是完全獨立的缩滨,該值只是 num1 中 5 的一個副本势就。此后,這兩個變量可以參與任何操作而不會相互影響脉漏。
當(dāng)從一個變量向另一個變量復(fù)制引用類型的值時苞冯,同樣也會將存儲在變量對象中的值復(fù)制一份放到為新變量分配的空間中。不同的是侧巨,這個值的副本實際上是一個指針舅锄,而這個指針指向存儲在堆中的一個對象。復(fù)制操作結(jié)束后司忱,兩個變量實際上將引用同一個對象皇忿。因此畴蹭,改變其中一個變量,就會影響另一個變量鳍烁,如下面的例子所示:

var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Nicholas";
alert(obj2.name); //"Nicholas"

首先叨襟,變量 obj1 保存了一個對象的新實例。然后幔荒,這個值被復(fù)制到了 obj2 中糊闽;換句話說,obj1和 obj2 都指向同一個對象爹梁。這樣右犹,當(dāng)為 obj1 添加 name 屬性后,可以通過 obj2 來訪問這個屬性姚垃,因為這兩個變量引用的都是同一個對象恢口。
ECMAScript 中所有函數(shù)的參數(shù)都是按值傳遞的指攒。也就是說贤斜,把函數(shù)外部的值復(fù)制給函數(shù)內(nèi)部的參
數(shù)怕磨,就和把值從一個變量復(fù)制到另一個變量一樣却盘∷夂福基本類型值的傳遞如同基本類型變量的復(fù)制一樣单刁,而引用類型值的傳遞捉超,則如同引用類型變量的復(fù)制一樣服协。有不少開發(fā)人員在這一點上可能會感到困惑绍昂,因為訪問變量有按值和按引用兩種方式,而參數(shù)只能按值傳遞偿荷。在向參數(shù)傳遞基本類型的值時窘游,被傳遞的值會被復(fù)制給一個局部變量(即命名參數(shù),或者用ECMAScript 的概念來說跳纳,就是 arguments 對象中的一個元素)忍饰。在向參數(shù)傳遞引用類型的值時,會把這個值在內(nèi)存中的地址復(fù)制給一個局部變量寺庄,因此這個局部變量的變化會反映在函數(shù)的外部艾蓝。(按值傳遞)
檢測基本類型用typeof,引用類型用instanceof

result = variable instanceof constructor

如果變量是給定引用類型(根據(jù)它的原型鏈來識別斗塘;)的實例赢织,那么instanceof 操作符就會返回 true。請看下面的例子:

alert(person instanceof Object); // 變量 person 是 Object 嗎馍盟?
alert(colors instanceof Array); // 變量 colors 是 Array 嗎于置?
alert(pattern instanceof RegExp); // 變量 pattern 是 RegExp 嗎?

根據(jù)規(guī)定贞岭,所有引用類型的值都是 Object 的實例八毯。因此搓侄,在檢測一個引用類型值和 Object 構(gòu)造函數(shù)時,instanceof 操作符始終會返回 true话速。當(dāng)然休讳,如果使用 instanceof 操作符檢測基本類型的值,則該操作符始終會返回 false尿孔,因為基本類型不是對象俊柔。

執(zhí)行環(huán)境的類型總共只有兩種——全局和局部(函數(shù)),但還是有其他辦法來延長作用域鏈活合。這么說是因為有些語句可以在作用域鏈的前端臨時增加一個變量對象雏婶,該變量對象會在代碼執(zhí)行后被移除。在兩種情況下會發(fā)生這種現(xiàn)象白指。具體來說留晚,就是當(dāng)執(zhí)行流進入下列任何一個語句時,作用域鏈就會得到加長:

  • try-catch 語句的 catch 塊告嘲;
  • with 語句错维。
    這兩個語句都會在作用域鏈的前端添加一個變量對象。對 with 語句來說橄唬,會將指定的對象添加到作用域鏈中赋焕。對 catch 語句來說,會創(chuàng)建一個新的變量對象仰楚,其中包含的是被拋出的錯誤對象的聲明隆判。

5.引用數(shù)據(jù)類型

5.1 Object

ECMAScript 中的對象其實就是一組數(shù)據(jù)和功能的集合。對象可以通過執(zhí)行 new 操作符后跟要創(chuàng)建的對象類型的名稱來創(chuàng)建僧界。而創(chuàng)建 Object 類型的實例并為其添加屬性和(或)方法侨嘀,就可以創(chuàng)建自定義對象,如下所示:

var o = new Object();

這個語法與 Java 中創(chuàng)建對象的語法相似捂襟;但在 ECMAScript 中咬腕,如果不給構(gòu)造函數(shù)傳遞參數(shù),則可以省略后面的那一對圓括號葬荷。也就是說,在像前面這個示例一樣不傳遞參數(shù)的情況下闯狱,完全可以省略那對圓括號(但這不是推薦的做法):

var o = new Object; // 有效煞赢,但不推薦省略圓括號

僅僅創(chuàng)建 Object 的實例并沒有什么用處,但關(guān)鍵是要理解一個重要的思想:即在 ECMAScript 中哄孤,(就像 Java 中的 java.lang.Object 對象一樣)Object 類型是所有它的實例的基礎(chǔ)照筑。換句話說,Object 類型所具有的任何屬性和方法也同樣存在于更具體的對象中。
Object 的每個實例都具有下列屬性和方法凝危。

  • constructor:保存著用于創(chuàng)建當(dāng)前對象的函數(shù)波俄。對于前面的例子而言,構(gòu)造函數(shù)(constructor)就是Object()蛾默。
  • hasOwnProperty(propertyName):用于檢查給定的屬性在當(dāng)前對象實例中(而不是在實例的原型中)是否存在懦铺。其中,作為參數(shù)的屬性名(propertyName)必須以字符串形式指定(例如:o.hasOwnProperty("name"))支鸡。
  • isPrototypeOf(object):用于檢查傳入的對象是否是傳入對象的原型
  • propertyIsEnumerable(propertyName):用于檢查給定的屬性是否能夠使用 for-in 語句來枚舉冬念。與 hasOwnProperty()方法一樣,作為參數(shù)的屬性名必須以字符串形式指定牧挣。
  • toLocaleString():返回對象的字符串表示急前,該字符串與執(zhí)行環(huán)境的地區(qū)對應(yīng)。
  • toString():返回對象的字符串表示瀑构。
  • valueOf():返回對象的字符串裆针、數(shù)值或布爾值表示。通常與 toString()方法的返回值相同寺晌。

由于在 ECMAScript 中 Object 是所有對象的基礎(chǔ)世吨,因此所有對象都具有這些基本的屬性和方法。

5.2 Array

5.2.1 array屬性

  • Array.length
  • Array.prototype

5.2.2 array的方法

  • Array.from()
  • Array.isArray()
  • Array.of()
  • Array.prototype.concat()
  • Array.prototype.copyWithin()
  • Array.prototype.entries()
  • Array.prototype.every()
  • Array.prototype.fill()
  • Array.prototype.filter()
  • Array.prototype.find()
  • Array.prototype.findIndex()
  • Array.prototype.flat()
  • Array.prototype.flatMap()
  • Array.prototype.forEach()
  • Array.prototype.includes()
  • Array.prototype.indexOf()
  • Array.prototype.join()
  • Array.prototype.keys()
  • Array.prototype.lastIndexOf()
  • Array.prototype.map()
  • Array.prototype.pop()
  • Array.prototype.push()
  • Array.prototype.reduce()
  • Array.prototype.reduceRight()
  • Array.prototype.reverse()
  • Array.prototype.shift()
  • Array.prototype.slice()
  • Array.prototype.some()
  • Array.prototype.sort()
  • Array.prototype.splice()
  • Array.prototype.toLocaleString()
  • Array.prototype.toString()
  • Array.prototype.unshift()
  • Array.prototype.values()

5.3 Date

ECMAScript 中的 Date 類型是在早期 Java 中的 java.util.Date 類基礎(chǔ)上構(gòu)建的呻征。為此耘婚,Date類型使用自 UTC(Coordinated Universal Time,國際協(xié)調(diào)時間)1970 年 1 月 1 日午夜(零時)開始經(jīng)過的毫秒數(shù)來保存日期怕犁。在使用這種數(shù)據(jù)存儲格式的條件下边篮,Date 類型保存的日期能夠精確到 1970 年 1月 1 日之前或之后的 285 616 年。要創(chuàng)建一個日期對象奏甫,使用 new 操作符和 Date 構(gòu)造函數(shù)即可,如下所示凌受。

var now = new Date(); 

在調(diào)用 Date 構(gòu)造函數(shù)而不傳遞參數(shù)的情況下阵子,新創(chuàng)建的對象自動獲得當(dāng)前日期和時間。如果想根據(jù)特定的日期和時間創(chuàng)建日期對象胜蛉,必須傳入表示該日期的毫秒數(shù)(即從 UTC 時間 1970 年 1 月 1 日午夜起至該日期止經(jīng)過的毫秒數(shù))挠进。為了簡化這一計算過程,ECMAScript 提供了兩個方法:Date.parse()和 Date.UTC()誊册。

例如领突,要為 2004 年 5 月 25 日創(chuàng)建一個日期對象,可以使用下面的代碼:

var someDate = new Date(Date.parse("May 25, 2004")); 

如果傳入 Date.parse()方法的字符串不能表示日期案怯,那么它會返回 NaN君旦。實際上,如果直接將表示日期的字符串傳遞給 Date 構(gòu)造函數(shù),也會在后臺調(diào)用 Date.parse()金砍。換句話說局蚀,下面的代碼與前面的例子是等價的:

var someDate = new Date("May 25, 2004"); 

Date.UTC()方法同樣也返回表示日期的毫秒數(shù),但它與 Date.parse()在構(gòu)建值時使用不同的信息恕稠。Date.UTC()的參數(shù)分別是年份琅绅、基于 0 的月份(一月是 0,二月是 1鹅巍,以此類推)千扶、月中的哪一天(1 到 31)、小時數(shù)(0 到 23)骆捧、分鐘县貌、秒以及毫秒數(shù)。在這些參數(shù)中凑懂,只有前兩個參數(shù)(年和月)是必需的煤痕。如果沒有提供月中的天數(shù),則假設(shè)天數(shù)為 1接谨;如果省略其他參數(shù)摆碉,則統(tǒng)統(tǒng)假設(shè)為 0。以下是兩個使用 Date.UTC()方法的例子:

// GMT 時間 2000 年 1 月 1 日午夜零時
var y2k = new Date(Date.UTC(2000, 0));
// GMT 時間 2005 年 5 月 5 日下午 5:55:55
var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55)); 

ECMAScript 5 添加了 Data.now()方法脓豪,返回表示調(diào)用這個方法時的日期和時間的毫秒數(shù)巷帝。這個方法簡化了使用 Data 對象分析代碼的工作。

//取得開始時間
var start = Date.now();
//調(diào)用函數(shù)
doSomething();
//取得停止時間
var stop = Date.now(),
 result = stop – start;

支持 Data.now()方法的瀏覽器包括 IE9+扫夜、Firefox 3+楞泼、Safari 3+、Opera 10.5 和 Chrome笤闯。在不支
持它的瀏覽器中堕阔,使用+操作符把 Data 對象轉(zhuǎn)換成字符串,也可以達到同樣的目的颗味。

//取得開始時間
var start = +new Date();
//調(diào)用函數(shù)
doSomething();
//取得停止時間
var stop = +new Date(),
 result = stop - start; 

Date 類型還有一些專門用于將日期格式化為字符串的方法超陆,這些方法如下。

  • toDateString()——以特定于實現(xiàn)的格式顯示星期幾浦马、月时呀、日和年;
  • toTimeString()——以特定于實現(xiàn)的格式顯示時晶默、分谨娜、秒和時區(qū);
  • toLocaleDateString()——以特定于地區(qū)的格式顯示星期幾磺陡、月趴梢、日和年漠畜;
  • toLocaleTimeString()——以特定于實現(xiàn)的格式顯示時、分垢油、秒盆驹;
  • toUTCString()——以特定于實現(xiàn)的格式完整的 UTC 日期。
  • 與 toLocaleString()和 toString()方法一樣滩愁,以上這些字符串格式方法的輸出也是因瀏覽器
  • 而異的躯喇,因此沒有哪一個方法能夠用來在用戶界面中顯示一致的日期信息。

5.4 RegExp

5.4.1創(chuàng)建正則

var re = /ab+c/;
var re = new RegExp("ab+c");

5.4.2正則表達式可以使用的方法(一共7種硝枉,其中只有exec和test用于RegExp的方法廉丽,其他5種應(yīng)用于string)

  • exec
    一個在字符串中執(zhí)行查找匹配的RegExp方法,它返回一個數(shù)組(未匹配到則返回 null)妻味。
  • test
    一個在字符串中測試是否匹配的RegExp方法正压,它返回 true 或 false。
  • match
    一個在字符串中執(zhí)行查找匹配的String方法责球,它返回一個數(shù)組焦履,在未匹配到時會返回 null。
  • matchAll
    一個在字符串中執(zhí)行查找所有匹配的String方法雏逾,它返回一個迭代器(iterator)嘉裤。
  • search
    一個在字符串中測試匹配的String方法,它返回匹配到的位置索引栖博,或者在失敗時返回-1屑宠。
  • replace
    一個在字符串中執(zhí)行查找匹配的String方法,并且使用替換字符串替換掉匹配到的子字符串仇让。
  • split
    一個使用正則表達式或者一個固定字符串分隔一個字符串典奉,并將分隔后的子字符串存儲到數(shù)組中的 String 方法。
    當(dāng)你想要知道在一個字符串中的一個匹配是否被找到丧叽,你可以使用 test 或 search 方法卫玖;
    想得到更多的信息(但是比較慢)則可以使用 exec 或 match 方法。
    如果你使用exec 或 match 方法并且匹配成功了蠢正,那么這些方法將返回一個數(shù)組并且更新相關(guān)的正則表達式對象的屬性和預(yù)定義的正則表達式對象骇笔。如果匹配失敗,那么 exec 方法返回 null(也就是false)嚣崭。

5.4.3正則表達式標(biāo)志:

  • g 全局搜索。
  • i 不區(qū)分大小寫搜索懦傍。
  • m 多行搜索雹舀。
  • s 允許 . 匹配換行符。
  • u 使用unicode碼的模式進行匹配粗俱。
  • y 執(zhí)行“粘性(sticky)”搜索,匹配從目標(biāo)字符串的當(dāng)前位置開始说榆。

5.4.4常用的正則表導(dǎo)式特殊字符:

  • *匹配前一個表達式0或多次,等價于{0,}
  • +匹配前一個表達式1或多次,等價于{1,}
  • ?匹配前一個表達式0或1次
  • .匹配換行符之外的任何單個字符
  • \d匹配一個數(shù)字签财,等價于[0-9]
  • \w匹配一個單個字符(字母數(shù)字或下劃線)串慰,等價于[A-Za-z0-9_]

5.4.5正則表達式的其他用途

正則表達式判斷質(zhì)數(shù)
!/^.?$|^(..+?)\1+$/.test(Array(你的數(shù)字+1).join('1'))
結(jié)果為true,表示是素數(shù)
結(jié)果為false唱蒸,表示不是素數(shù)(為1或者合數(shù))

5.5 Function

  • 不能把函數(shù)命名為 eval 或 arguments邦鲫;
  • 不能把參數(shù)命名為 eval 或 arguments;
  • 不能出現(xiàn)兩個命名參數(shù)同名的情況神汹。

如果發(fā)生以上情況庆捺,就會導(dǎo)致語法錯誤,代碼無法執(zhí)行屁魏。

ECMAScript 函數(shù)的參數(shù)與大多數(shù)其他語言中函數(shù)的參數(shù)有所不同滔以。ECMAScript 函數(shù)不介意傳遞進來多少個參數(shù),也不在乎傳進來參數(shù)是什么數(shù)據(jù)類型氓拼。也就是說你画,即便你定義的函數(shù)只接收兩個參數(shù),在調(diào)用這個函數(shù)時也未必一定要傳遞兩個參數(shù)桃漾』捣耍可以傳遞一個、三個甚至不傳遞參數(shù)呈队,而解析器永遠不會有什么怨言剥槐。之所以會這樣,原因是 ECMAScript 中的參數(shù)在內(nèi)部是用一個數(shù)組來表示的宪摧。函數(shù)接收到的始終都是這個數(shù)組粒竖,而不關(guān)心數(shù)組中包含哪些參數(shù)(如果有參數(shù)的話)。如果這個數(shù)組中不包含任何元素几于,無所謂蕊苗;如果包含多個元素,也沒有問題沿彭。實際上朽砰,在函數(shù)體內(nèi)可以通過 arguments 對象來訪問這個參數(shù)數(shù)組,從而獲取傳遞給函數(shù)的每一個參數(shù)喉刘。
其實瞧柔,arguments 對象只是與數(shù)組類似(它并不是 Array 的實例),因為可以使用方括號語法訪問它的每一個元素(即第一個元素是 arguments[0]睦裳,第二個元素是 argumetns[1]造锅,以此類推),使用 length 屬性來確定傳遞進來多少個參數(shù)廉邑。沒有傳遞值的命名參數(shù)將自動被賦予 undefined 值哥蔚。這就跟定義了變量但又沒有初始化一樣倒谷。

其次,重寫arguments 的值會導(dǎo)致語法錯誤(代碼將不會執(zhí)行)糙箍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渤愁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子深夯,更是在濱河造成了極大的恐慌抖格,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塌西,死亡現(xiàn)場離奇詭異他挎,居然都是意外死亡,警方通過查閱死者的電腦和手機捡需,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門办桨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人站辉,你說我怎么就攤上這事呢撞。” “怎么了饰剥?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵殊霞,是天一觀的道長。 經(jīng)常有香客問我汰蓉,道長绷蹲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任顾孽,我火速辦了婚禮祝钢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘若厚。我一直安慰自己拦英,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布测秸。 她就那樣靜靜地躺著疤估,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霎冯。 梳的紋絲不亂的頭發(fā)上铃拇,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音沈撞,去河邊找鬼锚贱。 笑死,一個胖子當(dāng)著我的面吹牛关串,可吹牛的內(nèi)容都是我干的拧廊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼晋修,長吁一口氣:“原來是場噩夢啊……” “哼吧碾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起墓卦,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤倦春,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后落剪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睁本,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年忠怖,在試婚紗的時候發(fā)現(xiàn)自己被綠了呢堰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡凡泣,死狀恐怖枉疼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鞋拟,我是刑警寧澤骂维,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站贺纲,受9級特大地震影響航闺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜猴誊,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一潦刃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧稠肘,春花似錦福铅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至憾股,卻和暖如春吨拗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背歉胶。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工汛兜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人通今。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓粥谬,卻偏偏與公主長得像肛根,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子漏策,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354