HTML(HyperText Markup Language,中文:超文本標(biāo)記語(yǔ)言)是一種用于創(chuàng)建網(wǎng)頁(yè)結(jié)構(gòu)和內(nèi)容的標(biāo)記語(yǔ)言。它由一系列標(biāo)簽組成,這些標(biāo)簽描述了網(wǎng)頁(yè)中的各個(gè)元素和其它相關(guān)信息。通過(guò)使用HTML標(biāo)簽和屬性,開發(fā)人員可以定義文本、圖像、鏈接、表格、表單等元素,并控制它們的外觀和行為。本文主要介紹HTML的基本概念、歷史背景和用途。
參考文檔:https://www.cjavapy.com/article/3297/
HTML實(shí)例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CJAVAPY編程之路(cjavapy.com)</title>
</head>
<body>
<h1>我的第一個(gè)標(biāo)題</h1>
<p>我的第一個(gè)段落。</p>
</body>
</html>
HTML文檔的后綴名可以是.html或.htm,都可以使用,沒(méi)有區(qū)別。
注意:對(duì)于中文網(wǎng)頁(yè)需要使用<meta charset="utf-8"> 聲明編碼,否則會(huì)出現(xiàn)亂碼。有些瀏覽器(如 360 瀏覽器)會(huì)設(shè)置 GBK 為默認(rèn)編碼,則你需要設(shè)置為<meta charset="gbk"> 。
1)標(biāo)簽(Tag)
HTML使用標(biāo)簽來(lái)定義網(wǎng)頁(yè)中的各個(gè)元素。標(biāo)簽通常以尖括號(hào)< >的形式出現(xiàn),如<p>表示段落,<img>表示圖像等。標(biāo)簽可以包含屬性,用于提供額外的信息或控制元素的行為。
2)元素(Element)
一個(gè)完整的HTML元素由開始標(biāo)簽、內(nèi)容和結(jié)束標(biāo)簽組成。例如,<p>這是一個(gè)段落</p>就是一個(gè)完整的段落元素。
3)屬性(Attribute)
HTML標(biāo)簽可以具有屬性,用于提供元素的額外信息或控制元素的行為。屬性以鍵值對(duì)的形式出現(xiàn),例如<img src="image.jpg">中的src屬性指定了圖像的源文件。
4)文檔結(jié)構(gòu)
一個(gè)HTML文檔由<html>、<head>和<body>等標(biāo)簽組成。其中,<html>標(biāo)簽用于定義整個(gè)HTML文檔的根元素,<head>標(biāo)簽用于定義文檔的頭部信息,如標(biāo)題和樣式表鏈接,<body>標(biāo)簽用于定義文檔的主體內(nèi)容。
5)塊級(jí)元素和內(nèi)聯(lián)元素
HTML元素可以被分類為塊級(jí)元素和內(nèi)聯(lián)元素。塊級(jí)元素以塊的形式顯示,獨(dú)占一行或一塊空間,如<p>、<div>等。內(nèi)聯(lián)元素以行內(nèi)的方式顯示,不會(huì)獨(dú)占一行,如<span>、<a>等。
6)嵌套
HTML元素可以嵌套在其他元素內(nèi)部,形成一個(gè)層次結(jié)構(gòu)。例如,<div>元素可以包含<p>元素,<p>元素可以包含<span>元素。
7)<!DOCTYPE> 聲明
HTML文檔的開頭通常會(huì)包含一個(gè)DOCTYPE聲明,用于指定文檔的HTML版本。
例如:
<!DOCTYPE html>
<!DOCTYPE HTML>
<!doctype html>
<!Doctype Html>
HTML(HyperText Markup Language)是一種用于創(chuàng)建網(wǎng)頁(yè)結(jié)構(gòu)和內(nèi)容的標(biāo)記語(yǔ)言,而Web瀏覽器(如谷歌瀏覽器,Internet Explorer,F(xiàn)irefox,Safari)是用于顯示和解釋HTML文檔的應(yīng)用程序。Web瀏覽器通過(guò)解析HTML文檔,將其轉(zhuǎn)換為可視化的網(wǎng)頁(yè)。瀏覽器會(huì)讀取HTML文檔中的標(biāo)簽和內(nèi)容,并根據(jù)這些標(biāo)簽和內(nèi)容的定義,渲染出網(wǎng)頁(yè)的結(jié)構(gòu)和樣式。HTML提供了各種標(biāo)簽和屬性,用于定義文本、圖像、鏈接、表格、表單等在網(wǎng)頁(yè)中的展示和交互方式。瀏覽器在解析HTML時(shí),會(huì)根據(jù)標(biāo)簽和屬性的定義,將文本顯示為段落、標(biāo)題或其他格式,顯示圖像、鏈接,并響應(yīng)用戶的交互操作。
通過(guò)HTML和Web瀏覽器的結(jié)合,用戶可以在瀏覽器中訪問(wèn)和瀏覽各種網(wǎng)頁(yè)內(nèi)容,包括網(wǎng)頁(yè)文本、圖像、視頻、音頻等多媒體元素,并與網(wǎng)頁(yè)進(jìn)行交互,如點(diǎn)擊鏈接、填寫表單、提交數(shù)據(jù)等。
大部分瀏覽器中,直接輸出中文會(huì)出現(xiàn)中文亂碼的情況,需要在頭部將字符聲明為 UTF-8 或 GBK。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>
頁(yè)面標(biāo)題</title>
</head>
<body>
<h1>我的第一個(gè)標(biāo)題</h1>
<p>我的第一個(gè)段落。</p>
</body>
</html>
HTML有多個(gè)版本,每個(gè)版本都有不同的特性和改進(jìn)。
版本 | 發(fā)布時(shí)間 |
HTML | 1991 |
HTML+ | 1993 |
HTML 2.0 | 1995 |
HTML 3.2 | 1997 |
HTML 4.01 | 1999 |
XHTML 1.0 | 2000 |
HTML5 | 2014 |
1)HTML 1.0
HTML 1.0是最早的HTML版本,于1993年發(fā)布。它只包含一些基本的標(biāo)簽和屬性,用于創(chuàng)建簡(jiǎn)單的文本和鏈接。HTML 1.0的目標(biāo)是定義一種通用的超文本標(biāo)記語(yǔ)言。
2)HTML 2.0
HTML 2.0于1995年發(fā)布,是對(duì)HTML 1.0的改進(jìn)和擴(kuò)展。它引入了一些新的標(biāo)簽和屬性,如圖像標(biāo)簽和表格標(biāo)簽,以支持更豐富的內(nèi)容展示。
3)HTML 3.2
HTML 3.2于1997年發(fā)布,是對(duì)HTML 2.0的進(jìn)一步改進(jìn)。它引入了一些新的標(biāo)簽和屬性,如表單標(biāo)簽和框架標(biāo)簽,以支持交互性和頁(yè)面布局。
4)HTML 4.01
HTML 4.01于1999年發(fā)布,是對(duì)HTML 3.2的修訂和擴(kuò)展。它引入了更多的標(biāo)簽和屬性,如層標(biāo)簽和樣式表,以支持更靈活的頁(yè)面設(shè)計(jì)和樣式控制。
5)XHTML 1.0
XHTML(eXtensible HyperText Markup Language)是基于XML的HTML版本。XHTML 1.0于2000年發(fā)布,它嚴(yán)格遵循XML的語(yǔ)法規(guī)則,要求所有標(biāo)簽和屬性都要正確嵌套和閉合。
6)HTML5
HTML5是HTML的最新版本,于2014年正式發(fā)布。HTML5引入了許多新的特性和API,如語(yǔ)義化標(biāo)簽、多媒體支持、Canvas繪圖、本地存儲(chǔ)等。HTML5還支持響應(yīng)式設(shè)計(jì),以適應(yīng)不同設(shè)備和屏幕尺寸。
HTML是構(gòu)建網(wǎng)頁(yè)結(jié)構(gòu)和內(nèi)容的基礎(chǔ)語(yǔ)言,它提供了豐富的標(biāo)簽和屬性,使得開發(fā)者可以創(chuàng)建各種類型的網(wǎng)頁(yè),并實(shí)現(xiàn)不同的功能和效果。HTML用于定義網(wǎng)頁(yè)的整體結(jié)構(gòu),包括標(biāo)題、段落、列表、標(biāo)題、導(dǎo)航菜單等元素。通過(guò)使用不同的HTML標(biāo)簽和屬性,可以將文本、圖像、音頻、視頻等內(nèi)容組織起來(lái),并構(gòu)建頁(yè)面的層次結(jié)構(gòu)。HTML可以用于展示文本內(nèi)容和多媒體元素,如圖像、音頻和視頻。通過(guò)使用適當(dāng)?shù)腍TML標(biāo)簽和屬性,可以插入和顯示各種類型的媒體內(nèi)容,從而使網(wǎng)頁(yè)更加豐富和吸引人。HTML提供了創(chuàng)建表單的標(biāo)簽和元素,可以用于收集用戶的輸入數(shù)據(jù)。通過(guò)使用表單元素如文本框、復(fù)選框、單選按鈕和下拉列表等,用戶可以輸入數(shù)據(jù)并提交給服務(wù)器進(jìn)行處理。
參考文檔:https://www.cjavapy.com/article/3297/
HTML文本格式化通常使用一系列特定的標(biāo)簽來(lái)改變文本的外觀或結(jié)構(gòu)。這些標(biāo)簽可以控制文本的字體、大小、顏色、對(duì)齊方式等,也可以用來(lái)標(biāo)記文本的邏輯結(jié)構(gòu)(如段落、標(biāo)題、列表等)。除了這些基本的格式化標(biāo)簽,HTML還支持通過(guò)CSS(級(jí)聯(lián)樣式表)來(lái)更精細(xì)和靈活地控制文本的格式和樣式。
參考文檔:https://www.cjavapy.com/article/3306/
HTML中,文本格式化和結(jié)構(gòu)化主要通過(guò)一系列標(biāo)簽來(lái)完成,其中標(biāo)題(Headings)標(biāo)簽是最常用于定義文本格式的元素之一。HTML提供了六級(jí)標(biāo)題標(biāo)簽,從 <h1> 到 <h6>,<h1> 表示最高級(jí)別的標(biāo)題,而 <h6> 表示最低級(jí)別的標(biāo)題。這些標(biāo)題標(biāo)簽不僅幫助改善網(wǎng)頁(yè)的結(jié)構(gòu)和可讀性,還對(duì)搜索引擎優(yōu)化(SEO)至關(guān)重要,因?yàn)樗阉饕媸褂眠@些標(biāo)簽來(lái)識(shí)別網(wǎng)頁(yè)上的不同部分和內(nèi)容的層次結(jié)構(gòu)。每個(gè)級(jí)別的標(biāo)題都有默認(rèn)的樣式,通常是不同的大小和加粗,以顯示它們的層次結(jié)構(gòu)
<h1>這是一個(gè) H1 標(biāo)題</h1>
<h2>這是一個(gè) H2 標(biāo)題</h2>
<h3>這是一個(gè) H3 標(biāo)題</h3>
<h4>這是一個(gè) H4 標(biāo)題</h4>
<h5>這是一個(gè) H5 標(biāo)題</h5>
<h6>這是一個(gè) H6 標(biāo)題</h6>
HTML中,文本格式化通常涉及使用特定的標(biāo)簽來(lái)控制文本的顯示方式。段落和換行是兩個(gè)基本但非常重要的文本格式化概念。用<p>創(chuàng)建段落,<br>插入換行。
1)段落 (<p> 標(biāo)簽)
<p> 標(biāo)簽自帶上下邊距,用以區(qū)分不同的段落。
<p>這是一個(gè)段落。</p>
<p>這是另一個(gè)段落。</p>
2)換行 (<br> 標(biāo)簽)
<br> 標(biāo)簽只是簡(jiǎn)單地添加一個(gè)換行點(diǎn),不添加任何額外的空間或邊距,并且通常用于詩(shī)歌或地址等需要精確控制換行位置的文本。
這是文本行的開始。<br>這是新的一行,但在同一個(gè)段落內(nèi)。
使用<em>和<strong>強(qiáng)調(diào)文本。HTML中,強(qiáng)調(diào)文本通常使用 <em> 和 <strong> 標(biāo)簽來(lái)實(shí)現(xiàn)。這兩個(gè)標(biāo)簽既有語(yǔ)義意義,也影響文本的表現(xiàn)形式。
<em> 標(biāo)簽用于表示強(qiáng)調(diào)文本,通常表現(xiàn)為斜體,用以表示文本的輕度強(qiáng)調(diào)。
<strong> 標(biāo)簽用于表示更強(qiáng)烈的強(qiáng)調(diào),通常表現(xiàn)為加粗,表示文本的高度強(qiáng)調(diào)。
<p>This is <em>emphasized</em> text.</p>
<p>This is <strong>strongly emphasized</strong> text.</p>
HTML 提供了兩種主要的列表類型:有序列表(<ol>)和無(wú)序列表(<ul>)。兩種類型都使用列表項(xiàng)(<li>)來(lái)定義列表中的實(shí)際項(xiàng)。
1)有序列表
有序列表以 <ol> 標(biāo)簽開始。每個(gè)列表項(xiàng)都放在 <li> 標(biāo)簽內(nèi)。列表是有序的,也就是每個(gè)項(xiàng)目都是編號(hào)的。這適用于項(xiàng)目順序很重要的列表,如食譜或待辦事項(xiàng)列表。
<ol>
<li>第一項(xiàng)</li>
<li>第二項(xiàng)</li>
<li>第三項(xiàng)</li>
</ol>
2)無(wú)序列表
無(wú)序列表以 <ul> 標(biāo)簽開始。像有序列表一樣,每個(gè)項(xiàng)都放在 <li> 標(biāo)簽內(nèi)。然而,無(wú)序列表中的項(xiàng)目不是編號(hào)的。使用圓點(diǎn)符號(hào)進(jìn)行表示。這適用于項(xiàng)目順序不重要的列表,如購(gòu)物清單。
<ul>
<li>蘋果</li>
<li>香蕉</li>
<li>橙子</li>
</ul>
<!DOCTYPE html>
<html>
<head>
<title>文本格式化示例</title>
</head>
<body>
<h1>HTML 文本格式化</h1>
<p>這是一個(gè)<em>斜體</em>和<strong>加粗</strong>的示例。</p>
<p><u>這段文本下劃線</u>和<s>這段文本是刪除線</s>。</p>
<p>化學(xué)水分子公式為H<sub>2</sub>O,E=mc<sup>2</sup>。</p>
<pre>
這是預(yù)格式化文本,
保留了空格和
換行符。
</pre>
<blockquote>這是一個(gè)長(zhǎng)引用的示例,可能包含多個(gè)段落。</blockquote>
<p>這是一個(gè)<q>短引用</q>的示例。</p>
<p>使用<code>HTML</code>和<code>CSS</code>進(jìn)行網(wǎng)頁(yè)設(shè)計(jì)。</p>
<p>按<kbd>Ctrl</kbd> + <kbd>C</kbd>復(fù)制文本。</p>
<p><samp>這是計(jì)算機(jī)程序的輸出。</samp></p>
<p>在JavaScript中,<var>x</var>可以作為變量。</p>
</body>
</html>
參考文檔:https://www.cjavapy.com/article/3306/
. 初識(shí)JS
1.1 什么是JS語(yǔ)言
javascript是一種運(yùn)行在客戶端 的腳本語(yǔ)言
客戶端: 即接受服務(wù)的一端,與服務(wù)端相對(duì)應(yīng),在前端開發(fā)中,通常客戶端指的就是瀏覽器。
腳本語(yǔ)言: 也叫解釋型語(yǔ)言,特點(diǎn)是執(zhí)行一行,解釋一行,如果發(fā)現(xiàn)報(bào)錯(cuò),代碼就停止執(zhí)行。
1.2 JS的三個(gè)組成部分
javascript的三個(gè)組成部分:ECMAScript、BOM、DOM
ECMAScript: 定義了javascript的語(yǔ)法規(guī)范。
BOM: 一套操作瀏覽器功能的API。
DOM: 一套操作頁(yè)面元素的API。
1.3 script 標(biāo)簽
1、script標(biāo)簽的書寫方式
書寫Javascript代碼有兩種方式,第一種是直接在script標(biāo)簽中書寫,第二種是將代碼寫在js文件中,通過(guò)script的src屬性進(jìn)行引入。
直接在script中書寫javascript代碼:
<!-- type="text/javascript" 可以省略 --> <script type="text/javascript"> alert("今天天氣真好呀"); </script>
通過(guò)script標(biāo)簽引入一個(gè)JS文件,需要指定src屬性:
<!-- 表示引用了test.js文件,并且script標(biāo)簽內(nèi)不可以繼續(xù)寫代碼 --> <script src="test.js"></script>
如果script標(biāo)簽指定了src屬性,說(shuō)明是想要引入一個(gè)js文件,這個(gè)時(shí)候不能繼續(xù)在script標(biāo)簽中寫js代碼,即便寫了,也不會(huì)執(zhí)行。
2、script標(biāo)簽的書寫位置
script標(biāo)簽的書寫位置,原則上來(lái)說(shuō),可以在頁(yè)面中的任意位置書寫。
寫在head標(biāo)簽中,style標(biāo)簽之后:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="demo.css"> <!-- 寫在這里 --> <script src="demo.js"></script> </head> <body> </body> </html>
瀏覽器有一個(gè)特性,就是在遇到<body>標(biāo)簽時(shí)才開始呈現(xiàn)內(nèi)容。如果在head里面引用js文件的話,意味著必須要等到全部的javascript代碼都被下載、解析和執(zhí)行完成之后,才能開始呈現(xiàn)頁(yè)面的內(nèi)容。如果文件數(shù)量一旦過(guò)多,將會(huì)影響頁(yè)面加載速度,此時(shí)頁(yè)面有可能會(huì)在加載完成前一片空白。
寫在</body>標(biāo)簽的前面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="demo.css"> </head> <body> <!-- 寫在這里 --> <script src="demo.js"></script> </body> </html>
在解析javascript代碼之前,頁(yè)面的內(nèi)容已經(jīng)完全呈現(xiàn)在瀏覽器當(dāng)中了,用戶會(huì)明顯感覺(jué)頁(yè)面加載變快了。
1.4 js中輸入輸出語(yǔ)句
1.5 注釋
不被程序執(zhí)行的代碼。用于程序員標(biāo)記代碼,在后期的修改,以及他人的學(xué)習(xí)時(shí)有所幫助,在JS中,分為單行注釋和多行注釋以及文檔注釋。
單行注釋
//這是單行注釋,只能注釋一行
多行注釋
/* 這是多行注釋,不能嵌套 */
文檔注釋
/** * 求圓的面積 * @param r {number} 圓的半徑 * @returns {number} 圓的面積 * 這是文檔注釋 */ function getArea (r) { return Math.PI * r * r; }
注釋的作用
2. 變量
變量,可以變化的量,變量是在計(jì)算機(jī)中存儲(chǔ)數(shù)據(jù)的一個(gè)標(biāo)識(shí)符。可以把變量看成存儲(chǔ)數(shù)據(jù)的容器。
變量與字面量:
2.1 變量的聲明與賦值
// 1- 同時(shí)聲明并且賦值 var num = 100; console.log(num); // 100 // 2- 先聲明了一個(gè)變量,再賦值 var num1; num1 = 100; console.log(num1); // 100 // 3- 沒(méi)有聲明變量,直接賦值(可以,但是不推薦) num2 = 200; console.log(num2); // 200 // 4- 有變量聲明,但是沒(méi)有賦值(可以,沒(méi)有賦值,變量的值默認(rèn)是個(gè)undefined) var num9; console.log(num9); // undefined // 5- 既沒(méi)有聲明,也沒(méi)有賦值,直接用。 console.log(num3); //報(bào)錯(cuò) num3 // 6- 一個(gè) var,逗號(hào)分隔 可以同時(shí)聲明多個(gè)變量 var name = "Levi丶", age = 18, gender = "男";
2.2 變量的命名規(guī)則與規(guī)范
命名規(guī)則(必須遵守):
命名規(guī)范(建議遵守):
2.3 交換兩個(gè)變量的值
方法一: 聲明一個(gè)新的變量
// 交換 num1 和 num2的值 var num1 = 11; var num2 = 22; var temp; temp = num1; // num1=11 temp=11 num1 = num2; // num1=22 num2=22 num2 = temp; // temp=11 num2=11
方法二: 不通過(guò)聲明變量的方式
// 不使用臨時(shí)變量 var num1 = 11; var num2 = 22; // num1 = 11 + 22 num1 = num1 + num2; // num1=33 // num2 = 33 - 22 num2 = num1 - num2; // num2=11 // num1 = 33 - 11 num1 = num1 - num2; // num1=22
3. 數(shù)據(jù)類型
基本數(shù)據(jù)類型包括了:number、string、boolean、undefined、null
3.1 如何查看數(shù)據(jù)類型
使用typeof關(guān)鍵字查看數(shù)據(jù)類型
typeof(name); // 括號(hào)可以省略 typeof name;
3.2 Number 類型
進(jìn)制
浮點(diǎn)數(shù)
所謂浮點(diǎn)數(shù),就是該數(shù)當(dāng)中必須包含一個(gè)小數(shù)點(diǎn),并且小數(shù)點(diǎn)后面至少有一位數(shù)字。
科學(xué)計(jì)數(shù)法:
//如何表示0.003和20000? var num = 3e-3; // 0.003 var num2 = 2e+4; // 20000
浮點(diǎn)數(shù)的精度問(wèn)題:
0.1 + 0.2 = ? // 0.30000000000000004 0.07 * 100 = ? // 7.000000000000001
浮點(diǎn)數(shù)在運(yùn)算的時(shí)候會(huì)出現(xiàn)精度丟失的問(wèn)題,因此在做比較運(yùn)算的時(shí)候,盡量不要用小數(shù)進(jìn)行比較。在第五章的時(shí)候會(huì)著重講解這個(gè)問(wèn)題
數(shù)值范圍
javascript不能表示世界上所有的數(shù),因此在javascript中,數(shù)值大小是有一定限制的。
數(shù)值判斷
示例代碼:
var str = "abc"; console.log(isNaN(str)); // true 說(shuō)明不是一個(gè)數(shù)字
3.3 String 類型
字面量
字符串的字面量:“abc” 、 ‘a(chǎn)bc’ 字符串可以是雙引號(hào),也可以是單引號(hào)引起來(lái)。
不管是雙引號(hào),還是單引號(hào),都是成對(duì)出現(xiàn)的,假如打印的字符串里有引號(hào)怎么辦呢?
這里就要活學(xué)活用,如果只有一處有引號(hào),就可以用單雙引號(hào)混合使用:
console.log('我是"帥哥"'); // ==> 我是"帥哥"
假如引號(hào)非常多的時(shí)候怎么辦呢? 用轉(zhuǎn)義字符:“\”:
console.log("我是'帥哥',\"哈哈哈\""); // ==> 我是'帥哥',"哈哈哈"
字符串拼接
拼接字符串使用+號(hào)
示例代碼:
console.log(11 + 11); // 22 console.log("hello" + " world"); // "hello world" console.log("100" + "100"); // "100100" console.log("11" + 11); // "1111"
總結(jié):
字符串長(zhǎng)度
length屬性用來(lái)獲取字符串的長(zhǎng)度
var str = "abcdefghij"; str.length;// 字符串的長(zhǎng)度 10
3.4. boolean 類型
boolean類型只有兩個(gè)字面量,true和false,區(qū)分大小寫(True,F(xiàn)alse不是布爾類型,只是標(biāo)識(shí)符)。
所有類型的值都可以轉(zhuǎn)化成true或者false
NaN、""、undefined、null、alse、0 這6個(gè)值可以轉(zhuǎn)換成false,其余的都是true。
3.5 undefined類型與null類型
undefined表示一個(gè)聲明了沒(méi)有賦值的變量
var name ; console.log(name); // undefined
null表示一個(gè)空的對(duì)象
var name = null; console.log(typeof name); // Object
如果定義的變量,將來(lái)是準(zhǔn)備用于保存對(duì)象的話,最好將變量初始化為null
var name = null;
undefined 與 null 的關(guān)系
undefined == null; // true undefined === null; // false
實(shí)際上,undefiner值是派生自null值的,所以判斷相等時(shí)為true,但是兩種用途是完全不一樣的。
4. 簡(jiǎn)單數(shù)據(jù)類型轉(zhuǎn)換
如何使用谷歌瀏覽器,快速的查看數(shù)據(jù)類型?
這個(gè)在調(diào)試過(guò)程中時(shí)非常有用的。
4.1 轉(zhuǎn)字符串類型
1、String()函數(shù)轉(zhuǎn)換
var num = 123; console.log(String(num)); // "123"
2、toString() 轉(zhuǎn)換不了undefined 和 null
var num = 123; console.log(num.toString()); // "123" console.log(undefined.toString()); // 報(bào)錯(cuò) console.log(null.toString()); // 報(bào)錯(cuò)
3、+ "" 加引號(hào)
var num = 123; console.log(num + ""); // "123"
4.2 轉(zhuǎn)數(shù)值類型
1、Number
console.log(Number("-123")); // -123 console.log(Number("")); // 0 console.log(Number("123abc")); // NaN
2、parseInt(取整)
console.log(parseInt("123.123")); // 123 console.log(parseInt("123.123abc")); // 123 console.log(parseInt("abc123.123")); // NaN console.log(parseInt("")); // NaN console.log(parseInt("abc")); // NaN
3、parseFloat(取數(shù))
console.log(parseFloat("123.123")); // 123.123 console.log(parseFloat("123.123abc")); // 123.123 console.log(parseFloat("abc123.123")); // NaN console.log(parseFloat("")); // NaN console.log(parseFloat("abc")); // NaN
4、參與運(yùn)算==> "+" or "-0"
var str = "-123"; console.log(+str); // -123 console.log(str-0); // -123
4.3 轉(zhuǎn)布爾類型
布爾類型只有true和false,但是所有類型的值都可以轉(zhuǎn)換成布爾類型
1、能夠轉(zhuǎn)換成false的只有6種:
其余的都是true
2、! 轉(zhuǎn)換
var str = ""; // Boolean() 判斷這個(gè)參數(shù)的布爾類型 console.log(Boolean(str)); // false console.log(!str); // true
5. JS小數(shù)運(yùn)算精度丟失
5.1 JS數(shù)字精度丟失的一些典型問(wèn)題
js在使用小數(shù)進(jìn)行計(jì)算的時(shí)候,會(huì)出現(xiàn)精度丟失的問(wèn)題。不要用來(lái)跟其他的小數(shù)做比較。
0.1 + 0.2 != 0.3 //true 0.30000000000000004 // 16位數(shù) 和 17位數(shù)相等 9999999999999999 == 10000000000000001 // true 9007199254740992 + 1 == 9007199254740992 // true
5.2 JS數(shù)字丟失精度的原因
計(jì)算機(jī)的二進(jìn)制實(shí)現(xiàn)和位數(shù)限制有些數(shù)無(wú)法有限表示。就像一些無(wú)理數(shù)不能有限表示,如 圓周率 3.1415926...,1.3333... 等。JS 遵循 IEEE 754 規(guī)范,采用 雙精度存儲(chǔ)(double precision) ,占用 64 bit。如圖
意義:
浮點(diǎn)數(shù),比如:
0.1 >> 0.0001 1001 1001 1001…(1001無(wú)限循環(huán)) 0.2 >> 0.0011 0011 0011 0011…(0011無(wú)限循環(huán))
此時(shí)只能模仿十進(jìn)制進(jìn)行四舍五入了,但是二進(jìn)制只有0和1兩個(gè),于是變?yōu)?舍1入。這即是計(jì)算機(jī)中部分浮點(diǎn)數(shù)運(yùn)算時(shí)出現(xiàn)誤差,丟失精度的根本原因。
大整數(shù)的精度丟失和浮點(diǎn)數(shù)本質(zhì)上是一樣的,尾數(shù)位最大是 52 位,因此 JS 中能精準(zhǔn)表示的最大整數(shù)是 Math.pow(2, 53),十進(jìn)制即 9007199254740992。
大于 9007199254740992 的可能會(huì)丟失精度:
9007199254740992 >> 10000000000000...000 // 共計(jì) 53 個(gè) 0 9007199254740992 + 1 >> 10000000000000...001 // 中間 52 個(gè) 0 9007199254740992 + 2 >> 10000000000000...010 // 中間 51 個(gè) 0
實(shí)際上:
9007199254740992 + 1 // 丟失 9007199254740992 + 2 // 未丟失 9007199254740992 + 3 // 丟失 9007199254740992 + 4 // 未丟失
結(jié)果如圖:
以上,可以知道看似有窮的數(shù)字,在計(jì)算機(jī)的二進(jìn)制表示里卻是無(wú)窮的,由于存儲(chǔ)位數(shù)限制因此存在“舍去”,精度丟失就發(fā)生了。
5.3 JS數(shù)字丟失精度的解決方案
對(duì)于整數(shù),前端出現(xiàn)問(wèn)題的幾率可能比較低,畢竟很少有業(yè)務(wù)需要需要用到超大整數(shù),只要運(yùn)算結(jié)果不超過(guò) Math.pow(2, 53) 就不會(huì)丟失精度。
對(duì)于小數(shù),前端出現(xiàn)問(wèn)題的幾率還是很多的,尤其在一些電商網(wǎng)站涉及到金額等數(shù)據(jù)。解決方式:把小數(shù)放到位整數(shù)(乘倍數(shù)),再縮小回原來(lái)倍數(shù)(除倍數(shù))
// 0.1 + 0.2 (0.1*10 + 0.2*10) / 10 == 0.3 // true
6. 運(yùn)算符
6.1 一元運(yùn)算符
遞增 "++" 和 遞減 "--" 還分為前自增或后自增,前自減或后自減,兩種自增自減的運(yùn)算結(jié)果是不一樣的;
舉個(gè)例子,看代碼:
var num = 5; console.log(num++); // 5 console.log(++num); // 7 (因?yàn)閯倓俷um自增了一次,這里打印的話就等于在6的基礎(chǔ)上前自增了,在計(jì)算機(jī)科學(xué)中,被稱為副效應(yīng)) console.log(num--); // 7 (這里是后自減,所以先返回值,返回7,再運(yùn)算--,此時(shí)的num實(shí)際是等于6了) console.log(--num); // 5
6.2 邏輯運(yùn)算符
示例代碼:
/*細(xì)讀上面三句話,就能理解為什么會(huì)是這個(gè)打印結(jié)果了*/ console.log(true && true); //true console.log(false || false); //false console.log(null && undefined); //null console.log(null || undefined); //undefined console.log("abc" && undefined); //undefined console.log("abc" || undefined); //abc console.log(null || false || 0 || 1 || null); //1 console.log("abc" && "bcd" && "def"); //def
6.3 運(yùn)算符的優(yōu)先級(jí)
示例代碼:
// 第一題 true && true console.log(((4 >= 6) || ("人" != "狗")) && !(((12 * 2) == 144) && true)); // true // 第二題 var num = 10; // true && true if(5 == num / 2 && (2 + 2 * num).toString() === "22") { console.log(true); // true }else{ console.log(false); }
7. 選擇語(yǔ)句
7.1 if..else語(yǔ)句
語(yǔ)法:
只有一個(gè)判斷條件的時(shí)候 if..else:
if(判斷條件){ // 當(dāng)判斷條件為true的時(shí)候執(zhí)行代碼1,為false的時(shí)候執(zhí)行代碼2 代碼1; }else{ 代碼2; }
當(dāng)不止一個(gè)判斷條件的時(shí)候 else用else if 代替:
if(判斷條件1){ // 判斷條件 1 為 true 的時(shí)候執(zhí)行 代碼 1 代碼1; }else if(判斷條件2){ // 判斷條件 2 為 true 的時(shí)候執(zhí)行 代碼 2 代碼2; }else{ // 兩個(gè)條件都不滿足的時(shí)候執(zhí)行代碼 3 代碼3; }
思考1:
var age = 20; if(age >= 18){ console.log("沒(méi)時(shí)間解釋了,趕緊上車吧"); // 打印這條 }else if(age >= 16){ console.log("請(qǐng)?jiān)诩议L(zhǎng)的陪同下觀看"); }else { console.log("回家學(xué)習(xí)吧"); }
思考2:
var date = new Date(); // 獲取當(dāng)前的時(shí)間 var week = date.getDay(); // 獲得 0-6 表示周幾 0:星期日 if(week == 0){ console.log("今天是星期天"); }else if(week == 1){ console.log("今天是星期一"); }else if(week == 2){ console.log("今天是星期二"); }else if(week == 3){ console.log("今天是星期三"); }else if(week == 4){ console.log("今天是星期四"); }else if(week == 5){ console.log("今天是星期五"); }else if(week == 6){ console.log("今天是星期六"); }else{ console.log("你火星的來(lái)的吧"); }
7.2 switch..case
語(yǔ)法:
// switch: 開關(guān); case: 案列; switch(變量){ // 判斷變量是否全等于case的值1,或者值2, case 值1: 執(zhí)行代碼1; // 全等于的時(shí)候執(zhí)行代碼1 break; // 然后break;代碼跳出switch語(yǔ)句, 不加break,會(huì)繼續(xù)執(zhí)行下面的代碼 case 值2: 執(zhí)行代碼2; break; default: 執(zhí)行代碼3; // 當(dāng)都不滿足條件的時(shí)候,會(huì)執(zhí)行默認(rèn)里的執(zhí)行代碼3 }
思考:素質(zhì)教育(把分?jǐn)?shù)變成ABCDE)
// 90-100 : A // 80-89: B // 70-79: C // 60-69: D // 0-59 : E // 這里的等級(jí)是根據(jù)一個(gè)范圍的分?jǐn)?shù)劃定的,用if..else很容易實(shí)現(xiàn),但是switch..case是一個(gè)具體的條件,怎么辦呢? // 方法:將分?jǐn)?shù)除以10再用parseInt屬性取整 var score = 85; score = parseInt(score/10); // 8 switch (score) { // score = 10 或者 9 的時(shí)候 返回 A case 10: case 9: console.log("A"); break; // score = 8 的時(shí)候 返回 B case 8: console.log("B"); break; case 7: console.log("C"); break; case 6: console.log("D"); break; default: console.log("E"); }
7.3 三元運(yùn)算符
這個(gè)運(yùn)算符可以用來(lái)代替if..else條件判斷。但是為什么有這個(gè)運(yùn)算符呢?這里的原因是if..else使用兩個(gè)代碼塊,卻只有一個(gè)會(huì)執(zhí)行,在講究的程序員看來(lái)是一種浪費(fèi)。所以使用三元運(yùn)算符,用一條語(yǔ)句就可以完成功能。
語(yǔ)法:
判斷語(yǔ)句?表達(dá)式1:表達(dá)式2; 根據(jù)判斷語(yǔ)句返回的布爾值,true的話,返回表達(dá)式1,false的話返回表達(dá)式2
舉個(gè)例子,看代碼:
var sex = 1; sex == 1 ? "男":"女"; // 判斷sex是否等于1,如果true,返回第一個(gè)表達(dá)式:"男"
例題:判斷兩個(gè)數(shù)的大小
// 用if..else語(yǔ)句解決 // 這里使用了兩個(gè)代碼塊,有點(diǎn)浪費(fèi) var num1 = 18; var num2 = 39; var max; if(num1>num2){ max = num1; }else{ max = num2; } console.log(max); // 用三元運(yùn)算符 var num3 = 28; var num4 = 49; var max1 = num3>num4? num3:num4; console.log(max1);
注意(容易出錯(cuò)的地方):
下面這個(gè)語(yǔ)句判斷如果是會(huì)員,費(fèi)用為2美元,非會(huì)員,為10美元。現(xiàn)在設(shè)置了非會(huì)員,卻打印出了2美元,顯然出錯(cuò)了。
var isMember = false; console.log("當(dāng)前費(fèi)用" + isMember ? "$2.00" : "$10.00"); // "$2.00"
出錯(cuò)的原因是?號(hào)的優(yōu)先級(jí)比+號(hào)低,所以實(shí)際運(yùn)行的語(yǔ)句是
// true console.log("當(dāng)前費(fèi)用false" ? "$2.00" : "$10.00"); // "$2.00"
8.循環(huán)語(yǔ)句
8.1 while 循環(huán)
語(yǔ)法:
// 1. 如果循環(huán)條件的結(jié)果是true的時(shí)候,就會(huì)執(zhí)行循環(huán)體 // 2. 如果循環(huán)條件的結(jié)果是false的時(shí)候,結(jié)束循環(huán)。 while(循環(huán)條件){ 循環(huán)的代碼; // 循環(huán)體 自增或者自減; // 一定不要忘記自增或自減,否則就會(huì)死循環(huán) }
例如,求0~100的和:
var num = 0; var sum = 0; while(num <= 100){ sum += num; num++; } console.log(sum); // 5050
8.2 do..while 循環(huán)
語(yǔ)法:
do{ 循環(huán)的代碼; // 循環(huán)體 自增或者自減; // 一定不要忘記自增或自減,否則就會(huì)死循環(huán) }while(循環(huán)條件);
例如,求0~100的和:
var num = 0; var sum = 0; do{ sum += num; num++; }while(num<=100); console.log(sum); // 5050
8.3 for 循環(huán)
寫while循環(huán)的經(jīng)常會(huì)忘記自增,for循環(huán)其實(shí)是while循環(huán)演化過(guò)來(lái)的,語(yǔ)法更加的簡(jiǎn)潔明了,使用非常的廣泛。
語(yǔ)法:
//主要for循環(huán)的表達(dá)式之間用的是;號(hào)分隔的,千萬(wàn)不要寫成,號(hào) for(初始化表達(dá)式;判斷表達(dá)式;自增表達(dá)式){ //循環(huán)體 }
例如:求0~100的和:
var sum = 0; for(var num = 0; num <= 100; num++){ sum += num; } console.log(sum); // 5050
8.4 break 和 continue
break:立即跳出整個(gè)循環(huán),即循環(huán)結(jié)束,開始執(zhí)行循環(huán)后面的內(nèi)容(直接跳到大括號(hào))continue:立即跳出當(dāng)前循環(huán),繼續(xù)下一次循環(huán)(跳到i++的地方)
1、continue 示例代碼:
for(var i = 1; i <= 10; i++) { if(i == 5) { continue; } console.log(i); // 1,2,3,4,6,7,8,9,10 }
2、break 示例代碼:
for(var i = 1; i <= 10; i++) { if(i == 5) { break; } console.log(i); // 1,2,3,4 }
8.5 循環(huán)語(yǔ)句練習(xí)
1、計(jì)算一個(gè)數(shù)的位數(shù)
當(dāng)不知道循環(huán)次數(shù)的時(shí)候,用while循環(huán):
var num = 1234567; //因?yàn)椴恢姥h(huán)次數(shù),所以推薦使用while循環(huán) var count = 0; // count記錄位數(shù) while(num != 0){ // 循環(huán)條件 num = parseInt(num/10);// 讓num縮小10倍 count++; // ,每縮小10倍就計(jì)算一次位數(shù)了 } console.log(count); // 7
2、翻轉(zhuǎn)一個(gè)數(shù)
var num = 12345678; //因?yàn)椴恢姥h(huán)次數(shù),所以推薦使用while循環(huán) var str = ""; while(num != 0){ str += num%10; // 將每一位取余 num = parseInt(num/10);//讓num縮小10倍 } // str 是一個(gè)字符串,所以 +str將它轉(zhuǎn)回Number類型 console.log(+str); //
3、總結(jié):
9. 數(shù)組
所謂數(shù)組,就是將多個(gè)元素(通常是同一類型的),按一定順序排列放到一個(gè)集合中,那么這個(gè)集合就稱之為數(shù)組
在javascript中,數(shù)組是一個(gè)有序的列表,可以在數(shù)組中存放任意的數(shù)據(jù),并且數(shù)組的長(zhǎng)度可以動(dòng)態(tài)的調(diào)整
9.1 創(chuàng)建數(shù)組
1、通過(guò)構(gòu)造函數(shù)創(chuàng)建數(shù)組:
2、通過(guò)數(shù)組子面量創(chuàng)建數(shù)組:
9.2 數(shù)組的下標(biāo)與長(zhǎng)度
數(shù)組的下標(biāo):
數(shù)組是有序的,數(shù)組中的每一個(gè)元素都對(duì)應(yīng)了一個(gè)下標(biāo),下標(biāo)是從0開始的
var arr = ['aa','bb','cc']; arr[0]; // 下標(biāo)是0,對(duì)應(yīng)的值是'aa' arr[2]; // 下標(biāo)是2,對(duì)應(yīng)的值是'cc'
數(shù)組的長(zhǎng)度:
跟字符串一樣,數(shù)組也有一個(gè)length的屬性,指數(shù)組中存放的元素的個(gè)數(shù)
var arr = ['aa','bb','cc']; arr.length; // 數(shù)組的長(zhǎng)度為3
空數(shù)組的長(zhǎng)度為0
數(shù)組的長(zhǎng)度與下標(biāo)的關(guān)系:
數(shù)組的最大下標(biāo) = 數(shù)組的長(zhǎng)度 - 1
9.3 數(shù)組的賦值與取值
數(shù)組的取值:
var arr = ['red','blue','green']; arr[0]; // red arr[2]; // green arr[3]; // 返回undefined,因?yàn)閿?shù)組最大的下標(biāo)為2
數(shù)組的賦值:
var arr = ["red", "green", "blue"]; arr[0] = "yellow"; // 把red替換成了yellow arr[3] = "pink"; // 給數(shù)組新增加了一個(gè)pink的值 arr[5] = "black"; // 數(shù)組輸出為["red", "green", "blue",empty,empty,"black"]
9.4 數(shù)組的遍歷
遍歷: 對(duì)數(shù)組的每一個(gè)元素都訪問(wèn)一次,叫做遍歷
數(shù)組遍歷的基本語(yǔ)法:
var arr = [1,2,3,4,5,6,7,8,9]; for(var i = 0; i < arr.length; i++){ console.log(arr[i]); // 1 2 3 4 5 6 7 8 9 }
數(shù)組遍歷的逆向遍歷語(yǔ)法:
// i= arr.length-1 ==> 表示初始化表達(dá)式 從數(shù)組最后一位開始遍歷 // i>=0 表示判斷條件,下標(biāo)要滿足大于等于0 // i--,表示每次遍歷 初始值都是自減的 var arr = [1,2,3,4,5,6,7,8,9]; for(var i = arr.length-1; i >= 0; i--){ console.log(arr[i]); // 9 8 7 6 5 4 3 2 1 }
9.5 數(shù)組綜合練習(xí)
1、求一個(gè)數(shù)組中的最大值、最小值以及對(duì)應(yīng)的下標(biāo)
var arr = [298, 1, 3, 4, 6, 2, 23, -88,77,44]; var max = arr[0]; // 隨機(jī)取數(shù)組中的一個(gè)值與其他值比較 var maxIndex = 0; // 初始化最大值的下標(biāo) var min = arr[0]; var minIndex = 0; for(var i = 0; i< arr.length; i++){ if(max < arr[i]){ // 用一開始選擇的值,與遍歷后的值進(jìn)行比較 max = arr[i]; // 當(dāng)后面的值比初始值大,就將后面的這個(gè)值賦值給初始值,再用這個(gè)全新的值再v 去與后面的比較 maxIndex = i; // 比較結(jié)束后,此時(shí)的索引就是最大值的索引 } if(min > arr[i]){ min = arr[i]; minIndex = i; } } console.log("最大的值是:" + max); console.log("最大值的下標(biāo)是:" + maxIndex); console.log("最小的值是:" + min); console.log("最小值的下標(biāo)是:" + minIndex);
2、讓數(shù)組倒序保存到一個(gè)新的數(shù)組中
需要了解數(shù)組的一個(gè)方法 push,在數(shù)組的最后面添加
var arr = ["大喬", "小喬", "甄姬", "不知火舞"]; var newArr = []; for (var i = arr.length - 1; i >= 0; i--) { newArr.push(arr[i]); } console.log(newArr); // ["不知火舞", "甄姬", "小喬", "大喬"]
3、將字符串?dāng)?shù)組用"|"或其他符號(hào)拼成一個(gè)字符串
var arr = ["aa","bb","cc","dd"]; var str = ""; for(var i = 0; i<arr.length; i++){ if(i == arr.length-1){ str = str + arr[i]; // 判斷一下,如果是最后一個(gè)的話就不用加“|” }else{ str = str + arr[i]+"|"; // str初始值是一個(gè)空字符串,遍歷的時(shí)候需要加上前一次的結(jié)果 } }
4、數(shù)組去重
var arr = [1, 1, 5, 7, 8, 3, 2, 5, 7, 2, 4, 6, 2, 5, 7, 2, 5]; //定義一個(gè)新數(shù)組 var newArr = []; //遍歷需要去重的數(shù)組 for (var i = 0; i < arr.length; i++) { //假設(shè)不存在 var flag = true; //需要判斷arr[i]這個(gè)值是否在新數(shù)組中存在 for(var j = 0; j < newArr.length; j++){ //進(jìn)行比較即可 if(arr[i] == newArr[j]){ //如果發(fā)現(xiàn)了相等的數(shù),說(shuō)明存在 flag = false; } } if(flag){ //如果假設(shè)成立,說(shuō)明不存在 newArr.push(arr[i]); } } console.log(newArr);
10. 冒泡排序
10.1 冒泡排序的思路
一個(gè)有8位元素的數(shù)組,讓它的第一位與后面每一位進(jìn)行比較,前面一位小于后面的時(shí)候,位置不變,前面的大于后面的交換位置,就這樣一共要比七趟(最后一趟不要比,就剩一位,就是最小的);
實(shí)現(xiàn)原理如下圖:
10.2 按性能等級(jí)冒泡排序分3個(gè)等級(jí)
1、冒泡排序 60分:
var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var tang = 0; var ci = 0; for (var i = 0; i < arr.length - 1; i++) { // 外層for循環(huán),循環(huán)的是比較的趟數(shù),因?yàn)橹灰容^8趟 所以i判斷的條件為length-1 tang++; for (var j = 0; j < arr.length - 1; j++) { // 內(nèi)層for循環(huán),循環(huán)的是比較的次數(shù),每趟比較8次 ci++; if (arr[j] > arr[j + 1]) { // 判斷比較的兩個(gè)數(shù),如果前面的大于后面的一位,交換位置 var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } console.log("趟數(shù):" + tang); // 8趟 console.log("次數(shù):" + ci); // 64次 console.log(arr); }
測(cè)試代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <span id="demo"></span><br/> <button id="stb">從小到大</button> <button id="bts">從大到小</button> <span id="show"> </span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; } strArr.push("外循環(huán)" + outer + "次"); strArr.push("內(nèi)循環(huán)" + inner + "次"); show.innerHTML = strArr.join(" "); } </script> </body> </html>
每趟都比較8次?明顯是多余了,下面進(jìn)行優(yōu)化
2、冒泡排序80分:
var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var tang = 0; var ci = 0; for (var i = 0; i < arr.length - 1; i++) { tang++; for (var j = 0; j < arr.length - 1 - i; j++) { // 第二趟只比了7次 依次遞減 ci++; if (arr[j] > arr[j + 1]) { var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } console.log("趟數(shù):" + tang); // 8趟 console.log("次數(shù):" + ci); // 36次 console.log(arr);
i 是從下標(biāo)0開始的,第一趟的時(shí)候i=0,比了8次,第二趟i=1,只需要比7次,第三趟i=2,只需要比6次...依次類推,所以 比的次數(shù)應(yīng)該就是arr.length - 1 -i;
測(cè)試代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <span id="demo"></span><br/> <button id="stb">從小到大</button> <button id="bts">從大到小</button> <span id="show"> </span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1 - i; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; } strArr.push("外循環(huán)" + outer + "次"); strArr.push("內(nèi)循環(huán)" + inner + "次"); show.innerHTML = strArr.join(" "); } </script> </body> </html>
還有什么可以優(yōu)化的嗎? 假如8個(gè)數(shù)在第3趟的時(shí)候就排好了,還需要繼續(xù)排嗎?
3、冒泡排序100分:
假設(shè)成立法(3步):
var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var tang = 0; var ci = 0; for (var i = 0; i < arr.length - 1; i++) { var flag = true; // 假設(shè)每一次進(jìn)來(lái)都排好了 tang++; for (var j = 0; j < arr.length - 1 - i; j++) { ci++; if (arr[j] > arr[j + 1]) { flag = false; // 如果兩位比較還滿足前面的比后面的大的時(shí)候,說(shuō)明假設(shè)不成立 var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } if (flag == true) { // 最后判斷一下,如果假設(shè)推翻不了,就停止運(yùn)行。 break; } } console.log("趟數(shù):" + tang); // 4 趟 console.log("次數(shù):" + ci); // 26 次 console.log(arr);
當(dāng)順序已經(jīng)排好后,就不用再去執(zhí)行趟數(shù)了;
測(cè)試代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <span id="demo"></span><br/> <button id="stb">從小到大</button> <button id="bts">從大到小</button> <span id="show"> </span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { var sorted = true; strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1 - i; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; sorted = false; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; if (sorted) { break; } } strArr.push("外循環(huán)" + outer + "次"); strArr.push("內(nèi)循環(huán)" + inner + "次"); show.innerHTML = strArr.join(" "); } </script> </body> </html>
第三趟已經(jīng)排好了,為什么還要排第四趟呢? 原因很簡(jiǎn)單,因?yàn)榈谌说臅r(shí)候js是不知道你已經(jīng)排好的,只有第四趟的時(shí)候,js再進(jìn)行換位比較的時(shí)候,發(fā)現(xiàn)位置都不需要換了,說(shuō)明排好了。
如果覺(jué)得不錯(cuò)可以關(guān)注微信公眾號(hào):編程成長(zhǎng)記
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。