JavaScript基礎(chǔ)入門筆記

0 介紹

0.1 ECMAScript

ECMA-262 的第 5 版是 JS 的第一個(gè)穩(wěn)定版本,得到了各瀏覽器廠商的支持。<br />

  • 語(yǔ)法
  • 類型
  • 語(yǔ)句
  • 關(guān)鍵詞
  • 保留字
  • 操作符
  • 對(duì)象

0.2 DOM

文檔對(duì)象模型是針對(duì) XML 但經(jīng)過(guò)擴(kuò)展用于 HTML 的 API 。DOM 把整個(gè)頁(yè)面映射為一個(gè)多層次節(jié)點(diǎn)結(jié)構(gòu)。HTML 或 XML 頁(yè)面中的每個(gè)組成部分都是某種類型的節(jié)點(diǎn),這些節(jié)點(diǎn)又包含著不同類型的數(shù)據(jù)灼狰。<br />document object model 文檔對(duì)象模型,里面提供了一些屬性和方法浮禾,可以讓我們操作頁(yè)面的元素

0.3 BOM

原則上講交胚,BOM只處理瀏覽器窗口和框架,但下面一些針對(duì)瀏覽器的 JS 擴(kuò)展也被看做是BOM的一部分盈电。<br />browser object model 瀏覽器對(duì)象模型蝴簇,里面提供了一些屬性和方法,可以讓我們操作瀏覽器匆帚。

1 導(dǎo)入JS

1.1 三種常見(jiàn)導(dǎo)入

1.1.1 行內(nèi)導(dǎo)入JS(慎重:不安全)

<div onclick="alert('hello world')"></div>

1.1.2 內(nèi)嵌式

<script>
    alert('hello world')
</script>

1.1.3 外鏈?zhǔn)?/h3>
// 新建一個(gè)js文件
<script src="./js/demo.js"></script>

// or

<script src="./js/demo.js" type="text/javascript"></script>

1.2 內(nèi)嵌與外鏈不能同時(shí)操作

內(nèi)嵌導(dǎo)入和外鏈導(dǎo)入不能合并在一起熬词,如果當(dāng)前是外鏈導(dǎo)入的,那么在script腳本塊找那個(gè)編寫(xiě)的所有代碼都不會(huì)被執(zhí)行吸重。

<script src="./js/demo.js">
  alert('hello world')
</script>

1.3 位置編寫(xiě)位置

我們一般性會(huì)把css放在body的上面互拾,把js放在body末尾(約定速成的規(guī)范)

但是如果放在了標(biāo)簽前面那么將如何處理?

頁(yè)面加載完所有資源之后執(zhí)行操作

在js中

window.onload=function(){

}

在jq中

$(document).ready(function(){

})

window.addEventListener('load',function(){},false);

// ie8以下

window.attachEvent('onreadystatechange',function(){
})

2 JS常用的輸出方式

2.1.彈窗輸出

2.1.1 alert

  • 在瀏覽器中彈出一個(gè)提示框(提供確定按鈕,點(diǎn)擊確定彈窗消失)
  • 使用alert彈窗信息嚎幸,提示的內(nèi)容最后都會(huì)轉(zhuǎn)換成字符串(調(diào)用了toSring這個(gè)方法)
alert(1)
alert({name:'wjw'}) //=> '[object Object]'
alert([13,14]) //=> '12,13'

2.1.2 confirm

  • 在alert基礎(chǔ)上增加了讓用戶選擇的操作(提供兩個(gè)按鈕:確定和取消)
  • 當(dāng)用戶點(diǎn)擊確定按鈕的時(shí)候颜矿,我們接收到的結(jié)果是true,點(diǎn)擊是取消按鈕我們接受到的結(jié)果是false嫉晶,此后我們可以根據(jù)結(jié)果來(lái)處理即可
var wjw = confirm("are you sure");
alert(wjw);

2.1.3 prompt

    • 在confirm 基礎(chǔ)上增加讓用戶增加輸入的效果
    • 用戶點(diǎn)擊取消按鈕骑疆,我們獲取到的結(jié)果是null,如果用戶點(diǎn)擊是確定按鈕田篇,我們將獲取用戶輸入的信息
    • 在真實(shí)的項(xiàng)目中,一般性會(huì)使用二次封裝的彈窗封断,不會(huì)使用這種彈窗
var flag = prompt("are you sure");

alert(flag)

2.2 控制臺(tái)輸出

控制臺(tái)輸出斯辰,方便開(kāi)發(fā)調(diào)試

2.2.1 console

  • 在控制臺(tái)輸出舶担,優(yōu)勢(shì)不會(huì)轉(zhuǎn)換數(shù)據(jù)類型坡疼,輸出什么格式的數(shù)據(jù)都可以
console.log({name:'wjw'});

console.dir() //比log輸出更加詳細(xì)一些
console.table //把json數(shù)據(jù)展示成一個(gè)表格

3 JS定義值

語(yǔ)法
ECMAScript 的語(yǔ)法大量借鑒了 C 及其他類 C 語(yǔ)言(如 Perl 和 Java)的語(yǔ)法。
區(qū)分大小寫(xiě)

3.1 注釋

// 單行注釋

/*
*    這是一個(gè)多行
*   (塊級(jí))注釋
*/

3.2 嚴(yán)格模式

嚴(yán)格模式
ES5 引入了嚴(yán)格模式的概念衣陶,在嚴(yán)格模式下柄瑰,ES3 中的一些不確定行為將得到處理,而且隊(duì)某些不安全的操作也會(huì)拋出錯(cuò)誤剪况。要在整個(gè)腳本中啟用嚴(yán)格模式教沾,可以在頂部添加如下代碼:<br />這行代碼看起來(lái)像是字符串,而且也沒(méi)有賦值給任何變量译断,但其實(shí)它是一個(gè)編譯指
示(pragma)授翻,用于告訴支持的JavaScript引擎切換到嚴(yán)格模式。在函數(shù)內(nèi)部的上方包含這條編譯指示孙咪,也可以指定函數(shù)在嚴(yán)格模式下執(zhí)行:

function doSomething(){
    "use strict";  //函數(shù)體
}

3.3 變量堪唐、常量

變量是可以變得
常量是不可變的

3.3.1變量

  • 變量其實(shí)只是一個(gè)無(wú)意義的名字,它所代表的意義都是其存儲(chǔ)的那個(gè)值
  • 讓原有的num變量存儲(chǔ)的值修改為13(變量只能代表一值)

js定義變量的方法

// var 變量名 = 值;

var num = 12;
var name = 'wjw'

3.3.1常量

  • 任何一個(gè)具體的數(shù)據(jù)都是常量翎蹈,例如12是個(gè)常量
  • 和變量累死淮菠,我們?cè)O(shè)置一個(gè)常量(也就是一個(gè)名字),給其存儲(chǔ)一個(gè)值荤堪,但是這個(gè)存儲(chǔ)的值不能修改
const num = 12;

3.4 JS中命名規(guī)范

  • JS中嚴(yán)格區(qū)分大小寫(xiě)
var test = 'wjw';
var Test = 'wjh';
console.log(test);
// 輸出test
  • 遵循國(guó)際命名規(guī)則"駝峰命名法"

第一個(gè)單詞首字母小寫(xiě)合陵,其余每一個(gè)有意義單詞首字母大寫(xiě)

var studentInfo; // 學(xué)生信息
// 所見(jiàn)即所得
// 例子:

/*
*    info : information 信息
*    init : initlization 初始化
*  add/insert/create 增加插入創(chuàng)建
*  remove/rm/clear/del/delete 刪除
*  update 修改
*  get/query/select : 查詢獲取
*/
  • 命名的時(shí)候可以使用$、_澄阳、數(shù)字拥知、字母,但是數(shù)字不能作為名字的第一位
var student_info;
var $xxx; //=> 一般都是應(yīng)用jq獲得到的值
var _xxx; //=> 一般這樣的情況代表變量是一個(gè)局或者公共的變量
  • JS中很多字都是有特殊含義的碎赢,我們這些詞低剔,叫做關(guān)鍵詞;現(xiàn)在沒(méi)有特殊含義揩抡,以后可能會(huì)作為關(guān)鍵的户侥,我們叫做保留字;二關(guān)鍵詞和保留字不可以隨便用來(lái)命名峦嗤;
image.png

<br />
image.png

<br />

4 JS數(shù)據(jù)類型

4.1 數(shù)據(jù)類型

4.1.1 基本數(shù)據(jù)類型(值類型)

  • Number 數(shù)字
  • String 字符串
    • 單引號(hào)包裹起來(lái)的都是字符串(單雙號(hào)沒(méi)有區(qū)別)
  • Boolean 布爾
    • true false => 布爾值只有兩個(gè)值
  • null 空對(duì)象指針
  • undefined 未定義

4.1.2 引用數(shù)據(jù)類型

  • {} 普通對(duì)象
  • [] 數(shù)組
  • /^$/ 正則
  • ...

4.1.3 function數(shù)據(jù)類型

  • funciotn fn (){}

4.2 數(shù)據(jù)類型檢查

  • typeof
  • 用來(lái)檢測(cè)數(shù)據(jù)類型的運(yùn)算符
  • instanceod
  • 檢測(cè)某個(gè)實(shí)例是否屬于這個(gè)類
  • constructor
  • 獲取當(dāng)前實(shí)例的構(gòu)造器
  • Object prototype.toSting.call()
    • 獲取當(dāng)前實(shí)例的所屬類信息

4.2.1 typeof

操作符
typeof 是用來(lái)檢測(cè)給定變量的數(shù)據(jù)類型的操作符蕊唐。對(duì)一個(gè)值使用 typeof 操作符可能返回下列某個(gè)字符串:

"undefined"
"boolean"
"string"
"number"
"object" // 如果這個(gè)值是對(duì)象或者null "function"

4.3 布爾值

Boolean()

  • 把其他數(shù)據(jù)類型的值轉(zhuǎn)化為布爾類型
  • 只有0、Nan烁设、null替梨、undefined這五個(gè)數(shù)據(jù)值轉(zhuǎn)換為布爾類型的false钓试,其余的都會(huì)變成true
image.png

嘆號(hào)在JS中海油一個(gè)作用:取反,先把值轉(zhuǎn)換為布爾類型副瀑,然后再去取反

image.png

!!

在嘆號(hào)取反的基礎(chǔ)上取反弓熏,取反兩次相當(dāng)于沒(méi)有操作,但是卻已經(jīng)其他類型值轉(zhuǎn)化為布爾類型了糠睡,和Boolean是相同的效果

4.4 字符串

在JS中單引號(hào)和雙引號(hào)包起來(lái)的都是字符串

12 - > number
'12' -> string
'[12,23]' -> string

4.4.1 toString()

第一種是使用幾乎每個(gè)值都有的 toString()方法挽鞠。多數(shù)情況下,調(diào)用 toString() 方法不必傳遞參數(shù)狈孔,但在調(diào)用數(shù)值的 toString()方法時(shí)信认,可以傳遞一個(gè)參數(shù):輸出數(shù)值的基數(shù)。默認(rèn)情況下均抽,toString() 方法以十進(jìn)制格式返回?cái)?shù)值的字符串表示嫁赏。而通過(guò)傳遞基數(shù),toString() 可以輸出二進(jìn)制油挥、八進(jìn)制潦蝇、十六進(jìn)制等。

var num = 10;
alert(num.toString());    // "10"
alert(num.toString(2));  // "1010"
alert(num.toString(8));  // "12"
alert(num.toString(10));  // "10"
alert(num.toString(16));  // "A"

常用方法<br />
image.png

4.5 number數(shù)字

0 12-22 12.5 js中多增加了一個(gè)number類型的數(shù)據(jù)NaN typeof NaN -> Number

var intNum = 55; // 十進(jìn)制整數(shù) var octalNum1 = 070; // 八進(jìn)制的56
var octalNum1 = 079; // 無(wú)效的八進(jìn)制數(shù)值——解析為79 
var octalNum1 = 08; // 無(wú)效的八進(jìn)制數(shù)值——解析為8 
var hexNum1 = 0xA;  // 十六進(jìn)制的10
var hexNum2 = 0x1F; // 十六進(jìn)制的31

注意深寥,八進(jìn)制字面量在嚴(yán)格模式下是無(wú)效的攘乒,會(huì)導(dǎo)致拋出錯(cuò)誤。

4.5.1 數(shù)值范圍

ECMAScript 能夠表示的最小數(shù)值保存在 Number.MIN_VALUE 中——在多數(shù)瀏覽器中翩迈,這個(gè)值是 5e-324持灰;能夠 Number.MAX_VALUE 中——在大多數(shù)瀏覽器中,這個(gè)值是1.7976931348623157e+308负饲。如果某次計(jì)算的結(jié)果得到了一個(gè)超過(guò)JavaScript 數(shù)值范圍的值堤魁,那么這個(gè)數(shù)值將會(huì)自動(dòng)轉(zhuǎn)換為 Infinity 值,如果這個(gè)數(shù)值是負(fù)數(shù)返十,則會(huì)轉(zhuǎn)換成 -Infinity(負(fù)無(wú)窮)妥泉,如果這個(gè)數(shù)值是正數(shù),則會(huì)轉(zhuǎn)換成Infinity(正無(wú)窮)洞坑。要確定一個(gè)數(shù)值是不是有窮的盲链,可以使用 isFinite() 函數(shù)。

4.5.2 NaN

  • not a numer : 不是一個(gè)數(shù)迟杂,但是屬于number類型
  • NaN == NaN : false , NaN 和任何其他值都不相等

4.5.3 isNaN()

  • 用來(lái)檢測(cè)當(dāng)前這個(gè)值是否是非有效數(shù)字刽沾,如果不是有效數(shù)字,檢測(cè)的結(jié)果是true , 反之是有效數(shù)字則為false
isNaN(0)   // ->false
isNaN(NaN) // ->true
  • 當(dāng)我們使用isNaN檢測(cè)值的時(shí)候排拷,檢測(cè)的值不是number類型的侧漓,瀏覽器默認(rèn)的吧值先轉(zhuǎn)換為number類型,任何再去檢測(cè)
isNaN('12') //->false

4.5.4 Number()

  • 把其他數(shù)據(jù)類型值轉(zhuǎn)化成number類型的值
Number('12') // -> 12
Number('12px') // ->NaN
// 在使用Number轉(zhuǎn)換的時(shí)候只要字符串中出現(xiàn)任何一個(gè)非有效數(shù)字字符监氢,最后的結(jié)果都是NaN

Number(true) //-> 1 
Number(false) //-> 0
Number(null) // -> 0
Number(undefined) //->NaN


  • 把引用數(shù)據(jù)類型轉(zhuǎn)換成number布蔗,首先需要吧引用數(shù)據(jù)類型轉(zhuǎn)為字符串(toString)藤违,在把字符串轉(zhuǎn)換為number即可
Number([]) // -> ""
Number([12]) // -> 12
Number([12,13]) // -> 12,13 (,是非有效字符) -> NaN
Number({age:12}) // ->NaN
Number({}) // -> NaN

4.5.5 pareInt

  • 也是吧其他數(shù)據(jù)類型值轉(zhuǎn)換為number,和Number方法在處理字符串的時(shí)候有所區(qū)別
Number('12px') // -> NaN
parseInt('12px') // -> 12
  • 提取規(guī)則:從左到右依次查找有效數(shù)字字符纵揍,知道遇到非有效數(shù)字字符為止(不管后端是否還有顿乒,都不找了)
parseInt('12px13') // -> 12

4.5.6 數(shù)值轉(zhuǎn)換

處理整數(shù)最常用的還是 parseInt() ,它會(huì)忽略字符前面的空格泽谨,直到找到第一個(gè)非空格字符璧榄。如果第一個(gè)字符不是數(shù)字字符或者負(fù)號(hào),parseInt() 就會(huì)返回 NaN隔盛;也就是說(shuō)犹菱,用 parseInt() 轉(zhuǎn)換空字符串會(huì)返回 NaN 。如果第一個(gè)字符是數(shù)字字符吮炕, parseInt() 會(huì)繼續(xù)解析第二個(gè)字符,直到解析完所有后續(xù)字符或者遇到了一個(gè)非數(shù)字字符访得。如果字符以“0x”開(kāi)頭且后面跟數(shù)字字符龙亲,會(huì)被解析為 16 進(jìn)制整數(shù);<br />以“0”開(kāi)頭且后面跟數(shù)字字符悍抑,會(huì)被解析為 8 進(jìn)制整數(shù)鳄炉。下面給出一些例子:

var num1 = parseInt("1234blue");   // 1234
var num2 = parseInt("");     // NaN
var num3 = parseInt("0xA");    // 10(十六進(jìn)制)
var num4 = parseInt(22.5);   // 22
var num5 = parseInt("70");     // 70
var num6 = parseInt("0xf");    // 15(十六進(jìn)制)

4.5.7 pareFloat

  • 在pareInt的基礎(chǔ)上可以識(shí)別小數(shù)點(diǎn)
pareInt('12.5px') -> 12
pareFloat('12.5px') -> 12.5

4.6 null 和undefined

  • null : 空,沒(méi)有
  • undefined :未定義搜骡,沒(méi)有
  • "" : 空字符串拂盯,沒(méi)有
  • 0: 也可以理解為沒(méi)有

4.6.1 空字符串和null的區(qū)別

  • 都是去去種樹(shù)
  • 空字符串屬于去挖了個(gè)坑,但是沒(méi)有種任何東西
  • null屬于連坑都沒(méi)挖
  • 空字符串相對(duì)于null來(lái)說(shuō)開(kāi)辟了內(nèi)存地址记靡,消耗了那么一丟丟的性能

4.6.2 null和undefined的區(qū)別

  • null一般都是暫時(shí)沒(méi)有谈竿,預(yù)期中以后會(huì)有的(可能以后也沒(méi)有達(dá)到預(yù)期),在js中null都是手動(dòng)先賦值為null摸吠,后期我們?cè)诮o其賦具體值
  • undefined:完全沒(méi)有預(yù)料之內(nèi)的

4.7 Object 對(duì)象

ECMAScript 中的對(duì)象其實(shí)就是一組數(shù)據(jù)和功能的集合空凸。對(duì)象可以通過(guò)執(zhí)行 new 操作符后跟要?jiǎng)?chuàng)建的對(duì)象類型的名稱來(lái)創(chuàng)建。而創(chuàng)建 Object 類型的實(shí)例并為其添加屬性和(或)方法寸痢,就可以創(chuàng)建自定義對(duì)象呀洲,如下所示:

var o = new Object();

每一個(gè)對(duì)象都是由零到多組 屬性名(key鍵):屬性值(value值) 組成的,或者說(shuō)有多組鍵值對(duì)組成的,每一組鍵值對(duì)中間用逗號(hào)分隔

4.7.1 屬性

描述這個(gè)對(duì)象特點(diǎn)特征的

var obj ={name:'wjw',age:8};

4.7.2 獲取

某個(gè)屬性名對(duì)應(yīng)的屬性值或者數(shù)字格式的

obj.name
obj['name']

4.7.3 存儲(chǔ)

屬性值可以是任何數(shù)據(jù)類型

  • 對(duì)象名.屬性名:忽略屬性名的單雙引號(hào)
  • 對(duì)象名[屬性名]:不能忽略單雙引號(hào)
// 如果屬性名是數(shù)字如何操作
obj.0 語(yǔ)法不支持
obj[0] / obj['0'] 兩種都支持

如果操作的屬性名在對(duì)象中不存在啼止,獲取的結(jié)果是undefined

obj.sex // ->undefined

4.7.4 設(shè)置/修改

一個(gè)對(duì)象的屬性名是不能重復(fù)的(唯一性)道逗,如果之前存在就是修改屬性值的操作,反之不存在就是新的設(shè)置屬性的操作

obj.sex = '男';
obj['age'] = 9;

4.7.5 刪除

假刪除:讓其屬性賦值為null献烦,但是屬性還是對(duì)象
obj.sex = null;
真刪除:把整個(gè)屬性都在對(duì)象中暴力移出
delete obj.sex

4.8 基本數(shù)據(jù)類型 和 引用數(shù)據(jù)類型的區(qū)別

JS是運(yùn)行在瀏覽器中的(內(nèi)核引擎)滓窍,瀏覽器會(huì)為JS提供賴以生存的環(huán)境(提供給js代碼執(zhí)行的環(huán)境)=> 全局作用域window(global)

var a = 12;
var b = a; // 把A變量存儲(chǔ)的值賦值給B
b = 13;
console.log(a);

var n ={name:'wjh'};
var m = n;
m.name = 'wjw'
console.log(n.name)
  • 基本數(shù)據(jù)類型是按值操作的:基本數(shù)據(jù)類型的賦值的時(shí)候,是直接把值賦值給變量即可
  • 引用數(shù)據(jù)類型是按照空間地址(引用地址)來(lái)操作的: var n = {name:'wjw'}
    • 先創(chuàng)建一個(gè)變量n
    • 瀏覽器首先會(huì)吧開(kāi)辟一個(gè)新的存儲(chǔ)控件(內(nèi)存控件)仿荆,目的是吧對(duì)象中需要存儲(chǔ)的內(nèi)容(鍵值對(duì))分別的存儲(chǔ)在這個(gè)空間中贰您,為了方便后期找到這個(gè)空間坏平,瀏覽器給空間設(shè)定一個(gè)地址(16進(jìn)制)
    • 把空間的地址賦值給了變量
image.png

4.9 function數(shù)據(jù)類型

函數(shù)數(shù)據(jù)類型也要按照引用地址來(lái)操作的

函數(shù):具備一定功能的方法

// => 創(chuàng)建函數(shù):
function 函數(shù)名(){
    //=> 函數(shù)體:實(shí)現(xiàn)某一個(gè)功能的具體JS代碼
}
// => 執(zhí)行函數(shù):相當(dāng)于使用洗衣機(jī)洗衣服(如果函數(shù)只創(chuàng)建了,但是沒(méi)有去執(zhí)行锦亦,函數(shù)沒(méi)有任何的意義)
// 函數(shù)名()
function fn(){
    console.log(1+1);
}
fn; // => 輸出函數(shù)本身
fn(); // => 把函數(shù)執(zhí)行(吧函數(shù)體重實(shí)現(xiàn)功能的代碼執(zhí)行)
image.png

形參:形式參數(shù)(變量)舶替,函數(shù)的入口<br />當(dāng)我們創(chuàng)建一個(gè)函數(shù)想要實(shí)現(xiàn)個(gè)功能的時(shí)候,發(fā)現(xiàn)有一些材料不清楚杠园,只有當(dāng)函數(shù)運(yùn)行的時(shí)候顾瞪,別人傳遞給我,我才知道抛蚁,此時(shí)我們就需要設(shè)定入口,讓用戶執(zhí)行的時(shí)候通過(guò)入口把值把我們

function fn(num1,num2){
    console.log(num1+num2)
}
// 實(shí)參:函數(shù)執(zhí)行傳遞給函數(shù)的具體值就是實(shí)參
fn(1,2);
fn(10,20);

4.10 數(shù)據(jù)類型轉(zhuǎn)換

把其他數(shù)據(jù)類型轉(zhuǎn)換為number類型<br />-> isNaN陈醒、Number、pareInt瞧甩、parseFloat<br />-> 在進(jìn)行數(shù)據(jù)加減乘除數(shù)學(xué)運(yùn)算的時(shí)候

// true -> 1 false->0
// ''->0  '12'->12  '12px'->NaN/12
// '小伙子'->NaN
// null -> 0 
// undefined-> NaN
{} /^$/ function() ->NaN
[]
[12]->'12'->12
['12,13']->'12,23'->NaN
// => 引用數(shù)據(jù)類型轉(zhuǎn)換為數(shù)字
// 通過(guò)toString方法把數(shù)組轉(zhuǎn)換為字符串钉跷,然后在調(diào)用Number轉(zhuǎn)換為數(shù)字

4.10.1 JS中的數(shù)據(jù)運(yùn)算

  • +、-肚逸、*爷辙、/加減乘除
  • 除了加法有特殊性,其余的運(yùn)算符都是數(shù)學(xué)運(yùn)算朦促,也是遇到非數(shù)字類型膝晾,需要把其轉(zhuǎn)換為number再運(yùn)算
1-'1' -> 0
10*null -> 0
10/undefined -> NaN
10*[10]->100

4.10.2 加法的特殊性:

  • 在遇到字符串的時(shí)候,+不是數(shù)學(xué)運(yùn)算务冕,而是字符串拼接血当,只要不遇到字符串就是數(shù)學(xué)運(yùn)算
1+'1' -> '11'
null+'1' -> ‘null1’

  • 字符串拼接:是把其它的值轉(zhuǎn)換為字符串然后再拼接(toString)
  • 其它數(shù)據(jù)類型的toString是直接的把值用單(雙)引號(hào)包起來(lái)極客,只有對(duì)象的特殊性禀忆,對(duì)象的有特殊性臊旭,對(duì)象.toStirng==='[Object Object]

4.10.3 將其它數(shù)據(jù)類型轉(zhuǎn)換為布爾類型

  • Boolean、油湖!巍扛、!乏德!
  • 在條件判斷的時(shí)候撤奸、也是轉(zhuǎn)換為布爾類型,然后驗(yàn)證條件的真假
  • 只有0喊括、NaN胧瓜、空字符串、null郑什、undefined五個(gè)轉(zhuǎn)換為false府喳、其余的都是轉(zhuǎn)換為true
[] -> true
-1 -> true

if(box){
        // => 首先把box變量存儲(chǔ)的值獲取到,轉(zhuǎn)化為布爾類型蘑拯,如果為true條件成立钝满,反之不成立
}

if(3+'3px'){
    // 條件成立: 3 + '3px' = '33px' 
}
if(3-'3px'){
    // 條件不成立: 3-'3px' = NaN
}

4.10.4 在使用==進(jìn)行比較的時(shí)候

在使用==進(jìn)行比較的時(shí)候兜粘,如果左右兩邊的數(shù)據(jù)不相同,瀏覽器默認(rèn)轉(zhuǎn)換為相同的類型弯蚜,然后在比較('==='不會(huì)這樣操作)

// 對(duì)象和對(duì)象: 應(yīng)用數(shù)據(jù)類型比較的空間地址不一樣孔轴,不是一個(gè)空間
[] == [] -> false
var a ={}
var b = a;
a==b -> true

4.10.5 對(duì)象和數(shù)字:吧對(duì)象轉(zhuǎn)換成數(shù)字

[]== 0 -> true
({})=== NaN -> false
NaN和自己不相等和其它任何值都不相等 

4.10.6 對(duì)象和字符串:把兩邊都轉(zhuǎn)換為數(shù)字比較的

[]==='' -> true

4.10.7 對(duì)象和布爾值:把兩邊都轉(zhuǎn)換成數(shù)字

[]==true ->  0==1 ->false
[]==false ->  0==0 ->true
![]==false ->  ![]  ->把數(shù)組變成為布爾在取反=false
false=false -> true

字符串和數(shù)字:字符串轉(zhuǎn)換為數(shù)字<br />字符串和布爾:都轉(zhuǎn)為數(shù)字<br />布爾和數(shù)字:布爾轉(zhuǎn)換為數(shù)字

規(guī)律:兩個(gè)等于號(hào)比較,左右兩邊數(shù)字值的類型不一樣碎捺,瀏覽器會(huì)吧兩邊的類型都轉(zhuǎn)換為數(shù)字然后再比較路鹰,但是null和undefined除外<br />null==undefined -> true<br />null===undefined -> false<br />null 和 undefined 和其它任何都不相等<br />null==0 -> false null以及undefined和其它任何值都不相等

5 JS中常見(jiàn)的操作的語(yǔ)句

5.1 if、else if 收厨、else

判斷操作語(yǔ)句

if(條件1){
    //=>條件1成立執(zhí)行的操作
}else if(條件2){
    //=>上面條件不成立晋柱,條件2成立,執(zhí)行的操作
}
...
else{
    // => 以上條件都不成立執(zhí)行的操作
}

如果好幾個(gè)條件都成立了诵叁,只吧第一個(gè)成立的條件執(zhí)行雁竞,后面成立的條件忽略不管<br />條件:

A==B、A!=B黎休、A>B浓领、A<B

if(A){} // 先把A轉(zhuǎn)換為布爾類型,判斷真假以此來(lái)決定是否成立

//否成立

if(A>B&&A<10){} //只有兩個(gè)小條件都是真势腮,整體條件為真

if(A>B||A<10){}  // 只要其中一個(gè)小條件成立,整體條件是真

BAT 面試題

var num = parseFloat('width:12.5px');
if(num==12.5){ // =>NaN
    alert(12.5);
}else if(num==NaN){ // NaN!=NaN
    alert(NaN);
}else if(typeof num=='number'){ // 
    alert(0)
}else{
    alert("啥也不是")
}

5.2 三元運(yùn)算符

條件漫仆?條件成立執(zhí)行:條件不成立執(zhí)行

if(條件){}else : 三元運(yùn)算符就是這種簡(jiǎn)單if..else..的另一種寫(xiě)法

var num = 10;
if(num>5&&num<10){
    num++;//累加1
}else{
    num--;
}
// 修改成為三元運(yùn)算符,如果條件成立或者不成立的某一種情況并不需要什么處理
// 我們空著語(yǔ)法不符合捎拯,我們使用null、undefined盲厌、void 0(就是undefined)占位就可以
num>5&&num<10?num++:num--;
var num = 10;
if(num>5 && num<10){
    num++;
  break;/continue;/return;
}
// => 修改成為三元運(yùn)算符
// 在三元運(yùn)算符的操作中不能出現(xiàn)break署照、continue、return這樣的關(guān)鍵詞吗浩,所以我們無(wú)法用三目代替if建芙、else
num>5 && num<10?
(num++,return):null;

5.3 swith case

swith case應(yīng)用于if、else中一個(gè)變量在不同值情況下的不同操作

var num =10;
switch(num){
    //switch后面小括號(hào)中存放的是一個(gè)值(一般我們都寫(xiě)變量;把變量存儲(chǔ)的值拿來(lái)用懂扼,有時(shí)候也可能是一個(gè)計(jì)算)
  case 1:
    // case后面放的都是值禁荸,目的驗(yàn)證switch后面的值和哪一種case后面的值相等,相等的進(jìn)行對(duì)應(yīng)的處理
    ...
    break;
    // 每一種case借宿后都要加break借宿當(dāng)前的判斷
  case 10:
    ...
    break;
  default:
    // switch后面的值和每一種case情況對(duì)應(yīng)的值都不相等阀湿,執(zhí)行最后的default赶熟,類似于false
    ...
}

案例分析

var num = 5;
switch(num%2){//=>先把取余操作進(jìn)行運(yùn)算,拿運(yùn)算結(jié)果case比較
    case 0:
  num++;
  break;  //不加break陷嘴,不管后面的條件是夠成立映砖,都會(huì)繼續(xù)向下執(zhí)行,知道遇到break為止
                // 不加break灾挨,就可以實(shí)現(xiàn)||這樣的操作
  case: 2-1: //case后面也應(yīng)該是值邑退,此處先把2-1計(jì)算竹宋,把計(jì)算的結(jié)果和switch值比較
  num--;
  // 最后一項(xiàng)可以不加break,不加也能跳出判斷
  break;
}
num%2:讓num存儲(chǔ)的值除以2去余數(shù)(0或者1)

swich case 中的比較實(shí)用的"==="

  • =:賦值地技,等號(hào)左邊是變量蜈七,右邊是值
  • ==:比較,如果左邊兩邊的類型不一樣乓土,瀏覽器默認(rèn)轉(zhuǎn)換為一樣的然后再進(jìn)行比較 '6'==6 => 6==6 =>true
  • ===:絕對(duì)相等擎宝,不僅要求值一樣,并且類型也要完全一樣

5.4 循環(huán)操作語(yǔ)句

循環(huán)著隆,重復(fù)做一件事情

for(設(shè)置循環(huán)起始值凿歼;設(shè)置循環(huán)執(zhí)行的條件;步長(zhǎng)累加){
    // 循環(huán)體:重復(fù)做的事情都是在循環(huán)體重
}
  • 設(shè)置初始值
  • 驗(yàn)證條件
  • 條件成立食磕,執(zhí)行循環(huán)體:不成立尽棕,循環(huán)借宿
  • 步長(zhǎng)累加
for(;i<5;;){
    consloe.log(i);
  //沒(méi)有步長(zhǎng)累加,我們的i永遠(yuǎn)是0彬伦,循環(huán)條件永遠(yuǎn)成立“死循環(huán)”;
  //項(xiàng)目中不能出現(xiàn)死循環(huán)滔悉,一旦出現(xiàn),循環(huán)下面的事情都做不了
}

5.4.1 continue

結(jié)束本輪循環(huán),繼續(xù)執(zhí)行下一輪:循環(huán)體重continue后面的代碼都不會(huì)在執(zhí)行单绑,它會(huì)直接的去執(zhí)行步長(zhǎng)回官,然后進(jìn)行下一輪

for(var i=0;i<5;i+=2){
    console.log(i)
  continue;
}

5.4.2 break

結(jié)束整個(gè)循環(huán):循環(huán)體重一旦遇到break首先后面代碼不執(zhí)行了,而且步長(zhǎng)累加也不執(zhí)行了搂橙,循環(huán)都結(jié)束了

for(var i=0;i<5;i+=2){
    console.log(i)
  break;
}

BAT面試題

for(var i=1;i<10;i+=2){
    if(i<5){
    i++;
    continue;
  }else{
    i+=3;
    break;
  }
  console.log(i)
}
console.log(i) // =>10

5.4.3 for in

用來(lái)遍歷(循環(huán))對(duì)象鍵值對(duì)的

  • var key;var attr(attribute);
  • 對(duì)象中有多少鍵值對(duì)歉提,我們的for in 循環(huán)遍歷多少次(多少次)
  • 第一次循環(huán)key這個(gè)遍歷存儲(chǔ)的都是當(dāng)前循環(huán)這個(gè)組鍵值隊(duì)的屬性名
  • key存儲(chǔ)的值都是字符串格式的(不管屬性名是否為數(shù)字)
  • 在for in 循環(huán)的遍歷時(shí)候,大部分瀏覽器都是先把對(duì)象中的鍵值對(duì)進(jìn)行排序(把數(shù)字屬性的排在前面区转,并且排列的時(shí)候安卓數(shù)字由小達(dá)大排列),其次在把非數(shù)字的屬性名按照之前編寫(xiě)的順序苔巨,循環(huán)的時(shí)候按照重新排列循序一次遍歷(小數(shù)算作字母不要做數(shù)字)
var obj = {name:wjw,age:8,0:'wjh',3:'ylp',1:'cx'}
for(var key in obj){
    console.log('ok')
    // key 屬性名 string
    console.log(obj.key)
    //獲取obj中key這個(gè)屬性對(duì)應(yīng)的值 ->undefined <=> obj['key']
    console.log(obj[key]);
    //->每一次循環(huán)把key變臉存儲(chǔ)的值(當(dāng)前遍歷的屬性名)獲取到放在中括號(hào)中,獲取obj對(duì)應(yīng)的屬性值
}
for(var key in obj){
    if(obj.hasOwnProperty(key)){
        
    }
 
}

6 JS的DOM獲取節(jié)點(diǎn)

DOM:document object model 文檔對(duì)象模型废离,提供一些屬性和方法可以讓我們?nèi)ゲ僮鱀OM元素

image.png
image.png

6.1 節(jié)點(diǎn)介紹

node 節(jié)點(diǎn)侄泽,瀏覽器默認(rèn)在一個(gè)html頁(yè)面中的所有內(nèi)容都是節(jié)點(diǎn)(包括標(biāo)簽、注解蜻韭、文字文本等)

  • 元素節(jié)點(diǎn):HTML標(biāo)簽
  • 文本節(jié)點(diǎn):文字內(nèi)容(大部分瀏覽器會(huì)把空格和換行也當(dāng)做文本節(jié)點(diǎn))
  • 注解節(jié)點(diǎn)
  • document文檔節(jié)點(diǎn)

元素節(jié)點(diǎn)

  • nodeType:1
    • 屬性含有某個(gè)節(jié)點(diǎn)的名稱
  • nodeName: 大寫(xiě)標(biāo)簽名(在部分瀏覽器的怪異模式下悼尾,我們寫(xiě)的標(biāo)簽名是小寫(xiě),它獲取的就是小寫(xiě)...)
    • 對(duì)于元素節(jié)點(diǎn)湘捎,因?yàn)楸旧聿恢苯影谋揪骰恚詎odeValue是不可用的。當(dāng)然你也可以在示例中自己寫(xiě)試試看有什么結(jié)果出現(xiàn)窥妇。
    • 對(duì)于文本節(jié)點(diǎn)舷胜,nodeValue=文本值
    • 對(duì)于屬性節(jié)點(diǎn),nodeValue=屬性值
  • nodeValue:null
    • 對(duì)于元素節(jié)點(diǎn),nodeType=1
    • 對(duì)于文本節(jié)點(diǎn)烹骨,nodeType=3
    • 對(duì)于屬性節(jié)點(diǎn)翻伺,nodeType=2
    • 對(duì)于注釋元素,nodeType=8
    • 對(duì)于文檔元素沮焕,nodeType=9

[curEle].tagName:獲取當(dāng)前元素的標(biāo)簽名(獲取的標(biāo)簽名一般都是大寫(xiě))

文本節(jié)點(diǎn)

nodeType:3<br />nodeName:#text<br />nodeValue:文本內(nèi)容

注釋節(jié)點(diǎn)

nodeType:8<br />nodeName:#comment<br />nodeValue:注釋內(nèi)容

文檔節(jié)點(diǎn)

nodeType:9<br />nodeName:#document<br />nodeValue:null

<-- div#box>(ul>li{0$}*3)+div{內(nèi)容$}*3-->
<div id="box">
        <ul>
            <li>01</li>
            <li>02</li>
            <li>03</li>
        </ul>
        <div>內(nèi)容1</div>
        <div>內(nèi)容2</div>
        <div>內(nèi)容3</div>
 </div>

6.2 獲取dom元素

6.2.1 document.getElementById 一個(gè)元素

  • 此方法的上下文只能document
  • 一個(gè)html頁(yè)面中元素的id理論上是不能重復(fù)的,如果頁(yè)面中ID重復(fù)了吨岭,我們獲得結(jié)果第一個(gè)id對(duì)應(yīng)的元素對(duì)象
  • 在ie7更低的版本瀏覽器中,會(huì)把表單元素的name值當(dāng)做id來(lái)識(shí)別使用(項(xiàng)目中盡量不要讓表單的name和其他元素的id相同)
  • 如果我們把js放在結(jié)構(gòu)的下面峦树,我們可以直接使用id值獲取這個(gè)元素(不需要通過(guò)getElementById獲取)辣辫,而且這種方式會(huì)把頁(yè)面中所有id是他的元素都獲取到(元素對(duì)象,或者集合) => 不推薦
<div id="box1"></div><div id="box2"></div><div id="box1"></div>
<script>
   console.log(box1)    // -> [div#box1, div#box1, box1: div#box1]
</script>
<input id="myInput" type="text" size="20"/><br />
<script>
  var x=document.getElementsByName("myInput");
</script>

6.2.2 document.getElementClassName 元素集合

  • 上下文是可以自己來(lái)指定
  • 獲取到的結(jié)果是一個(gè)元素集合(類數(shù)組集合)
  • 獲取的結(jié)果是集合魁巩,哪怕集合中只有一項(xiàng)急灭,我們想要操作的是這一項(xiàng)(元素對(duì)象),需要先從集合中獲取出來(lái)谷遂,然后再操作
  • 但是真實(shí)的項(xiàng)目中我們經(jīng)常會(huì)通過(guò)樣式類名獲取元素葬馋,getElementClassName這個(gè)方法在ie6-8不兼容的
<input name="myInput" type="text" size="20"/><br />
<script>
  var x=document.getElementsByName("input");
</script>

var bodyBox = document.getElementsByTagName('body');
bodyBox[0].getElementsByTagName('div');

6.2.3 document.getElementsTagName 元素集合

<input name="myInput" type="text" size="20"/><br />
<script>
  var x=document.getElementsByName("input");
</script>

6.2.4 document.getElementsByName 節(jié)點(diǎn)集合

通過(guò)元素的NAME屬性值獲取一組元素(類數(shù)組:節(jié)點(diǎn)集合NodeList)
他的上下文只能是document

  • IE瀏覽器只能識(shí)別表單元素的name屬性值,所以我們這個(gè)方法一般都用來(lái)操作表單元素的
  • 獲取html獲得body的元素對(duì)象
<input name="myInput" type="text" size="20"/><br />
<script>
 var x=document.getElementsByName("myInput");
</script>

6.2.5 domcument.domcumentElement 獲取整個(gè)html的對(duì)象

 document.documentElement.clientWidth||document.body.clientWidth
 // 獲取當(dāng)前瀏覽器可視區(qū)域的寬度(當(dāng)前頁(yè)面一個(gè)屏幕的寬度)
 // =>clientHieght 獲取高度

6.2.6 domcument.body 獲取body對(duì)象

6.2.7 domcument.head 獲取整個(gè)head對(duì)象

6.2.8 [context]querySelector 一個(gè)元素對(duì)象 / [context]querySelectorAll 獲取元素集合

  • ie6-8不兼容肾扰,而且沒(méi)有特別好的辦法處理他的兼容畴嘶,所以這兩個(gè)方法一般多用于移動(dòng)端開(kāi)發(fā)使用

querySelector 獲取一個(gè)元素對(duì)象<br />querySelectorAll 獲取的一個(gè)元素集合<br />只要css支持的選擇器,這里大部分都支持

document.querySelector('#box1');
document.querySelectorAll('.box1');
document.querySelectorAll('div');
document.querySelectorAll('body>div');
document.querySelectorAll('#box1 li');

6.3 節(jié)點(diǎn)關(guān)系屬性

節(jié)點(diǎn)是用來(lái)描述頁(yè)面中每一部門之間關(guān)系的,只要我可以獲取頁(yè)面中的一個(gè)頁(yè)面集晚,那么我就可以通過(guò)相關(guān)的屬性和方法獲取頁(yè)面中所有的節(jié)點(diǎn)

image.png

6.3.1 childNodes

獲取當(dāng)前元素所有的子節(jié)點(diǎn)(節(jié)點(diǎn)集合:類數(shù)組)
注:不僅僅是元素子節(jié)點(diǎn)窗悯,文本、注釋等都會(huì)包含在內(nèi):子節(jié)點(diǎn)說(shuō)明只是在兒子輩分中查找

6.3.2 children

獲取所有的元素子節(jié)點(diǎn)(元素集合)
在IE6-8下獲取的結(jié)果和標(biāo)準(zhǔn)瀏覽器中有區(qū)別(IE6-8中會(huì)把注釋點(diǎn)當(dāng)做元素節(jié)點(diǎn)獲取到)

6.3.3 pareNode

獲取當(dāng)前元素的父節(jié)點(diǎn)(元素對(duì)象)

6.3.4 previousibing

獲取當(dāng)前節(jié)點(diǎn)的上一個(gè)各個(gè)節(jié)點(diǎn)上一個(gè)哥哥節(jié)點(diǎn)(不一定是元素節(jié)點(diǎn)也可能是文本或者注釋)

6.3.5 nextibling

獲取當(dāng)前節(jié)點(diǎn)的下一個(gè)弟弟節(jié)點(diǎn)

6.3.6 previousElementbling

獲取當(dāng)前節(jié)點(diǎn)的上一個(gè)哥哥元素節(jié)點(diǎn)

6.3.7 nextElementsIbling

獲取當(dāng)前節(jié)點(diǎn)下一個(gè)弟弟元素節(jié)點(diǎn)
IE6-8不兼容

6.3.8 firstChild

當(dāng)前元素所有子節(jié)點(diǎn)中的第一個(gè)(也不一定是元素節(jié)點(diǎn)偷拔,可能是文本和注釋)

6.3.9 lastChild

當(dāng)前元素多有子節(jié)點(diǎn)中的最后一個(gè)
fistElementChild lastElementChild(IE6-8兼容)

6.4 創(chuàng)建和增加DOM元素

真實(shí)項(xiàng)目中蟀瞧,我們偶爾會(huì)在js中動(dòng)態(tài)創(chuàng)建html標(biāo)簽,然后把其增加到頁(yè)面中

6.4.1 document.createElement

在js中動(dòng)態(tài)創(chuàng)建一個(gè)html標(biāo)簽

6.4.2 appendChild

容器.appendChild(新元素)
把當(dāng)前創(chuàng)建的新元素添加到容器的末尾位置

6.4.3 inserBefore

容器.inserBefore(新元素条摸、老元素)
在當(dāng)前容器中,把新創(chuàng)建的元素增加到老元素之前

// 創(chuàng)建
var oDiv = document.createElement('div');
oDiv.id='div1';
oDiv.className = 'box';

// 添加到頁(yè)面中
document.body.appendChild(oDiv);
document.body.inserBefore(oDiv,box2);
var link = document.createElement('a');
link.

consloe.dir(link);
// hash:存儲(chǔ)餓哈希值 '#haha'
// hostname:域名 'www.baidu.com'
// pathname:路徑 '/stu/'
// protocol:協(xié)議 'http:'
// search:問(wèn)號(hào)傳遞參數(shù)值 '?nname=1&age=2'

真實(shí)項(xiàng)目中很多需要通過(guò)動(dòng)態(tài)創(chuàng)建元素來(lái)完成的铸屉,其中有一個(gè)需求:解析一個(gè)url地址每一部分的信息(包括問(wèn)號(hào)傳值的參數(shù)值)

  • 純字符串拆分截取
  • 編寫(xiě)強(qiáng)大的正則钉蒲,捕獲到需要的結(jié)果
  • 通過(guò)動(dòng)態(tài)創(chuàng)建一個(gè)a標(biāo)簽,利用a標(biāo)簽的一些內(nèi)置屬性來(lái)分別獲取每一部分的內(nèi)容
function queryURLParameter(url){
    var link = document.createElement('a');
  link.href=url;
  
  var search = link.search,
        obj = {}'
  if(search.length===0) return;
  search = search.substr(1).split(/&|=/g);
  for(var i=0;i<search.length;i+=2){
    var key = search[i],
            value = search[i+1];
    obj[key]=value;
  }
  link = null;
  return obj;
}

6.5 修改刪除克隆DOM元素

6.5.1 removeChild

  • 容器.removeChild(元素)
  • 在當(dāng)前容器中把每一個(gè)元素移出掉

6.5.2 replaceChild

  • 容器.removeChild(新元素彻坛,老元素)
  • 把原有的元素克隆一份一模一樣的顷啼,false:只克隆當(dāng)前元素本身,true:深度克隆昌屉,吧當(dāng)前元素本身以及元素的所有后代都進(jìn)行克隆

6.5.3 [set/get/remove]Attribute

給當(dāng)前元素設(shè)置/獲取/移出屬性的(一般操作的都是它的自定義屬性)
box.setAttribute('myIndex',0)
box.getAttribute('myIndex')
box.removeAttribute('myIndex')

使用xxx.index=0 和xxx.setAttribute('index',0)這兩種設(shè)置自定義屬性的區(qū)別

xxx.index : 是吧當(dāng)前操作的元素當(dāng)做一個(gè)普通對(duì)象钙蒙,為其設(shè)置一個(gè)屬性名<br />xxx.setAttribute:把元素當(dāng)做特殊的元素對(duì)象來(lái)處理,設(shè)置的自定義屬性是和頁(yè)面結(jié)構(gòu)中的DOM元素映射在一起的

JS中獲取的元素對(duì)象间驮,我們可以把他理解為兩種角色:

  • 與頁(yè)面HTML結(jié)構(gòu)無(wú)關(guān)的普通對(duì)象
  • 與頁(yè)面HTML結(jié)構(gòu)存在映射關(guān)系的元素對(duì)象

元素對(duì)象中的內(nèi)置屬性躬厌,大部分都和頁(yè)面的標(biāo)簽存在映射關(guān)系:<br />xxx.style.backgroundColor = 'xxx' 此時(shí)不僅把js中對(duì)象對(duì)應(yīng)的屬性值改變了,而且也會(huì)映射到頁(yè)面的html標(biāo)簽上(標(biāo)簽中有一個(gè)style行內(nèi)樣式竞帽,元素的樣式改變了)<br />xxx.className = 'xxx'此時(shí)不僅是吧js對(duì)象中的屬性值改變了扛施,而且頁(yè)面中的標(biāo)簽增加了class樣式類(可以看見(jiàn)的)

元素對(duì)象中的自定義屬性: xxx.index=0<br />僅僅是吧js對(duì)象中增加了一個(gè)屬性名(自定義的)鸿捧,和頁(yè)面中的html沒(méi)啥關(guān)系(在結(jié)構(gòu)上看不見(jiàn))

xxx.setAttribute:通過(guò)這種方式設(shè)置的自定義屬性和之前提到的內(nèi)置屬性差不多,都是和html結(jié)構(gòu)存在映射關(guān)系的(設(shè)置的自定屬性可以呈現(xiàn)在結(jié)構(gòu)上)

6.6 面試題

把當(dāng)前頁(yè)面中所有id叫做box1的都獲取到

var allList = document.getElementsByTagName(*);
var result = []
for(var i=0;i<allList.length;i++){
    var item = allList[i];
  item.id === 'box1'?result.push(item)
}
console.log(result)

獲取當(dāng)前元素的上一個(gè)哥哥元素節(jié)點(diǎn)(兼容所有的瀏覽器)
curEle:current element

// 首先獲取當(dāng)前元素的上一個(gè)哥哥節(jié)點(diǎn)疙渣,判斷當(dāng)前獲取的節(jié)點(diǎn)是否為元素節(jié)點(diǎn)(nodeType===1)
// 如果不是基于當(dāng)前獲取的節(jié)點(diǎn)匙奴,找他的上一個(gè)哥哥節(jié)點(diǎn)..(找?guī)状尾恢?一直到找到的節(jié)點(diǎn)是元素節(jié)點(diǎn)為止
// 如果在查找過(guò)程中,發(fā)現(xiàn)沒(méi)有上一個(gè)哥哥節(jié)點(diǎn)妄荔,找到頭了泼菌,則不再繼續(xù)查找

function prev(curEle){
    var p = curEle.previousSibling; // 屬性返回同一樹(shù)層級(jí)中指定節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)。
  while(p&&p.nodeType!==1){ //p:p!=null
    p = p.previousSibling;
  }
    return p;
}

// 擴(kuò)展
// next: 獲取下一個(gè)弟弟元素節(jié)點(diǎn)
// prevAll:獲取所有的哥哥元素節(jié)點(diǎn)
// nextAll:獲取所有的弟弟元素節(jié)點(diǎn)
// siblings:獲取所有的兄弟元素節(jié)點(diǎn)
// index:獲取當(dāng)前元素的兄弟中排名索引

7 Math的常用方法

7.1 數(shù)學(xué)函數(shù)

但是他是對(duì)象數(shù)據(jù)類型的

  • 'object'
  • Math對(duì)象中給我們提供了很多常用操作數(shù)字的方法
  • console.dir(Math) // 查看所有方法

7.1.1 abs

Math.abs 取絕對(duì)值

7.1.2 cell / floor

cell: 向上取整
floor: 向下取整

7.1.3 round

round: 四舍五入

7.1.4 random

random: 獲取一個(gè)[0,1]之間的一個(gè)隨機(jī)小數(shù)

7.1.5 max/minx

max 獲取一組值中的最大值
minx 獲取一組值中的最小值

7.1.6 PI

Math.PI 獲取圓周率

7.1.7 pow / sqrt

pow 獲取一個(gè)值的多少冪
sqrt 獲取一個(gè)值的開(kāi)平方

8 字符串及常用的方法

在js中用單(雙)引號(hào)包裹起來(lái)的都是字符串

var str = 'welcome to credan!'

字符串就是由零到多個(gè)字符串組成的

第一個(gè)字符索引0<br />第二個(gè)字符索引1<br />...<br />有l(wèi)ength的屬性啦租,存儲(chǔ)的是當(dāng)前字符串中字符的個(gè)數(shù)(字符串的長(zhǎng)度)

以數(shù)字作為索引哗伯,從零開(kāi)始的

str[0] -> 'w' 第一個(gè)字符<br />strlength-> 46<br />str[str.length-1] -> '!' 最后一個(gè)字符<br />str[100] -> undefined 如果指定的索引不存在獲取的結(jié)果是undefined

真實(shí)項(xiàng)目中,我們經(jīng)常操作字符串刷钢,此時(shí)我們需要掌握常用的一些字符床操作方法

console.dir(String.prototype)

charAt && charCodeAt

8.1 str.charCodeAt(索引):

在charAt 基礎(chǔ)上笋颤,把獲取的字符變?yōu)閁nicode編碼值(對(duì)應(yīng)ASCll碼表)

  • 48-57 0-9
  • 65-90 A-Z
  • 97-122 a-z
  • ...

String.fromCharCode(十進(jìn)制的Unicode值),把值按照ascll碼表中的信息内地,轉(zhuǎn)為原有字符伴澄,charCodeAt正好對(duì)應(yīng)<br />


image.png

8.2 substr && substring && slice

  • 實(shí)現(xiàn)字符串截取的三個(gè)辦法
  • str.substr(n.m) : 從索引n開(kāi)始,截取m個(gè)字符
  • str.substring(n,m):從索引n開(kāi)始阱缓,截取到索引為m處(包含m)非凌,把找到的部分截取
  • str.slice(n,m):和substring語(yǔ)法意義,區(qū)別在于slice支持一負(fù)數(shù)做索引
image.png

當(dāng)索引是負(fù)數(shù)的時(shí)候荆针,瀏覽器在處理的時(shí)候敞嗡,是用字符串的總長(zhǎng)度加上負(fù)數(shù)索引,然后按照正數(shù)處理操作

細(xì)節(jié):

  • 如果只傳遞了n(str.substr(n)/str.substring(n)),相當(dāng)于索引n開(kāi)始的一直截取到字符串的末尾
  • 如果傳遞的索引超出最大限制航背,也是吧能截取的部分截取掉即可
  • 如果一個(gè)參數(shù)都不傳遞:相當(dāng)于吧證書(shū)字符串都截取(字符串的克隆)
image.png

indexOf && lastIndexOf

  • str.indexOf 獲取當(dāng)前字符在字符串中第一次出現(xiàn)位置的索引
  • str.lastIndexOf 獲取的是最后一次出現(xiàn)位置的索引
image.png

如果當(dāng)前字符在字符串中沒(méi)有出現(xiàn)過(guò)喉悴,結(jié)果是-1:我們根據(jù)這個(gè)規(guī)律可言驗(yàn)證一下當(dāng)前字符串中是否包含某個(gè)字符

if(str.indexOf('?')===-1){
    // => 沒(méi)有出現(xiàn)過(guò)
}

if(str.indexOf('?')>=-1){
    // => 出現(xiàn)過(guò)
}

8.3 split

str.split 按照某個(gè)字符串分成數(shù)組中的某一項(xiàng),和數(shù)組中的join方法是對(duì)應(yīng)

image.png

8.4 replace

str.replace 實(shí)現(xiàn)字符的替換
執(zhí)行一次replace 只能替換一次玖媚,如果有好幾個(gè)都需要替換箕肃,在不適用正則的情況下,我們需要執(zhí)行很多次replace

image.png

有些需求及時(shí)執(zhí)行很多次repalce也實(shí)現(xiàn)不了今魔,此時(shí)需要使用正則處理勺像,真實(shí)項(xiàng)目中replace一般都是和正則搭配使用的

image.png

8.5 trim && trimLeft && trimRight

  • str.trimLeft : 去除字符串開(kāi)始的口空格
  • str.trimRight : 去除字符串結(jié)尾的口空格
  • str.trim 去除字符串首位的空格
image.png

獲取地址欄的值

function queryURLPrameter(url){
    // => url 傳遞的參數(shù)
  var quesIndex = url.indexOf('?'),
          obj = {}
  if(quesIndex === -1){ // url中沒(méi)有問(wèn)號(hào)傳參 直接返回空
        retrun obj;
  }
  url = url.substr(quesIndex + 1);
  var ary = url.split('&');
  for(var i =0;i<ary.length;i++){
    var curAry = ary[i].split('=');
    obj[curAry[0]] = curAry[i];
  }
  return obj
}
String.prototype.myQueryURLParameter = function
    myQueryURLParamter(){
    var obj = /([^=?&]+)=([^=?&]+)/g;
  this.replace(reg,function(){
    var arg = argments;
    obj[arg[1]] = arg[2]
  })
  return obj;
}

var str = 'https://www/baidu.com/s?wd=1233213&issp=1';
console.log(str.myQueryURLParameter());

9 Date的基礎(chǔ)知識(shí)

9.1 Data 是日期類

通過(guò)它可以對(duì)時(shí)間進(jìn)行處理

var time = new Date();
// 獲取當(dāng)前客戶端本機(jī)時(shí)間(當(dāng)前獲取的時(shí)間不能作為重要的參考依據(jù))

// 獲取結(jié)果是一個(gè)日期格式的對(duì)象
// Wed Mar 20 2019 17:37:16 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
typeof new Date() -> object


time.getFullYear() 獲取四位數(shù)整年
time.getMonth() 獲取月份
time.getDate() 獲取日
time.getDay() 獲取星期(0-6代表周日-周六)
time.getHours() 獲取小時(shí)
time.getMinutes() 獲取分鐘
time.getSeconds() 獲取秒
time.getMilliseconds() 獲取毫秒
time.getTime() 獲取當(dāng)前日期距離'1970-01-01 00:00:00'的毫秒差
var time = new Date('2017-10-22'); 
// 當(dāng)new Date 中傳遞一個(gè)時(shí)間格式的字符串,相當(dāng)于把這個(gè)字符串換位標(biāo)準(zhǔn)時(shí)間對(duì)象
// (轉(zhuǎn)換完成后错森,就可以調(diào)取上面我們講的那些方法)

// 時(shí)間格式的字符串<br />'2017-10-22' (IE下識(shí)別不了)<br />'2017/10/22 16:15:34'<br />'1508659621314'(如果傳遞的是距離1970年那個(gè)毫秒查吟宦,也可以識(shí)別轉(zhuǎn)換的,但是只能是數(shù)字,不能是字符串)<br />

10 數(shù)組的函數(shù)

10.1 數(shù)組的基礎(chǔ)結(jié)構(gòu)

  • 數(shù)組也是對(duì)象數(shù)據(jù)類型 typeof [] -> 'object'
  • 數(shù)組也是屬性名涩维,只不過(guò)屬性名是數(shù)字殃姓,我們把數(shù)字屬性名稱之為它的索引:數(shù)組是以數(shù)字為索引,索引從零開(kāi)始,有一個(gè)length屬性代表數(shù)組的長(zhǎng)度
image.png

<br />

類數(shù)組:類似于數(shù)組辰狡,但是不是數(shù)組

  • 通過(guò)getElementsByTageName 獲取的元素集合是類數(shù)組
  • 函數(shù)中的實(shí)參集合argument也是類數(shù)組
image.png

<br />

// for 循環(huán)操作
for(var i =0;i<ary.length;i++){
    console.log(ary[i])
}

// for in 循環(huán)操作
for(var key in ary){
    // key:屬性名(數(shù)組中的屬性名是索引)
    console.log(ary[key]);
}

// for 循環(huán)只能遍歷到數(shù)組私有的一些屬性锋叨,而for in 循環(huán)可以吧一些自定義的公共屬性也能遍歷到

10.2 數(shù)組中的常用方法

數(shù)組中有很多方法

console.dir(Array.prototype)
  • 方法的意義和作用
  • 方法的形參
  • 方法的返回值
  • 通過(guò)此方法,原來(lái)的數(shù)組是否發(fā)生了改變

實(shí)現(xiàn)數(shù)組的增加宛篇、修改娃磺、刪除

10.2.1 增加

push : 向數(shù)組的末尾追加新內(nèi)容

參數(shù):一到多個(gè),任何數(shù)據(jù)類型都可以叫倍,想要給數(shù)組末尾追加什么偷卧,直接傳遞到push方法中極客,傳遞多個(gè)逗號(hào)隔開(kāi)<br />返回值:新增后數(shù)組的長(zhǎng)度<br />原有數(shù)組改變了

unshift:向數(shù)組開(kāi)頭追加新內(nèi)容

參數(shù):需要追加的內(nèi)容(可以是多個(gè)任何數(shù)據(jù)類型的值)<br />返回值:新增后 數(shù)組的長(zhǎng)度<br />原來(lái)數(shù)組改變了

把數(shù)組當(dāng)做一個(gè)普通的對(duì)象吆倦,使用對(duì)象鍵值對(duì)的操作听诸,給其設(shè)置新的屬性(索引)<br />ary[ary.length]=xxx 向數(shù)組的末尾追加了新的內(nèi)容

10.2.2 刪除

pop 刪除數(shù)組最后一項(xiàng)

參數(shù):無(wú)<br />返回值:被刪除的那一項(xiàng)內(nèi)容<br />原有數(shù)組改變了

shift:刪除數(shù)組第一項(xiàng)

參數(shù):無(wú)<br />返回值:被刪除那一項(xiàng)的內(nèi)容<br />原有數(shù)組改變了<br />使用shift刪除第一項(xiàng)之后,后面每一項(xiàng)的索引都要向前進(jìn)一位(導(dǎo)致后面項(xiàng)的索引發(fā)生了改變)

把數(shù)組當(dāng)做一個(gè)普通對(duì)象操作<br />delete刪除:delete ary[索引]刪除指定索引這一項(xiàng)(當(dāng)前項(xiàng)被刪除后),原有數(shù)組其它項(xiàng)的索引不會(huì)改變:當(dāng)前數(shù)組的length也不會(huì)改變

ary.length--:刪除數(shù)組最后一項(xiàng)

splice:數(shù)組中內(nèi)置的方法蚕泽,可以實(shí)現(xiàn)數(shù)組的增加晌梨、修改、刪除

splice實(shí)現(xiàn)刪除<br />splice(n,m):從索引n開(kāi)始刪除m個(gè)(m不寫(xiě)是個(gè)刪除列數(shù)組的末尾须妻,n也不寫(xiě))<br />返回值:被刪除的內(nèi)容(以一個(gè)新數(shù)組保存)<br />原有數(shù)組改變了<br />splice(0) 清空數(shù)組<br />splice() 一項(xiàng)都不刪除仔蝌,返回一個(gè)新的空數(shù)組<br />splice(0,1)刪除第一項(xiàng)

splice實(shí)現(xiàn)修改

splice(n,m,x):在原有刪除的基礎(chǔ)上,用x代替刪除的內(nèi)容

splice實(shí)現(xiàn)增加<br />splice(n,0,x):在修改的基礎(chǔ)上荒吏,我們一項(xiàng)都不刪除敛惊,把x插入到索引n的前面<br />ary.splice(0,0,x) 向數(shù)組末尾追加新元素

數(shù)組的查詢

slice 數(shù)組的查詢
  • 參數(shù):slice(n,m) 從索引n開(kāi)始找到索引m處(不包含m)
  • 返回值:吧找到的部分已一個(gè)新數(shù)組返回
  • 原來(lái)的數(shù)組不變

slice(n) 從索引n開(kāi)始找到末尾<br />slice(0) /slice() 數(shù)組克隆,克隆一份和原來(lái)數(shù)組一模一樣的的新數(shù)組<br />slice支持負(fù)載索引绰更,如果傳遞的索引為負(fù)數(shù)瞧挤,瀏覽器解析的時(shí)候是按照總長(zhǎng)度+負(fù)數(shù)索引 來(lái)處理的

將兩個(gè)數(shù)組進(jìn)行拼接

concat:將多個(gè)數(shù)組拼接在一起

  • 參數(shù):要拼接的內(nèi)容(把內(nèi)容放在原數(shù)組的后面),可以是一個(gè)數(shù)組
  • 返回:拼接后的新數(shù)組

原有數(shù)組不變<br />
image.png

10.3 數(shù)組的查詢

slice: 數(shù)組的查詢<br />參數(shù): slice(n,m) 從索引n開(kāi)始找到索引為m處(不包含m)<br />返回值:把找到的部分已一個(gè)新數(shù)組返回<br />原來(lái)的數(shù)組不變

slice(n) 從索引n開(kāi)始找到末尾
slice(0) / slice() 數(shù)組克隆儡湾,克隆一份和原來(lái)數(shù)組一模一樣的新數(shù)組
slice 支持負(fù)數(shù)索引特恬,如果傳遞的索引為負(fù)數(shù),瀏覽器解析的時(shí)候是按照徐钠,總長(zhǎng)度+負(fù)數(shù)索引 來(lái)處理的

10.4 數(shù)組的拼接

concat:將多個(gè)數(shù)組拼接在一起<br />參數(shù):要拼接的內(nèi)容(把內(nèi)容放在原數(shù)組的后面),可以是一個(gè)數(shù)組鸵鸥,也可以是一些數(shù)據(jù)值<br />返回:拼接后的新數(shù)組<br />原有的數(shù)組不變

let arr = [0,100]
arr.concat([100,200],[200,300],12)

concat() 什么都沒(méi)有拼接,相當(dāng)于吧原有數(shù)組克隆一份一模一樣的出來(lái)<br />
image.png

10.5 數(shù)組轉(zhuǎn)字符串

10.5.1 toString

實(shí)現(xiàn)吧數(shù)組轉(zhuǎn)化為字符串(轉(zhuǎn)換后的字符串逗號(hào)分隔每一項(xiàng))

參數(shù):無(wú)<br />返回值:轉(zhuǎn)換的字符串<br />原有數(shù)組不變

10.5.2 join

把數(shù)組按照指定的分隔符轉(zhuǎn)換為字符串丹皱,和字符串中的split相對(duì)應(yīng)

  • 參數(shù):指定的鏈接符號(hào)
  • 返回值:轉(zhuǎn)換后的字符串
  • 原有數(shù)組不變
image.png

已知數(shù)組的每一項(xiàng)都是數(shù)字,想事先數(shù)組求和宋税,我們?nèi)绾螌?shí)現(xiàn)摊崭?

循環(huán)實(shí)現(xiàn)

var total = null;
for(var i=0;i<ary.length;i++){
    total+=ary[i];
}

利用join

var total = eval(ary.join('+')) // evel:把字符串變?yōu)閖s表達(dá)式執(zhí)行

10.6 實(shí)現(xiàn)數(shù)組中每一項(xiàng)的排序和排列

10.6.1 reverse

把數(shù)組中每一項(xiàng)倒過(guò)來(lái)排序

參數(shù):無(wú)<br />返回值:排序后的數(shù)組<br />原有數(shù)組改變

10.6.2 sort

實(shí)現(xiàn)數(shù)組的排序

參數(shù):無(wú)或者回調(diào)函數(shù)<br />返回值:排序后的數(shù)組<br />原有數(shù)組改變<br /> 不傳遞參數(shù)的情況下:可以給10以內(nèi)的數(shù)字進(jìn)行升序排列,但是超過(guò)10的就無(wú)法處理(多位數(shù)值識(shí)別第一位)

ary.sort(function(a,b){
    return a-b; //升序
  return b-a; //降序
})

10.7 驗(yàn)證數(shù)組中是否包含某一項(xiàng)

10.7.1 indexOf / lastindexOf

獲取當(dāng)前現(xiàn)在數(shù)組中第一次或者最后一次出現(xiàn)的位置索引

  • 數(shù)組的這兩個(gè)方法在IE6-IE8下不兼容
  • 字符串的這兩個(gè)方法兼容所有的瀏覽器
if(ary.indexOf(12)>-1){
    // 數(shù)組中包含12
}

10.7.2 原理

Array.prototype.myIndexOf = function myIndexOf(value){
    var result = -1;
  for(var i =0;i<this.length;i++){
    if(value===this[i]){
        result = i;
      break;
    }
  }
  return result;
}

10.8 遍歷數(shù)組每一項(xiàng)的方法

以下方法ie6-8下都不兼容

10.8.1 forEach

遍歷數(shù)組中的每一項(xiàng)

ary.forEach(function(value,index){
    /* 數(shù)組中有多少項(xiàng)杰赛,當(dāng)前回調(diào)函數(shù)執(zhí)行多少次呢簸,妹妹一次傳進(jìn)來(lái)的value就是當(dāng)前遍歷數(shù)組這一項(xiàng)的值,index
     就是遍歷這一項(xiàng)的索引
  */
})

10.8.2 map

遍歷數(shù)組中的每一項(xiàng),在forEach的基礎(chǔ)上根时,可以修改每一項(xiàng)的值

ary.map(function(value,index){
    /* 數(shù)組中有多少項(xiàng)瘦赫,當(dāng)前回調(diào)函數(shù)執(zhí)行多少次,妹妹一次傳進(jìn)來(lái)的value就是當(dāng)前遍歷數(shù)組這一項(xiàng)的值蛤迎,index
     就是遍歷這一項(xiàng)的索引
  */
  return xxx;
  // return 后面返回的結(jié)果就是當(dāng)前遍歷的這一項(xiàng)修改為xxx
})

filter<br />find<br />reduce<br />every<br />...

10.9 數(shù)組去重

var ary = [1,2,3,4,5,6,7,1,3,4,5];

方案一 最簡(jiǎn)單數(shù)組去重法

遍歷數(shù)組的每一項(xiàng)确虱,拿每一項(xiàng)和它后面的項(xiàng)依次比較,如果相同了,則把相同的這一項(xiàng)在原來(lái)數(shù)組中刪除即可

/*
* 新建一新數(shù)組替裆,遍歷傳入數(shù)組校辩,值不在新數(shù)組就push進(jìn)該新數(shù)組中
* IE8以下不支持?jǐn)?shù)組的indexOf方法
* */
function uniq(array){
    var temp = []; //一個(gè)新的臨時(shí)數(shù)組
    for(var i = 0; i < array.length; i++){
        if(temp.indexOf(array[i]) == -1){
            temp.push(array[i]);
        }
    }
    return temp;
}

var aa = [1,2,2,4,9,6,7,5,2,3,5,6,5];
console.log(uniq(aa));

方案二 對(duì)象鍵值法去重

/*
* 速度最快, 占空間最多(空間換時(shí)間)
*
* 該方法執(zhí)行的速度比其他任何方法都快辆童, 就是占用的內(nèi)存大一些宜咒。
* 現(xiàn)思路:新建一js對(duì)象以及新數(shù)組,遍歷傳入數(shù)組時(shí)把鉴,判斷值是否為js對(duì)象的鍵故黑,
* 不是的話給對(duì)象新增該鍵并放入新數(shù)組。
* 注意點(diǎn):判斷是否為js對(duì)象鍵時(shí)庭砍,會(huì)自動(dòng)對(duì)傳入的鍵執(zhí)行“toString()”场晶,
* 不同的鍵可能會(huì)被誤認(rèn)為一樣,例如n[val]-- n[1]逗威、n["1"]峰搪;
* 解決上述問(wèn)題還是得調(diào)用“indexOf”。*/
function uniq(array){
    var temp = {}, r = [], len = array.length, val, type;
    for (var i = 0; i < len; i++) {
        val = array[i];
        type = typeof val;
        if (!temp[val]) {
            temp[val] = [type];
            r.push(val);
        } else if (temp[val].indexOf(type) < 0) {
            temp[val].push(type);
            r.push(val);
        }
    }
    return r;
}

var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));

方案三 排序后相鄰去除法

/*
* 給傳入數(shù)組排序凯旭,排序后相同值相鄰概耻,
* 然后遍歷時(shí),新數(shù)組只加入不與前一值重復(fù)的值。
* 會(huì)打亂原來(lái)數(shù)組的順序
* */
function uniq(array){
    array.sort();
    var temp=[array[0]];
    for(var i = 1; i < array.length; i++){
        if( array[i] !== temp[temp.length-1]){
            temp.push(array[i]);
        }
    }
    return temp;
}

var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));

方案四 數(shù)組下標(biāo)法

/*
*
* 還是得調(diào)用“indexOf”性能跟方法1差不多罐呼,
* 實(shí)現(xiàn)思路:如果當(dāng)前數(shù)組的第i項(xiàng)在當(dāng)前數(shù)組中第一次出現(xiàn)的位置不是i鞠柄,
* 那么表示第i項(xiàng)是重復(fù)的,忽略掉嫉柴。否則存入結(jié)果數(shù)組厌杜。
* */
function uniq(array){
    var temp = [];
    for(var i = 0; i < array.length; i++) {
        //如果當(dāng)前數(shù)組的第i項(xiàng)在當(dāng)前數(shù)組中第一次出現(xiàn)的位置是i,才存入數(shù)組计螺;否則代表是重復(fù)的
        if(array.indexOf(array[i]) == i){
            temp.push(array[i])
        }
    }
    return temp;
}

var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));

方案五 優(yōu)化遍歷數(shù)組法

// 思路:獲取沒(méi)重復(fù)的最右一值放入新數(shù)組
/*
* 推薦的方法
*
* 方法的實(shí)現(xiàn)代碼相當(dāng)酷炫夯尽,
* 實(shí)現(xiàn)思路:獲取沒(méi)重復(fù)的最右一值放入新數(shù)組。
* (檢測(cè)到有重復(fù)值時(shí)終止當(dāng)前循環(huán)同時(shí)進(jìn)入頂層循環(huán)的下一輪判斷)*/
function uniq(array){
    var temp = [];
    var index = [];
    var l = array.length;
    for(var i = 0; i < l; i++) {
        for(var j = i + 1; j < l; j++){
            if (array[i] === array[j]){
                i++;
                j = i;
            }
        }
        temp.push(array[i]);
        index.push(i);
    }
    console.log(index);
    return temp;
}

var aa = [1,2,2,3,5,3,6,5];
console.log(uniq(aa));

11 函數(shù)基礎(chǔ)

  • 函數(shù)是指一段在一起的登馒、可以做某一件事兒的程序匙握。也叫做子程序、(OOP中)方法
  • 函數(shù)實(shí)現(xiàn)某一個(gè)功能的方法

11.1 創(chuàng)建函數(shù)

functoin [函數(shù)名](){
        // => [函數(shù)體]
    // 實(shí)現(xiàn)功能的具體js代碼
}

11.2 執(zhí)行函數(shù)

函數(shù)名(); // 創(chuàng)建的函數(shù)執(zhí)行陈轿,而且這個(gè)函數(shù)可以執(zhí)行很多次
函數(shù)名();

每一次執(zhí)行都相當(dāng)于把函數(shù)體重實(shí)現(xiàn)功能的js代碼重復(fù)執(zhí)行了一遍

在真實(shí)的項(xiàng)目中圈纺,我們一般都會(huì)把實(shí)現(xiàn)一個(gè)具體功能的代碼封裝到函數(shù)中

  • 如果當(dāng)前這個(gè)功能需要在頁(yè)面中執(zhí)行多次秦忿,不封裝成為函數(shù),每一次實(shí)現(xiàn)這個(gè)功能蛾娶,都需要重新吧代碼寫(xiě)一遍灯谣,浪費(fèi)時(shí)間;而封裝在一個(gè)函數(shù)中蛔琅,以后想實(shí)現(xiàn)多次這個(gè)功能胎许,我們就沒(méi)有必要在重新寫(xiě)代碼,只需要把函數(shù)重新的執(zhí)行即可揍愁,提高了開(kāi)發(fā)效率
  • 封裝在一個(gè)函數(shù)呐萨,頁(yè)面中就基本上很難重復(fù)一樣的代碼了,減少了頁(yè)面中代碼的冗余度莽囤,提高了代碼的重復(fù)利用率: 低耦合高內(nèi)聚

我們把以上的特點(diǎn)成為函數(shù)封裝 (OOP面向?qū)ο缶幊趟枷朊粒枰覀冋莆盏木褪穷惖睦^承、封裝朽缎、多態(tài))

11.3 JS中函數(shù)的核心原理

函數(shù)作為js中引用數(shù)據(jù)類型中的一種惨远,也是按照引用地址操作的

function sum(){
    var total = 1+1;
  total *= 20;
  console.log(total.toFixed(2));
}
sum();

11.3.1 創(chuàng)建函數(shù)

  • 首先會(huì)在當(dāng)前作用中聲明一個(gè)函數(shù)名(聲明的函數(shù)和使用var聲明變量是一樣的操作:var sum;function cum;這兩個(gè)名字算重復(fù)了)
  • 瀏覽器首先會(huì)開(kāi)辟一個(gè)新的內(nèi)存空間(奉陪一個(gè)16進(jìn)制地址),把函數(shù)體重寫(xiě)好的代碼當(dāng)做普通字符串存儲(chǔ)在這個(gè)內(nèi)存空間(創(chuàng)建一個(gè)函數(shù)如果不執(zhí)行话肖,函數(shù)沒(méi)有意義)
  • 把內(nèi)存空間的地址賦值給之前聲明的那個(gè)函數(shù)名

11.3.2 函數(shù)執(zhí)行

  • 目的:把之前存儲(chǔ)的實(shí)現(xiàn)具體功能的js代碼執(zhí)行
  • 函數(shù)執(zhí)行北秽,瀏覽器首先會(huì)為其開(kāi)辟新的私有作用域(只能執(zhí)行函數(shù)中之前編寫(xiě)的js代碼)
  • 形參賦值
  • 私有作用中的變量升級(jí)
  • 把之前穿件時(shí)間存儲(chǔ)的那些js代碼字符串,拿到自由作用域中最筒,然后把題目變成js表達(dá)式從上到下執(zhí)行
  • 私有作用域是否銷毀的問(wèn)題

<br />


image.png
image.png

<br />

11.3.3 閉包

函數(shù)執(zhí)行會(huì)形成一個(gè)私有的作用域贺氓,讓里面的私有變量和外界互不影響(相互干擾、外面的無(wú)法直接獲取里面的變量值)床蜘,此時(shí)我們可以理解為私有作用域把私有變量保護(hù)起來(lái)辙培,我們把這種保護(hù)機(jī)制稱為為閉包

11.3.4 棧內(nèi)存

作用域(全局作用域/私有作用域):提供一個(gè)供js代碼執(zhí)行的環(huán)境

11.3.5 堆內(nèi)存

所有的引用數(shù)據(jù)類型,他們需要存儲(chǔ)的內(nèi)容都是堆內(nèi)存中(相當(dāng)于一個(gè)倉(cāng)庫(kù)邢锯,目的是存儲(chǔ)信息)

  • 對(duì)象會(huì)吧鍵值隊(duì)存儲(chǔ)起來(lái)
  • 函數(shù)會(huì)把代碼當(dāng)做字符串存儲(chǔ)起來(lái)

11.4 函數(shù)中形參和實(shí)參

  • 形參:相當(dāng)于生成洗衣機(jī)的時(shí)候提供的入口扬蕊,需要用戶執(zhí)行函數(shù)的時(shí)候把需要的值傳遞進(jìn)來(lái),形參是個(gè)變量丹擎,用來(lái)春初和接口那些值
  • 實(shí)參:用戶執(zhí)行的時(shí)候傳遞給形參的具體指
// 隨便求出兩個(gè)數(shù)的和

function sum(num1,num2){ //num1/num2就是形參變量(類似于var了一下)
        var total = num1 + num2;
    total*=10;
    total=total.toFixed(2);
        console.log(total);
}

sum(10,20);//10/20是實(shí)參  num1=10 num2=20
sum(10); // num1=10 num2=undefined 定義了形參但是執(zhí)行的時(shí)候尾抑,沒(méi)有傳遞實(shí)參,默認(rèn)實(shí)參就是undefined

11.5 arguments實(shí)參集合

當(dāng)我們不知道用戶具體要傳遞幾個(gè)值的時(shí)候(傳遞幾個(gè)值都行)蒂培,此時(shí)我們無(wú)法設(shè)置形參的個(gè)數(shù):遇到此類需要再愈,需要使用函數(shù)內(nèi)置的實(shí)參集合:arguments

  • argument 只有函數(shù)才有
  • 不管執(zhí)行函數(shù)的時(shí)候是否傳遞實(shí)參,arguments天生就純?cè)诨ご粒瑳](méi)有傳遞實(shí)參ARG是個(gè)空的集合傳遞了ARG中包含了所有傳遞的實(shí)參值
  • 不管是否設(shè)置了形參践磅,ARG中始終存儲(chǔ)了所有的實(shí)參信息
function sum(){
    console.log(arguments)
}
sum(10,20,'wjh',{name:'wjw'});
image.png
  • arguments 是個(gè)類數(shù)組集合
    • 以數(shù)字作為索引(屬性名),從0開(kāi)始
    • arguments[0] 第一個(gè)實(shí)參信息
    • arguments[2] 第三個(gè)實(shí)參信息
    • arguments[n] 第n+1個(gè)實(shí)參信息
  • 有一個(gè)length的屬性灸异,存儲(chǔ)的是當(dāng)前幾個(gè)的長(zhǎng)度(當(dāng)前傳遞實(shí)參的個(gè)數(shù))
    • arguments.length
    • arguments['length']
    • arguments.calle 存儲(chǔ)的是當(dāng)前函數(shù)本身
    • arguments.calle.caller 存儲(chǔ)的是當(dāng)前函數(shù)只在哪執(zhí)行的(宿主函數(shù))府适,在全局作用域下執(zhí)行的,結(jié)果是null
function sum(){
    console.log(arguments.callee.caller);//f
}
function fn(){
    sum(10,20,'wjh',{name:'wjw'});
}
fn();

// arguments.call或者arguments.call.caller一般真正項(xiàng)目中很少使用肺樟,因?yàn)槭窃趪?yán)格js模式下不允許我們直接使用這兩個(gè)屬性檐春,然而現(xiàn)有項(xiàng)目大部分都是基于嚴(yán)格模式來(lái)的

// 任意數(shù)求和

function sum(){
    var total = null;
  for(var i =0;i<arguments.length;i++){
    var cur = Number(arguments[i]);
    !isNaN(cur)?total += cur : null
  }
  consloe.log(total);
  return total;
  // return 后面跟著的都是值(返回的都是值):此處不少TOTAL變量返回,而是吧total存儲(chǔ)到值返回而已
  // return 60;
}
sum(10,20,20);
sum();
sum(10,20,30,'wjw')
// console.log(total); 
//=>Uncaught ReferenceError: total is not defined 閉包的保護(hù)機(jī)制導(dǎo)致作用域會(huì)保護(hù)里面的私有變量

11.6 JS中的返回值return

返回值是函數(shù)提供的一個(gè)出口:我們?nèi)绻朐谕饷媸褂煤瘮?shù)私有的一些信息么伯,那么就需要通過(guò)return疟暖,把這些信息返回出來(lái)供外面使用

sum:代表的是函數(shù)本身<br />sum() 讓函數(shù)先執(zhí)行,代表的是當(dāng)前函數(shù)返回的結(jié)果(return)后面是啥田柔,相當(dāng)于函數(shù)返回的是啥

function sum(){
        var total = 0;
    renturn
}
console.log(sum());
// 如果函數(shù)中沒(méi)有return或者return后面啥也沒(méi)有俐巴,默認(rèn)返回的結(jié)果是undefined
function sum(){
        var total = 0;
    renturn;
    console.log(sum());
    // 函數(shù)體重遇到return后,return后面的代碼都不在執(zhí)行了
}

11.7 js中匿名函數(shù)

沒(méi)有名字的函數(shù)

  • 函數(shù)表達(dá)式
  • 自執(zhí)行函數(shù)
oBox.onclick = function(){
    // 把一個(gè)碼云名字的函數(shù)(有名字的也無(wú)所謂)作為值賦值給一個(gè)變量或者一個(gè)元素的某一個(gè)事件等,函數(shù)表達(dá)式

}
(function(n){
    // 創(chuàng)建函數(shù)和執(zhí)行函數(shù)放在一起硬爆,穿件完成立馬之執(zhí)行:自執(zhí)行函數(shù)
  // n 形參 n=10
})(10)

// 以下都是自執(zhí)行函數(shù)欣舵,符號(hào)只有控制語(yǔ)法規(guī)范
~function(){}(10)
-function(){}(10)
+function(){}(10)
!function(){}(10)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市缀磕,隨后出現(xiàn)的幾起案子缘圈,更是在濱河造成了極大的恐慌,老刑警劉巖袜蚕,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糟把,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡牲剃,警方通過(guò)查閱死者的電腦和手機(jī)遣疯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)凿傅,“玉大人缠犀,你說(shuō)我怎么就攤上這事∠凉椋” “怎么了夭坪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)过椎。 經(jīng)常有香客問(wèn)我室梅,道長(zhǎng),這世上最難降的妖魔是什么疚宇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任亡鼠,我火速辦了婚禮,結(jié)果婚禮上敷待,老公的妹妹穿的比我還像新娘间涵。我一直安慰自己,他們只是感情好榜揖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布勾哩。 她就那樣靜靜地躺著抗蠢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪思劳。 梳的紋絲不亂的頭發(fā)上迅矛,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音潜叛,去河邊找鬼秽褒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛威兜,可吹牛的內(nèi)容都是我干的销斟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼椒舵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蚂踊!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起逮栅,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悴势,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后措伐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體特纤,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年侥加,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捧存。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡担败,死狀恐怖昔穴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情提前,我是刑警寧澤吗货,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站狈网,受9級(jí)特大地震影響宙搬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拓哺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一勇垛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧士鸥,春花似錦闲孤、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)肥照。三九已至,卻和暖如春勤众,著一層夾襖步出監(jiān)牢的瞬間建峭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工决摧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凑兰。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓掌桩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親姑食。 傳聞我的和親對(duì)象是個(gè)殘疾皇子波岛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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