第一章
前端三大語言:HTML(專門編寫網頁內容)、CSS(編寫網頁樣式)、JS(專門編寫網頁交互行為)
能簡寫盡量簡寫
交互(IPO): ①用戶輸入;②執行: 程序接受、處理、響應數據;③輸出處理結果
原生JS:不需要下載任何第三方文件,僅依靠瀏覽器就可直接執行的js代碼
學習版本:ES6(2015)
現版本:ES7
中文亂碼問題:引入的 .js 文件要與HTML文件一樣是UTF-8模式,否則要在script中加?charset="gbk",但兩個不能同時使用
API(Application Programming Interface,應用程序編程接口)是一套用來控制Windows的各個部件的外觀和行為的一套預先定義的Windows函數
如果回調函數無法取名,可以在回調函數中調用定義的另一個有名的函數,以此來達到目的
判斷數據是否為null、0、""、NaN、null、undefined一律可以省略等號后的值,只判斷是否為false
js的事件監聽跟css不一樣,css只要設定好了樣式,不論是原來就有的還是新添加的,都有一樣的表現,而事件監聽不同,只能給已經加載好的元素綁定事件
_______________________________________________________________________________________________
typeof null返回object
最初,JavaScript使用標記位來區分對象類型和原始類型:對象值使用0來標識,原始值使用1,因此,導致全為0的null被識別為object
JavaScript可以通過typeof ...來判斷原始數據類型,但不能夠準確判斷引用類型,但可以用Object的toString方法來判斷:?console.log(Object.prototype.toString.call(要判斷的數據))
一元運算符: 有些運算符兩邊有2個操作數,比如2+3、6%5等,這些叫做二元運算符
? ? ? ? ? ? 只有一個操作數的叫做一元運算符,它們的優先級高于二元運算符
? ? ? ? ? ? 一元運算符包括: ++(自加)、--(自減)、!(邏輯非)
JS的運算規則: 優先級相同的運算符從左向右計算(賦值運算符相反)
var a=1;b=++a+a++; 表示 b=2+2;
var a={n:1};
var b=a;
a.x=a={n:2}; ? ?//從左往右讀(取出來),從右往左執行
? ? ? ? ? ? ? ? //先執行a.x={n:2},再執行a={n:2}
console.log(a.x);? ? //undefined
console.log(b.x);? ? //{n:2}
console.log(a);? ? ? //{n:2}
console.log(b);? ? ? //{n:1, x:{n:2}}
_______________________________________________________________________________________________
1、Javascript概述
Javascript運行于Javascript 【解釋器/引擎】中的解釋性腳本語言
Javascript運行環境:1、Javascript解釋器 :NodeJS
? ? ? ? ? ? ? ? ? ? 2、嵌入在瀏覽器中的內核(引擎)
? 解釋型:無需編譯,直接運行,出錯就停止
? 腳本語言:純文本語言
? JS解釋器和JS引擎:1、獨立安裝的JS解釋器:NodeJS
? ? ? ? ? ? ? ? ? ? 2、嵌入在瀏覽器內核中的JS解釋器:只要有瀏覽器,就能運行JS
2、Javascript 發展
? ①1992年 Nombas公司開發了一款腳本語言 ScriptEase ,可以嵌入在網頁中
? ②1995年 Netscape(網景)公司為Navigator2.0瀏覽器開發了一款腳本語言 LiveScript,為了蹭熱點將其命名為 Javascript,其實Javascript與Java沒有一點關系
? ③1996年,Microsoft ,為了IE3.0,發布了一個Javascript克隆版本 JScript
? ④1997年 Javascript1.1 作為草案提交給了ECMA(歐洲計算機制造商協會)→ECMA-262標準→ECMAScript(ECMA制定的JavaScript語言國際標準,規定了JS語言的核心語法)
3、Javascript (原生JS)的組成
??① 核心(ECMAScript,簡稱ES,ECMA制定的JavaScript語言國際標準,規定JS語言的核心語法)
? ② 文檔對象模型(DOM---Document Object Model)允許讓JS和HTML元素進行對話
?專門操作網頁內容的API
? ③ 瀏覽器對象模型(BOM—Browser Object Model)允許讓JS和瀏覽器進行對話和操作
?專門操作瀏覽器窗口的API
4、Javascript特點:
? ①任何編輯工具(例如:記事本)都可以編寫Javascript,語法類似于Java,C,...
? ②無需編譯,由JS解釋器運行(自上向下邊讀邊解釋邊執行,后解釋的相同內容會覆蓋先解釋的)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?賦值:?從左往右讀(取出來待執行),從右往左執行(賦值)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?運算:從左往右計算
? ③弱類型語言:聲明變量時,不必提前規定變量的數據類型,先后可保存不同類型的數據,由值來自動隱式轉換數據類型
? ④基于對象的編程語言———萬物皆對象
5、 Javascript的用途
? ①客戶端Javascript:瀏覽器中運行
? ? 1、客戶端數據計算
? ? 2、客戶端表單輸入驗證
? ? 3、瀏覽器事件的觸發和處理
? ? 4、客戶端動畫效果特效制作
? ? 5、服務器的異步數據提交(ajax)
? ②服務器端Javascript:1、分布式運算????2、實時服務器????3、窗口應用????4、網絡應用
_______________________________________________________________________________________________
Javascript基礎語法
1、JS運行在腳本解釋引擎:專門解析JS語言,并執行js程序的小軟件
瀏覽器內核:負責頁面內容的渲染,由兩部分組成:
? ①內容排版引擎:解析 HTML 和 CSS,并顯示網頁內容和樣式的小軟件,效率高
? ②腳本解釋引擎:解析并執行 Javascript 程序的小軟件,效率略低
全球僅有四個獨立的瀏覽器內核
? ? ? ? 瀏覽器 ? ? ? ? ? ?內核 ? ?內容引擎 ? ?腳本引擎
? ? Microsoft IE ? ? ? ?Trident? ? -- ? ? ? ? Chakra
? ? Mozilla Firefox ? ? ?Gecko? ?? -- ? ? ? ?Monkey系列
? ? Apple Safari ? ? ?? Webkit ? ?Webcore ? ? ?Nitro
? ? Google Chrome ? ? ?Webkit? ?Webcore ? ? ? V8
? ? Opera ? ? ? ? ? ? ?Presto? ? ?-- ? ? ?? Carakan
? ? Opera(2013 -) ? ? ? Webkit ? ?Webcore ? ? ? V8
2、Javascript運行環境
運行環境:
? ①安裝獨立的Javascript解釋器—Node.js
? ? 步驟:1、安裝NodeJS
? ? ? ? ? 2、運行JS腳本:console.log ("輸出的內容");
? ②瀏覽器內核嵌入的JS解釋器:在console中輸入腳本運行,將JS腳本嵌入在HTML網頁中執行
_______________________________________________________________________________________________
輸出位置(3個)
①向頁面添加內容:<script>document.write("html代碼段");</script>? /*document:當前網頁(不推薦)*/
②彈出對話框:彈出對話框顯示消息:alert("提示消息");? ?? /*彈出瀏覽器預定好的樣式,不可修改*/
③向控制臺中輸出內容:F12→console.log("xx");? ? /*控制臺專門用于調試程序,臨時顯示調試結果*/
書寫位置(2處)
①頁面的<script type="text/javascript"></script>標簽中嵌入腳本
? EX:?<script>document.write("xxx");</script>
? ? ? document.write:網頁中打印輸出一句話!里面的內容是交給內容排版引擎解析的
? EX:docume.write("<h1>第一個JS</h1>");
一旦進入script標簽內,就要使用js的語法
問題: 不符合內容與行為分離的原則,不便于維護和共用
②將腳本嵌入在外部的腳本文件中
? 1、創建腳本文件并編寫JS腳本:創建一個**.JS文件;直接編寫JS腳本
? 2、使用網頁中進行引入:<script src="url"></script>
? ? ?注意:必須成對出現,兩個script標簽之間不允許出現其他內容
? ? ?放在<head></head>中,瀏覽器解析head部分時就會執行這個代碼,然后才會解析頁面其它部分
? ? ?放在<body></body>中,瀏覽器讀取到該語句時才會執行(一般使用此方法)
3、JS基本調試
? JS運行過程中,如果出現錯誤,則終止本塊的執行,但不影響后續代碼塊執行
? <script></script>:代碼塊
4、基本語法規范
? ①代碼的基本組成:語句
? ? 語句:允許被JS引擎所解釋的代碼,由表達式,關鍵字,運行符所組成
? ? 注意:嚴格區分大小寫
? ? ? ? ?所有的標點,全部都是英文的
? ? ? ? ? 字符串可以用" "或' '
? ? ? ? ?語句都是以;表示結束
? ②JS中的注釋:單行注釋:// ? ? ? ? ? ? ? ? ? ? ?多行注釋:/**/
_______________________________________________________________________________________________
輸出臺操作(F12):
①Shift+Enter: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*僅換行暫不執行,用于多行輸出*/
②console.log("Hello World!"); ? ? ? ? ? ? ? /*每寫log一次,都自動換行*/
③左上角圓形叉號:Clear console ? ? ? ? ? ? ? /*清空控制臺*/
④調出剛寫過的代碼段:上下鍵切換
調試程序:2種
斷點調試:debugger; ? ?/*加在console.log 之前,在開著F12的情況下才有效*/
console.log(" , , "); /*在控制臺輸出(""中的+會將這兩個變量視為字符串,最后一個不能加,)*/
啟用嚴格模式:在script頂部插入:"use strict"; ? ? ? ? ? ? /*解決靜默失敗*/
嚴格模式下: 不用var定義變量是非法的,會導致錯誤;調用函數中的this值是undefined
非嚴格模式下: 不用var定義變量是全局變量;調用函數中的this值是全局對象
輸入: prompt("輸入提示") ? ? ? ? /*輸入框: 專門請用戶輸入一個數據的對話框*/
_______________________________________________________________________________________________
變量和常量
變量
1、什么是變量:內存中存儲一個數據的存儲空間,再起一個名字,為了重用
? ?量:數據
? ?變量:變化的數據
? ?內存:保存程序在運行過程中所需要用到的數據
?? 變量:內存中的一段存儲空間,用于保存數據
?? 值:變量中所保存的數據
?? 變量名:內存地址的別名即保存數據的空間的名稱
2、變量的聲明
①聲明變量:在內存中,創建一個存儲空間,再起一個名字
var 變量名;
默認值:undefined:專門表示一個從未使用過的變量
②為變量賦值:將數據保存在變量中(盡量不要讓變量空著,賦初值)
變量名=值;
注意:只有等號才能改變變量中的值;等號會覆蓋變量中的原值;變量賦值前必須先聲明(給未聲明過的變量賦值,普通情況下自動創建新變量并保存值;ES5模式規定禁止給未聲明的變量賦值)
取用:取出變量中的值做運算,只要使用變量值,等效于直接使用變量中的值
? ? ? 不加引號的都會當做變量
③聲明變量并賦值
var 變量名=值; ? ? ? ? ? ? ? ?/*只有等號才能賦值*/
注意:如果變量的值時非數字類型的話,要使用''或""括起來
? ? ? 聲明時可以省略var關鍵字,省略后成為了全局變量,推薦不要省略var關鍵字
④推薦:?一條語句聲明多個變量,用,分隔(每個變量必須要用=才能賦值)(建議多個變量換行寫)
? ? 例:var 名1="xxx",名2="xxx",名3="xxx";
3、變量名的命名規范
? ①不允許是JS的關鍵字或保留關鍵字
? ②可以包含字母,數字,下劃線(_),$
? ③不能以數字開頭
? ④盡量見名知義
? ⑤可以采用“匈牙利命名法”,“駝峰命名法”,“下劃線命名法”
? ? 駝峰命名法:變量名稱,如果只有一個單詞組成,采用全小寫模式 ? 例:var age
? ? 如果變量名由多個單詞組成,第一個單詞全小寫,其余的每個單詞的首字母,變大寫
4、變量的使用
①變量定義后,未賦過值而直接使用
? EX:var userName;
? ? ? console.log (userName); ? ? 結果為:undefined,表示沒有值
②對變量進行存取操作
? 1、獲取變量的值-GET操作
? ?? 例:var userAge=18;--------存值
? ? ? ?? console.log(userAge);------------取值
? ? ? ? ?document.write(userAge);----------取值
? ? ? ?? user-----存值操作 ? 18------取值操作
輸出從未聲明的變量時會返回:ReferenceError ? ? ? 沒有找到對象
? 總結:只要變量沒有出現在=左邊,一律是取值
? 2、設置變量的值 – SET操作
? ? ?例:var userAge=15;
? ? ? ?? var newAge=userAge
? ? ? ?? userAge---取值 ? newAge---存值
? ? ? ?? newAge=newAge+15;
? ? ? ? ?console.log(newAge);--------30
? 總結:只要變量出現在=左邊,一律是存值操作
筆試題: var a,b=2; ?→ ?a:undefined? b:2
? ? ? ? var a=b=2; ?→ ?a:2 ?b:2 (在函數中時,a是局部變量,b是全局變量)
_______________________________________________________________________________________________
常量
1、什么是常量
一經聲明定義后,就不允許被修改的數據成為常量
目的:保證數據的準確性
適合用常量表示的數據:EX:1、圓周率:兀=3.1415926; ?2、一周有7天
2、語法
const 常量名=值;
注意:①常量不允許賦值,否則會靜默失敗,ES5嚴格模式會報錯
? ? ? ②聲明變量時,必須初始化其值
? ? ? ③習慣上,常量名采用純大寫形式
取值:和變量用法一樣
var 變量=prompt("提示")? /*請用戶輸入變量的值,并保存在變量中,不能在node里使用prompt*/
_______________________________________________________________________________________________
數據類型(掌握)
1、什么是數據類型
?? 保存在內存中數據的真實類型,約束了數據在內存所占的空間大小,存儲結構
?? 不同的數據類型,擅長執行的操作不一樣,就需要配套合適的存儲結構,給操作提供便利
2、數據類型分類
原始類型(基本數據類型: 值直接保存在變量本地的數據類型)
? 包括5個: number、string、boolean、null、undefined
引用類型: 值無法直接保存在變量本地的復雜數據類型
? 包括: Array、Function、Date、RegExp、Error、Object、String、Number、Boolean、Math、Window
數組是引用類型的對象,對象的本質就是關聯數組,只不過用法更簡單
函數名其實僅是一個普通的變量 ,函數其實是保存代碼段的引用類型的對象
? ①number類型:
專門用于存儲數字,表示32(8位一個字節)位的"整數",也可以標識64位的"浮點數",采用二進制存儲(),凡是不加引號的數字直接量,默認都是number類型
何時: 如果一個數值可能需要比較大小和進行數學計算時
存儲空間: 整數占4個字節,浮點數占8個字節,數值大小和存儲空間無關(1字節=8位二進制)
特殊:舍入誤差:計算機中也有計算不盡的數值
原因:number類型底層都是二進制存儲
解決:四舍五入
n.toFixed(n)//四舍五入,保留n位小數,返回字符串類型,傳入數字,可Number(x).toFixed(2)
typeof x / typeof(x) ? ? ? ? ? /*返回變量x中存儲的數據類型*/
var m=n.toString(2) ? ? ? ? ?? /*把n中的數值(先轉為Unicode)轉換為內存中的二進制形式*/
? ②string類型
什么是: 凡是加引號的一串字符直接量都是字符串類型,EX:姓名,性別,住址,身份證號,不用做計算和比較大小,都用""或''包裹
何時: 記錄一串文字
js中一切文字都是由Unicode字符、數字、標點符號的序列組成的
Unicode 是編碼(對全球主要語言的每個字編一個號)的一種,Unicode下所有的字符,每個字符均占2字節,而且每個字符都有一個獨一無二的Unicode碼
字母和數字占1個字節,漢字占2個字節
string類型的數據在使用過程中,要用""或''引起來
特殊字符需要轉義,稱為轉義字符(字符串中具有特殊功能的字符)
如果在字符串中包含了和js語法沖突的','等,都要用\轉義為普通字符
? 轉義字符 ? ? ? ? ?表現(輸出)形式
? ?\n ? ? ? ? ? ? ?? 一個換行
? ? \t ? ? ? ? ?? ? ? 制表符
? ? \\ ? ? ? ? ? ? ? ? ? \
? ? \" ? ? ? ? ? ? ? ? ? ''
? ? \' ? ? ? ? ? ? ? ? ? '
例:var str= '你\n好';
? ? 路徑:所有操作系統都支持/斜線,所以保存路徑時要將\換成/:
var n=str.charCodeAt(i);? //查看字符串str中下標i位置字符的unicode號
String.fromCharCode(unicode號)? ? //將unicode號,反向轉回文字,一次只能轉一個字,要用循環
var m=n.toString(2);? ?? //將n中的數值轉換為二進制形式
parseInt(10000000000,2);??//把二進制數轉換成十進制
var str=x.toString();? ? //將 x 轉為字符串類型,不改變原值x。x為數組時,結果str用,分隔
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? x不能是null或undefined ———?不是萬能
var str=String(x);? ? ? ? //將x轉為字符串類型———萬能(首選)
? ③boolean類型
作為條件的結果,來表示肯定(真)或否定(假)
何時: 只要作為判斷條件的結論時,就用boolean類型
取值:true:真(肯定)
? ? ? false:假 (否定)
例:var xxx=true;
該類型數據可以參與到數字的運算中:true = 1 ??false = 0
? ④undefined /⑤null
undefined:空,由程序自動為一個變量初始化之用;表示一個聲明后未賦值的變量、沒有返回值的函數
null:空,讓程序員用于手動清空一個變量之用,表示一個空地址
第二章*****************************************************************************************
x:任何數據
str:字符串
num:數字
數據類型轉換:(凡是從頁面上獲得的都是字符串)
作用:將不需要的數據類型,轉化為需要的數據類型
js四大特點:弱類型的3大特點:
?????1. 聲明變量時,不需要提前規定變量中存儲的數據類型
?????2. 同一個變量先后可保存不同類型的數據
?????3. js會根據自身的需要,隱式轉換數據的類型
何時:只要給定的數據類型不是想要的,都要轉換
方法有2種:
1、隱式轉換: 不需要程序員干預,由js自動完成的數據類型轉換
??? 何時: 只要給定的數據類型和js運算要求的類型不相符,js都會自動轉化數據類型,再運行
? ? 如何:每種運算中都自帶隱式轉換
? ? ? ? ? 比如: 算數計算中
規則:
? ? ①默認:一切都轉為number類型,再做計算
? ? 為什么: 因為number類型最適合計算
? ? ? ? bool: true->1 ? ? ?false->0
? ? ②特殊:+運算中,只要碰到一個字符串,一切都轉為字符串,+運算變為字符串拼接
若字符串左邊有變量,先計算變量,從左到右依次計算(按優先級),到字符串的位置后,都轉化為字符串
2. 強制轉換:程序員主動調用轉換函數實現的類型轉換(3種情況)
??? 何時: 只要給定的數據類型不是想要的,且自動轉換的結果也不是想要的,就要強制轉換
console.log(typeof x); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*輸出str的數據類型*/
_______________________________________________________________________________________________
其他類型轉number: 2種:
1. Number(x): 將純數字x字符串或bool轉為number類型(不直接修改原變量的值,而是返回新值)
x=Number(x); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? /*用于隱式轉換中自動調用*/
? ? 何時: 都是隱式轉換,其實相當于自動調用Number(x),很少主動使用
? ? 問題: 只能轉換純數字組成的字符串和bool類型
? ? 如果轉不了: 就返回NaN
? ?NaN: 代表一切不是一個數字的任何值:Not a Number
? ? NaN參與任何運算結果只能是NaN
2. parseFloat/parseInt(str):?將字符串str轉為number類型,可去除結尾非數字字符,但不去掉開頭的,因為表達式從左到右依次執行,所以可以在計算后直接加個單位(首選parseFloat)
? ? parseFloat可保留小數部分
? ? parseInt? 去掉小數部分(向下取整)? ? ?? //當使用e作為計數符號時,也會去掉e符號
? ? 何時: 只要將字符串轉number,首選parseFloat(),Number()太局限
? ? ? ? ? 如果確實需要去掉小數,才選parseInt
? ? ? ? ? 如果轉不了,也返回NaN
強調: 參數應該是string類型,如果給定的值不是string類型,則先執行隱式轉換,轉為string類型,再轉number
? ? ? Number/parseFloat/parseInt 都會自動去掉空格
特殊:
parseFloat("true") ?->NaN
Number(true) ?->1
Number("") ?->0
Number(null) ->0
Number(undefined) ->NaN
其他類型轉string: 2種:
1.var str=x.toString() ?將 x 轉為字符串類型,并返回結果。x為數組時,用,分隔
? ? x不能是null或undefined ———?不是萬能
2.var str=String(x)?將x轉為字符串類型——萬能(首選)
? ? 其實,隱式轉為string時,都是程序自動調用String
其他類型轉Boolean類型: 1種
Boolean(x)
? ? 規則: 只有5個值會被轉為false:0? ""? NaN? null? undefined
? ? ? ? ? 其余都轉為true
? ? 其實, 隱式轉為bool時,都是程序自動調用Boolean(x)
_______________________________________________________________________________________________
運算符和表達式
程序: 人的想法在計算機中的執行
運算符: 程序中模擬人的想法的特殊符號
表達式: 由數據,變量和運算符組成的完成一項單一任務的語句
算數運算: + , - , * , / , %
%: 模運算/取余數: 被除數/除數,不要商,要除不盡的余數部分(取零頭)
? 何時: 1. 取余數,可限制一個結果不超過指定的最大值
? ? ? ? 2. 判斷能否整除
? ? ? ? ?? 判斷偶數: 能被2整除 n%2==0
? ? ? ? ?? 判斷奇數: 不能被2整除 n%2!=0
隱式轉換
默認:都轉number
特殊:+運算中,碰到字符串,都轉字符串,+運算變為字符串拼接(在外面套一個parseFloat)
? ? ?字符串左邊的變量會先進行計算,遇到字符串全部轉為字符串(按優先級,從左到右)
? ? ?true在計算中為1,false為0;在字符串中為true/false
舍入誤差: 計算機中,也有計算不盡的數值(如0.3-0.1, 0.1*3),一般是浮點型
解決:
1. 按指定位數四舍五入: n.toFixed(2)
?? 今后幾乎所有顯示金錢數的地方都要toFixed(2)
2. 存儲: 保存很長位數的小數: 0.39999999
關系運算: 用兩個值做比較,做判斷(若試圖比較未定義的變量,會報錯)
包括:>? <? >=? <=? ==? !=
返回值: bool 類型的true/fasle
隱式轉換:默認都轉為 number
特殊:1. 兩個值都是字符串, 則不再轉數字,而是依次比較兩個字符串的每個字符unicode號
? ? ? ? 一個是字符串,一個是number,會進行隱式轉換
? ?? 2. 判斷NaN:NaN和任何值做> < >= <= ==5種比較時,永遠false
? ? ? ? ? ? ? ? ?NaN和任何值做!=比較時,永遠是true
? ? ?? 問題:NaN==NaN ?=>false 用普通的==無法判斷NaN
? ? ?? 解決:isNaN(num) 專門代替==,用來判斷num是不是NaN
? ? ?? 何時: 只要判斷是不是NaN,都用isNaN(num)函數
? ? ?? 反用: 判斷一個值是不是數字:!isNaN(num),若是數字,則返回true
? ? ? ?注意:?空字符串、純數字的字符串返回false(不是NaN)
? ?? 3. 區分null和undefined
?????? 問題:==比較時,會自動將undefined隱式轉為null
? ? ? ? ? ?? null==undefined ? ?=> null=null
?????? 解決:=== 全等: 類型必須先相同,值再相等(!==,不全等同理)
? ? ? ? ? ? ?其實===就是不帶隱式轉換的==
總結:
= 賦值,只有=可以改變變量中的值
== 自帶隱式轉換作比較
=== 不帶隱式轉換作比較
注意: 兩個對象作比較,不做任何轉換,直接比較兩個對象的地址值(判斷兩個變量是否引用同一個對象)
邏輯運算: 將多個關系運算,綜合起來得到最終結論
何時: 只要根據多個條件,綜合得出最終結論時
包括:&&與(而且) ? ||或(要么) ? !非(沒有)
條件1&&條件2...:
? ? 要求所有條件都為true,結果為true
? ? 只要一個條件為false,結果為false
條件1||條件2...:
? ? 只要一個條件為true,結果為true
? ? 除非所有條件都為false,結果才為false
!條件: 顛倒 條件的 判斷結果
隱式轉換: 默認將每個條件都轉為bool類型
短路邏輯: 如果前一個條件已經可以得出最終結論,則后續條件不再執行
???? &&: 只有前一個條件為false時,后續條件才不執行
???? ||: 只要前一個條件為true時,后續條件不再執行
利用短路:①簡單分支結構: 1個條件,1件事,只有滿足才做
? ? ? ? ? ? 如何: 條件&&(操作) ? (最簡單的條件判斷語句,注意加())
? ? ? ? ? ②利用||選擇默認值,如果給定的值有效,則使用給定的值,否則使用默認值代替
? ? ? ? ? ? 如何:給定值||默認值
? ? ? ? ? ? 無效:只要給定的值為0 "" NaN null undefined
注意:如果邏輯運算最后執行的是一個關系運算,則返回bool
? ??如果邏輯運算最后執行的是一個值,則返回值,而不返回bool
_______________________________________________________________________________________________
位運算: 了解
用二進制簡化普通十進制的計算或操作
1. 左移/右移:
m<<n ?m左移n位,相當于m*2的n次方
m>>n ?m右移n位,相當于m/2的n次方
? ? 1<<3=1*23=8
? ? 2<<3=2*23=16
? ? 8>>3=8/23=1
2. 取整:
? ? n^0?? n|0?? n>>>0 ? ? ? ? 代替/簡化Math.floor(n),用來把n向下取整(^ 按位異或)
3. 交換兩變量的值:
? ? var a=3,b=5;
? ?? 方法一: var t=b; b=a; a=t;
? ?? 方法二:a+=b; b=a-b; a-=b;
? ?? 方法三:a^=b; b^=a; a^=b;(二、三只能交換number類型的數據)
? ? ?方法四:?a=a+b; b=a-b; a=a-b;
賦值運算:
?????擴展賦值運算: 對特殊賦值運算的簡化
? ? ?何時:只要取出變量中的值,計算后,再存回原變量中
? ? ?a=a+b 將a的值+b的值,再存回a中
?????將b的值累加到a上:可簡寫為a+=b
? ? a=a+b ?-> ?a+=b;
??? a=a-b ?-> ?a-=b;
??? a=a*b ?-> ?a*=b;
??? a=a/b ?-> ?a/=b;
??? a=a%b ?-> ?a%=b;
? 更簡化: 遞增遞減運算: 如果每次累加1/累減1
??? a+=1? ->? a++
??? a-=1? ->? a--
前++和后++
1. 如果單獨使用, 前后都一樣
2. 如果參與到其他表達式中時:
?? 相同:變量中的值一定都會變化,+1
?? 不同: 前++,使用返回+1后的 新值去運算
? ? ? ? ?后++,使用返回+1前的 舊值去運算
注意:所有表達式都從左到右依次執行;先執行的操作會影響后續操作
函數中: return i++; ? ?返回+1前的 舊值去運算
注意: ++a并不總和a=a+1完全一樣,++運算符不會進行字符串連接操作,它會先將操作數轉換為數字并增1
比如: var a="1"; ? ?++a為2, ?a+1為字符串"11"
第三章*****************************************************************************************
一、函數類型
定義: 內存中封裝一項任務步驟清單的代碼段,再起一個名字
為什么:代碼重用、劃分功能
何時: 只要一段代碼,可能被反復使用,就都要先封裝在函數中,再反復調用函數
如何: 分2步
1、聲明(兩種方法)
①function函數名(參數變量列表){ ? ? /*形參*/ /*function創建函數*/
? ? ?函數體(代碼段);
? ? ?return 返回值; ? ? ? ? ? ? ? ? /*返回值要接住,再輸出才能顯示*/
? ?}
② 函數名=function(參數變量列表){
? ? ?函數體(代碼段);
? ? ?return 返回值;
? ?}
參數: 函數運行時,接收傳入函數的數據的變量。參數用法和普通變量完全一樣,只不過不用var聲明
參數列表: 多個參數間用逗號分隔(參數變量1,參數變量2...)
? 何時:若一項任務必須某些數據才能正常執行時,就必須定義參數
? 作用:①提醒調用者正確使用函數;②讓函數變得更靈活
? 返回值: 函數執行的結果(由是否需要返回結果決定是否返回值)
? ? ? ?何時: 如果函數的調用者需要獲得函數執行結果
? ? ? ?如何返回: return 返回值;
? ? ? ?作用:①return可單獨使用: 退出函數;②退出函數時,順便返回結果
? ? ? ?如果沒有返回值的函數,就會默認返回undefined
2、調用: 讓引擎按照函數的步驟清單,執行任務
var 返回值=函數名(參數值列表);
或 ?函數名(參數值列表); ? ? ? ? ? ? ? ? ? /*實參*/
何時: 函數只有調用才執行,不調用不執行
參數值列表: 傳入函數的執行時必須的數據列表
? 只要函數定義時規定了參數變量,調用時都要傳入參數值,且順序和個數保持一致
? 每個參數值之間用逗號分隔
_______________________________________________________________________________________________
作用域scope: 一個變量的可用范圍
為什么:避免不同范圍的變量之間互相污染(注意執行順序)
包括: 2種:
1.全局作用域: window(保存著全局變量)
什么是: 程序中的任何位置都可以訪問的范圍
? ? ?全局變量: 保存在全局作用域中,程序任何位置都可使用的變量
? ? ? 特點:隨處可用,可反復使用
? ? ? 何時: 如果一個變量需要反復使用,或跨函數隨處可用時,只要不屬于任何函數的變量,都是全局的
? ? ? 用法:console.log(變量名);
2.函數作用域:(保存著局部變量)
什么是: 僅函數內可用的范圍
? ? ?局部變量: 保存在函數作用域中,僅函數內可用的變量
? ? ? 特點:僅在函數內可用,不可重用
? ? ? 何時: 如果只限于當前函數內使用,函數外不可用時
? ? ? 如何:1.函數的參數變量
? ? ? ? ? ? 2.在函數內用 var 聲明的變量
總結: 優先定義并使用局部變量
? ? ? 盡量少使用全局變量——避免被污染
變量的使用順序:優先使用函數內的局部變量,局部沒有才去全局找
聲明提前(hoist,提起):
什么是: 在開始執行程序前,引擎會將var聲明的變量和function聲明的函數,提前到"當前作用域"頂部集中優先創建,再開始執行程序 ? ? ? ? ?? /*但是賦值留在原地?*/
筆試: 如果先使用,后聲明,一定在考聲明提前,就要將所有var和function提前到當前作用域的頂部,先創建,再判斷程序的輸出
問題: 破壞了程序默認的執行順序
解決: ①傳統: 強烈建議將所有的聲明都集中在當前作用域頂部
? ? ? ②ES6: let代替var聲明變量
? ? ? ? ? ? ? let禁止在聲明之前,提前使用該變量,強制將聲明集中在當前作用域頂部創建
? ? ? ? ? ? ? 限制:不能用let反復創建相同名稱的變量
函數聲明:
?var/let 函數名=function(參數變量列表){...}?? /*用這種方式創建的函數不會被聲明提前*/
? 本質: 函數名其實僅是一個普通的變量
? ? ? ? 函數其實是保存代碼段的引用類型的對象
? ? ? ? 函數名通過函數對象的地址引用著函數對象
按值傳遞:
什么是:兩變量間賦值,或將變量傳入函數作為參數時,其實只是將原變量中的值復制一個副本給對方
結果:原始類型的值會 修改新變量,不影響原變量的值
_______________________________________________________________________________________________
2. 全局函數(了解)
什么是: ES標準中規定的,瀏覽器已經實現的,不需要任何對象(前綴.)就可直接調用的函數
比如: String()/Number()/Boolean()
? ? ? parseInt/parseFloat()
? ? ? isNaN()/encodeURI/decodeURI
反例(省略了前綴,屬于BOM): alert()/prompt()...
編碼解碼: 特指對地址欄中的url內容進行編碼和解碼
什么是編碼: 將url中多字節字符或保留字符編碼為單字節字符
? 為什么: url中不允許出現多字節字符以及和保留字符沖突的字符,否則會亂碼
? 何時: 只要url中可能包含多字節字符以及和保留字沖突的字符時,都要先編碼為單字節
什么是解碼:將編碼后的單字節字符串解碼回多字節原文
何時:只要收到的是編碼后的字符串,都要先解碼再使用
如何:編碼: var code=encodeURI(url);
? ? ?解碼: var url=decodeURI(code);
問題: 不能對保留字符編碼解碼,比如: ?: ?/
解決:編碼: var code=encodeURIComponent(url);
? ? ?解碼: var url=decodeURIComponent(code);
注意: 不會對ASCII字母和數字進行編碼,也不會對ASCII標點符號進行編碼:? - _ . ! ~ * ' ( ) 。
其他字符(比如: ;/?:@&=+$,# 這些用于分隔URI組件的標點符號),都是由一個或多個十六進制的轉義序列替換的
eval函數: 執行一段字符串格式的js表達式
eval()的作用
把字符串參數解析成js代碼并運行,并返回執行的結果
eval的作用域:
作用域在它所有的范圍內有效,但是IE8及以下指向window(全局)
解決方法:
functiona(){
? if(window.execScript){ ? ? ?? // 支持IE8及以下的版本
? ? window.execScript("var x=1");
? }else{?window.eval("var x=1"); }? ? ? ?//常用的瀏覽器都支持
? ? console.log(x);
? }
? a();
? console.log(x);
execScript與eval區別:
相同點:
execScript與eval都可以接收一個字符串,若該字符串是表達式(expression),則執行時將求得該表達式的值并返回;若該字符串是一個或多個語句(statements),則執行時將運行這些語句
不同點:
① execScript是IE瀏覽器獨有;eval則是所有瀏覽器都支持
② execScript無論是在什么作用域(global/local)內被調用,它所接受到的表達式(expression)或語句(statements)字符串都將在全局作用域內執行(global);eval則是在它被調用時所在的作用域內運行它所接受到的表達式(expression)或語句(statements)字符串
在不支持execScript函數的瀏覽器下實現在全局作用內執行字符串
function globalEval(data){
? if(data){
? ?(window.execScript || function(data){?window["eval"].call(window, data);?})(data);
? }
}
_______________________________________________________________________________________________
程序三大結構: 順序(判斷,不循環),分支和循環
1、分支結構
什么是: 讓程序根據不同的條件執行不同的操作
何時: 只要讓程序根據不同的條件執行不同的操作
如何:
1. 一個條件,一件事,滿足就執行,不滿足就不執行
? 如果操作簡單: 短路:條件&&(操作1,操作2,操作3...)
? 如果操作復雜:?
if(條件){
? 操作1;
? 操作2;
? ...
}
2. 一個條件,二件事,二選一執行:
? 如果僅兩個值二選一:
條件?值1:值2
? 如果操作簡單: 三目運算/三元運算/條件運算(三目運算符的優先級低于+)
條件?操作1:操作2 ? ? ? ? ?/*滿足條件執行并返回操作1的值,不滿足則執行并返回操作2的值*/
? 如果操作復雜:
if(條件){
? 操作1; ? ? ? ? ? ? ? ? ? ? ? /*滿足條件執行*/
}else{
? 操作2; ? ? ? ? ? ? ? ? ? ? ?/*不滿足條件執行*/
}
3. 多個條件,多件事,多選一執行(嵌套)
如果多個值,多選一: 三目運算(一般對齊)
? ? 條件1?值1:
? ? 條件2?值2:
? ? ? ...?... :
? ? 默認值 ? ? ? ? ? ? ? ? ? ? ? ? ? /*強調: 默認值不能省略*/
如果操作簡單: 三目運算
? ? 條件1?操作1:
? ? 條件2?操作2:
? ? ? ...?... :
? ? 默認操作? ? ? ? ? ? ? ? ? ? ?? /*強調:默認操作不能省略*/
如果操作復雜:if...else if結構
if(條件1){
? ? 操作1 ? ? ? ? ? ? ? ? ? ?? /*如果當前條件滿足,則不再向后執行*/
}else if(條件2){ ? ? ? ? ? ? ? ?/*如果進入條件2,暗示條件1不滿足*/
? ? 操作2
}else if(...){
? ? ...
}else{ ? ? ? ? ? ? ? ? ? ? /*如果沒有默認操作,則else可省略,即什么也不做*/
? ? 默認操作
}
簡寫:如果if(...)一句話 ? ?else(...)一句話 ? ?后面只有一句話,可省略{}(if、else仍然要寫)
特殊: 如果所有條件都是等于比較,可簡寫為
switch(表達式){ ? ? ? ? /*先計算表達式的值,用表達式的值和每個case后的值做"全等==="比較*/
? case 值1: ? ? ? ? ? ? /*如果表達式的值全等于case后的值1*/
? 操作1; ? ? ? ? ? ? ? /*就執行操作1*/
? case 值2:
? 操作2;
? ...
? default: ? ? ? ? ? ? ?/*如果所有case的值都不等于表達式的值*/
? 默認操作; ? ? ? ? ?? /*則執行默認操作*/
} ? ? ? ? ? ? ? ? ? ? ? /*強調: 最后一個default可省略*/
問題: 只要前一個case滿足條件,則后續所有case都被執行(而不會再判斷)
原因: switch是入口
解決: break;可終止當前結構繼續向后執行,并退出switch
如何:每個case之間,都要加break;
判斷一個值是否為空可以直接用if(值){ },不加等號,判斷是否為true
第四章*****************************************************************************************
2、循環loop
什么是: 讓程序反復執行相同的代碼段
何時: 只要讓程序反復執行同一段代碼
如何: 三要素:
? 1. 循環條件: 讓循環可以繼續執行的條件(只要條件滿足就反復執行循環,直到不滿足時退出循環)
? 2. 循環變量: 在循環條件中用作比較和判斷的變量
????? 從幾開始, 每次遞增/遞減幾,到幾結束
? 3. 循環體: 循環要反復執行的代碼段
????? 幾乎都要修改循環變量,直到不滿足條件;若循環條件始終為true,則循環永遠無法退出---死循環
包括: 3種:
while:
var 循環變量=初始值; ? ? ? ? ? ? /*聲明并初始化循環變量*/
while(循環條件){ ? ? ? ? ? ? ? ? ?/*當滿足循環條件時*/
? 循環體;
? 修改循環變量;
}
? 何時: 必須先滿足循環條件,才能執行循環體時
do...while:
var 循環變量=初始值;
do{
? 循環體;
? 修改循環變量;
}while(循環條件); ? ? ? ? ? ? ? ?/*當滿足循環條件時*/
? 何時: 即使條件不滿足,也至少可以執行一次時(先執行,再判斷)
while VS do...while
如果第一次循環都滿足,兩者的輸出是完全一樣的
? while: 先驗證條件后執行
? do...while: 先執行一次,再驗證條件
如果第一次條件不滿足,則while是一次都不執行,do while至少執行一次
for:
for(var 循環變量=初始值;循環條件;修改循環變量){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? //循環條件中有,時(逗號表達式),以最后一個為準
? 循環體; ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*先執行循環體,再修改循環變量*/
}
for循環和while循環的原理是完全一樣的(就是while循環的簡化)
for vs while: 如果循環變量的變化有規律: 首先for
? ? ? ? ? ? ? 如果循環變量的變化沒有規律: 首先while
強調:JavaScript中沒有塊級作用域
放在if/else if/else/for/while中的變量,出了塊(結構),依然可用
c、c++、java等所有{}都認為是塊級作用域,塊中的變量出了塊,不能使用
解決: 讓循環中的變量不要泄露到循環外
? ? ? 用let代替var: let聲明的變量僅能在{}內使用
簡寫:var 可同時聲明并初始化多個變量,用,分隔
? ? ? 如果for循環下只有一句語句,可省略{}—————不建議,容易出歧義
? ? ? 如果for循環體中只有一句話,且很簡單時,for循環的修改循環變量中可先后執行多個短小的操作,每個操作之間用逗號(,)分隔,省略循環體并加分號(;)結束——但不能改變原來的執行順序
_______________________________________________________________________________________________
break(中斷)?VS?continue(跳過):
break: 中斷并退出當前循環
?? 何時: 當判斷條件非常復雜時,就可用死循環+break的方式靈活控制循環退出——降低循環編寫的難度
continue: 跳過本輪循環,繼續執行下一輪
?? 只要顛倒判斷條件,就可避免使用continue
強調:break不能參與到任何簡寫中,必須獨立一句
嵌套循環: 循環內,又執行了另一個循環
步驟: 1. 截取片段找規律
? ? ? 2. 用外層循環反復調用規律的公式
_______________________________________________________________________________________________
二、數組類型
什么是: 內存中連續存儲多個數據的一塊存儲空間,再起一個名字
為什么: 便于維護和查找
? ? 程序=數據結構+算法
??? 數據結構: 數據在內存中的存儲結構
??? 算法: 解決問題的步驟
??? 好的數據結構可極大提高程序的執行效率
何時: 今后只要保存多個同一類型的數據時,都必須用數組
如何: 3件事(創建、賦值、取值)
創建: 3種:
1.創建空數組2種:
?? 何時: 創建數組時,暫時不知道數組內容
? ? ? ? var arr=[]; ? ? ? ? ? ? ? ? /*[]創建數組*/
? ? ? ?var arr=new Array();
2. 創建數組同時初始化數組內容:
?? 何時: 創建數組時已知數組的內容
???????var arr=[值1,值2,...];
? ? ? ?var arr=new Array(值1,值2,...);
3. 創建n個空元素的數組(只有一種):
?? 何時: 創建數組時,只知道數組元素個數,暫時不知道數據的內容
? ? ?? var arr=new Array(n);?? //()里若只有一個數字,創建空數組,否則設置其為數組的內容
訪問:
? 元素:數據中每個數據,都稱為元素
? 下標(index): 每個元素的存儲位置的序號。默認都是數字,從0開始,連續不重復
賦值: 將數據保存到數組的某個元素中
? ? ?arr[i]=新值; ? ? ? ? ? ? ? ?/*i:下標index*/
取值: 數組中每個元素的用法和普通的變量完全一樣
? ? ? 數組也稱為一組變量的集合,起一個統一的變量名
? ? ?arr[i]
console.log(arr[i]); ? ? ? /*輸出數組下標為i的元素*/
console.dir(arr); ? ? ? ? /*查看內存中arr的結構和內容*/
dir問題:不會立刻輸出結果
? 只有手動點擊三角時,才動態查找內存中對象的最終結構,會打亂程序的輸出結果順序
解決: 如果想查看數組中間狀態的內容:
console.log(String(arr)); ? ? ? ? /*對數組拍照*/
js的數組三個不限制:
? 1. 不限制元素的數據類型
? 2. 不限制下標越界:
? ?? 賦值時越界: 不會報錯!在指定的新位置自動創建新元素保存新值(添加后,數組的元素下標不連續則稱為稀疏數組)
? ?? 取值時越界: 不會報錯! 僅返回undefined
? 3. 不限制元素個數:?在任何時候,在任何位置添加新元素
.length屬性: 記錄數組中理論上的元素個數(不一定和實際元素個數相符)
特點:.length 永遠等于最后一個數字下標+1(自動維護,不需要手動修改)
? ? ? .length 永遠指向最后一個元素的下一個新位置
.length可修改數組大小——縮容(如使arr.length=5,可獲取數組的前5個值)
用法注意:arr.length ? ? ? ? ? ? ? ? ?/*.length屬性屬于數組,不能脫離數組單獨使用*/
固定套路: 1. 獲取數組最后一個元素:arr[arr.length-1]
? ? ? ? ? 2. 獲得倒數第n個元素:arr[arr.length-n]
? ? ? ? ? 3. 末尾追加一個新元素:arr[arr.length]=新元素
? ? ? ? ? 4. 刪除數組最后一個元素(改小length) :arr.length-=1;
? ? ? ? ? 5. 刪除數組末尾倒數n個元素(改小length):arr.length-=n;
_______________________________________________________________________________________________
數組是引用類型的對象
原始類型的值: 修改新變量,不影響原變量—————按值傳遞
原始類型:基本數據類型:值直接保存在變量本地的數據類型,Number/String/Boolean/Undefined/null
? ? 原因:將原變量中的實際值復制一個副本給對方
引用類型的對象: 用新變量修改對象,等效于直接修改原對象。新舊變量都受影響(arr2=arr1)
引用類型:值無法直接保存在變量本地的復雜數據類型
? ? 原因:僅將原變量中的地址值復制給新變量,導致兩個對象共用同一個對象
? ? ? ? ? 新舊變量使用相同的地址值,引用同一個對象(地址值相同)
遍歷:
什么是: 依次對數組中每個元素執行相同的操作
何時: 只要對數組中每個元素執行相同的操作時
如何:循環
for(var i=0;i<arr.length;i++){
? ? arr[i]? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*當前元素*/
}
var i=0,len=arr.length; i<len; i++? ? ?//可使用緩存代替arr.length,減少延遲,提高性能