前端之JavaScript
前端之JavaScript
一、瞭解知識
1996年11月,JavaScript的創造者--Netscape公司,決定將JavaScript提交給國際標準化組織ECMA,希望這門語言能夠成為國際標準。次年,ECMA釋出262號標準檔案(ECMA-262)的第一版,規定了瀏覽器指令碼語言的標準,並將這種語言稱為ECMAScript,這個版本就是1.0版。
該標準一開始就是針對JavaScript語言制定的,但是沒有稱其為JavaScript,有兩個方面的原因。一是商標,JavaScript本身已被Netscape註冊為商標。而是想體現這門語言的制定者是ECMA,而不是Netscape,這樣有利於保證這門語言的開發性和中立性。
因此ECMAScript和JavaScript的關係是,前者是後者的規格,後者是前者的一種實現。
ECMAScript的歷史
年份 | 名稱 | 描述 |
---|---|---|
1997 | ECMAScript 1 | 第一個版本 |
1998 | ECMAScript 2 | 版本變更 |
1999 | ECMAScript 3 | 新增正則表示式新增try/catch |
ECMAScript 4 | 沒有釋出 | |
2009 | ECMAScript 5 | 新增"strict mode"嚴格模式新增JSON支援 |
2011 | ECMAScript 5.1 | 版本變更 |
2015 | ECMAScript 6 | 新增類和模組 |
2016 | ECMAScript 7 | 增加指數運算子(**)增加Array.prototype.includes |
ps: ES6就是指ECMAScript 6。
1.js也是一門程式語言 它也是可以寫後端程式碼的,nodejs 支援js程式碼跑在後端伺服器上,但是其存在一定的不足,並不能真正“一統天下”。
2、2.js跟java沒有任何關係,純粹是為了蹭當時java的熱度。
3、ECMAScript和JavaScript的關係是,前者是後者的規格,後者是前者的一種實現。
- JavaScript 是指令碼語言
- JavaScript 是一種輕量級的程式語言。
- JavaScript 是可插入 HTML 頁面的程式設計程式碼。
- JavaScript 插入 HTML 頁面後,可由所有的現代瀏覽器執行。
- JavaScript 很容易學習
二、js註釋及js引入方式
註釋是程式碼之母。
"""註釋方式和C語言相同"""
// 單行註釋
/*
多行註釋1
多行註釋2
多行註釋3
*/
引入方式:
- script標籤內部直接書寫js程式碼
<script>
// 在這裡寫你的JS程式碼
</script>
- script標籤src屬性引入外部js程式碼
<script src="myscript.js"></script>
js是以分號作為語句的結束【 但是如果你不寫分號,問題也不大 也能夠正常執行 但是它就相當於沒有結束符】(比較奇葩)
三、學習流程
- 變數
- 資料型別
- 流程控制
- 函式
- 物件
- 內建方法/模組
變數
1、JavaScript的變數名可以使用_,數字,字母,$組成,但不能以數字開頭。
2、js推薦駝峰式命名方式,而python中則推薦使用字母加下劃線的方式。
2、宣告變數可以使用var、let,【js是一門弱型別的程式語言】
"""
在js中 首次定義一個變數名的時候需要用關鍵字宣告
1.關鍵字var
var name='jason'
2.es6推出的新語法
let name='jason'
如果你的編輯器支援的版本是5.1那麼無法使用let
如果是6.0則向下相容 var let
"""
var在for迴圈裡面定義也會影響到全域性
let在區域性定義只會在區域性生效
但是,在最新的語法中,let 和 var的區別已經被取消。
常量
js中是有真正意義上的常量的,而python中沒有真正意義上的常量 預設全大寫就是表示常量,是一種約定俗稱的寫法。
const pi = 3.14 # 常量的定義,修改就會報錯
PI = 3 # 報錯
// TypeError: "PI" is read-only
js中的保留字
abstract
boolean
byte
char
class
const
debugger
double
enum
export
extends
final
float
goto
implements
import
int
interface
long
native
package
private
protected
public
short
static
super
synchronized
throws
transient
volatile
資料型別
js 和 python也是一門面向物件 的程式語言 即一切皆物件!!!
js和python是一門擁有動態型別。
name = 'jason'
name = 123
name = [1,2,3,4]
# name可以指向任意的資料型別
# 但是有一些語言中,變數名之內指向一種後續不能更改,如C/C++。
數值型別(number)
JavaScript不區分整型和浮點型,就只有一種數字型別。
有一種NaN,表示不是一個數字(Not a Number)。
var a = 11;
var b = 11.11;
// 如何檢視當前資料型別
typeof a;
var a = 11;
var b = 11.11;
typeof a;
typeof b;
"number"
// 特殊的 NaN:數值型別 表示的意思是“不是一個數字” NOT A NUMBER
// 型別轉換
parseInt() # 轉化成整形
parseFloat() # 轉化成浮點型
parseInt('12312312')
12312312
parseFloat('11.11')
11.11
parseInt('11.11')
11
parseInt('123sdasdajs2312dasd')
123
parseInt('asdasdad123sdasdajs2312dasd')
NaN
字元型別(string)
方法 | 說明 | python中對應方法 |
---|---|---|
.length | 返回長度 | len() |
.trim() | 移除空白 | .strip() |
.trimLeft() | 移除左邊的空白 | .lstrip() |
.trimRight() | 移除右邊的空白 | .rstrip() |
.charAt(n) | 返回第n個字元 | .find() |
.concat(value, ...) | 拼接 | join() |
.indexOf(substring, start) | 子序列位置 | .index() |
.substring(from, to) | 根據索引獲取子序列 | []索引取值 |
.slice(start, end) | 切片 | [ : : ] |
.toLowerCase() | 小寫 | .lower() |
.toUpperCase() | 大寫 | .upper() |
.split(delimiter, limit) | 分割 | .splite() |
var s = 'yangyi';
typeof s; // typeof是一個一元運算子(就像++,--,!,- 等一元運算子),不是一個函式,也不是一個語句。
"string"
var s2 = '''yangyi''' // js不支援三引號
VM665:1 Uncaught SyntaxError: Unexpected string
// js提供了模版字串,類似於python中的""""""
var s3 = `
asdkajsd
sdjkladj
asdjlajdkl
`
typeof s3
"string"
// 模版字串除了可以定義多行文字之外還可以實現格式化字串操作
// 書寫${} 會自動去前面找大括號裡面的變數名對應的值 如果沒有定義直接報錯
// 字串的拼接
// 在python中不推薦你使用+做拼接,python中推薦只用join方法進行拼接。
// 在js中推薦你直接使用+做拼接。
name + age; // 字串和數值型別也可以進行拼接,其內部會自動進行型別轉換【比python還要人性化,哈哈哈】
'yangyi18'
string常用方法演示
.length 返回長度
.trim() 移除空白
.trimLeft() 移除左邊的空白
.trimRight() 移除右邊的空白
.charAt(n) 返回第n個字元
// MySql中 存在 concat、concat_ws、group_concat、python中有 .join()
.concat(value, ...) 拼接
.indexOf(substring, start) 子序列位置
.substring(from, to) 根據索引獲取子序列
.slice(start, end) 切片
.toLowerCase() 小寫
.toUpperCase() 大寫
.split(delimiter, limit) 分割
var name = 'yangyi'
undefined
name.length
6
var name1 = ' yangyi '
undefined
name1
" yangyi "
name1.trim()
"yangyi"
name1.trimLeft()
"yangyi "
name1.trimRight()
" yangyi"
var name2 = '$$yangyi$$'
undefined
name2.trim('$') // 不能加括號指定去除的內容【而python中的strip()可以去除特殊字元】
"$$yangyi$$"
name2.charAt(0)
"$"
name2.indexOf('yi')
6
name2.substring(0,5)
"$$yan"
name2.slice(0,5)
"$$yan"
name2.substring(0,-1) // 不識別負數
""
name2.slice(0,-1) // 後面推薦就使用slice就可以
"$$yangyi$"
var name3 = 'eGoNDsb123666HahA'
undefined
name3.toLowerCase()
"egondsb123666haha"
name3.toUpperCase()
"EGONDSB123666HAHA"
var name = 'yangyi|anan|leichao|yangxin|...'
undefined
name.split('|') // 和python一樣的用法
(5) ["yangyi", "anan", "leichao", "yangxin", "..."]
name.split('|',2)
(2) ["yangyi", "anan"]0: "leichao"1: "hecha"length: 2__proto__: Array(0)
name.split('|',10) // 第二個引數不是限制切割字元的個數還是獲取切割之後元素的個數
(5) ["yangyi", "anan", "leichao", "yangxin", "..."]
name.concat(name1,name2) // 直接進行拼接
var p = 1111
undefined
name.concat(p) // js是弱型別(內部會自動轉換成相同的資料型別做操作)
l = [1,2,3,4,5,6,7]
res = '|'.join(l) // 直接報錯【這是python的寫法】
print(res)
布林值(boolean)
"""
1.在python中布林值是首字母大寫的
True
False
2.但是在js中布林值是全小寫的
true
false
# 布林值是false的有哪些
空字串、0、null、undefined、NaN
"""
null與undefined
"""
null
表示值為空 一般都是指定或者清空一個變數時使用
name = 'yangyi'
name = null
undefined
表示聲明瞭一個變數 但是沒有做初始化操作(沒有給值)
函式沒有指定返回值的時候 返回的也是undefined
"""
物件(Object)
JavaScript 中的所有事物都是物件:字串、數值、陣列、函式...此外,JavaScript 允許自定義物件。
JavaScript 提供多個內建物件,比如 String、Date、Array 等等。
物件只是帶有屬性和方法的特殊資料型別。
陣列
陣列物件的作用是:使用單獨的變數名來儲存一系列的值。類似於Python中的列表 [ ]。
陣列的常用方法
方法 | 說明 |
---|---|
.length | 陣列的大小 |
.push(ele) | 尾部追加元素 |
.pop() | 獲取尾部的元素 |
.unshift(ele) | 頭部插入元素 |
.shift() | 頭部移除元素 |
.slice(start, end) | 切片 |
.reverse() | 反轉 |
.join(seq) | 將陣列元素連線成字串 |
.concat(val, ...) | 連線陣列 |
.sort() | 排序 |
.forEach() | 將陣列的每個元素傳遞給回撥函式 |
.splice() | 刪除元素,並向陣列新增新元素。 |
.map() | 返回一個數組元素呼叫函式處理後的值的新陣列 |
// 常用方法使用
var l = [11,22,33,44,55]
typeof l
"object" // 屬於物件【此處重視】
l1[1]
"sdasd"
l1[-1] // 不支援負數索引
var l = [111,222,333,444,555,666]
l.length
6
l.push(777)
7
l
(7) [111, 222, 333, 444, 555, 666, 777] // 陣列型別的呈現方式
l.pop()
777
l
(6) [111, 222, 333, 444, 555, 666]
l.unshift(123)
7
l
(7) [123, 111, 222, 333, 444, 555, 666]
l.shift()
123
l
(6) [111, 222, 333, 444, 555, 666]
l.slice(0,3) // 不修改原陣列,和python相同
(3) [111, 222, 333]
l.reverse()
(6) [666, 555, 444, 333, 222, 111]
l.join('$') // 跟python剛好相反
"666$555$444$333$222$111"
l.concat([111,222,333]) // 類似於python中的extend
(9) [666, 555, 444, 333, 222, 111, 111, 222, 333]
l.sort() // python中也有sort
(6) [111, 222, 333, 444, 555, 666]
三個重要方法
-
forEach()
# 三個比較重要的方法
var ll = [111,222,333,444,555,666]
ll.forEach(function(value){console.log(value)},ll)
111 # 一個引數就是數組裡面每一個元素物件
222
333
444
555
666
ll.forEach(function(value,index){console.log(value,index)},ll)
111 0 # 兩個引數就是元素 + 元素索引
222 1
333 2
444 3
555 4
666 5
ll.forEach(function(value,index,arr){console.log(value,index,arr)},ll) # 元素 + 元素索引 + 元素的資料來源
111 0 (6)[111, 222, 333, 444, 555, 666]
222 1 (6)[111, 222, 333, 444, 555, 666]
333 2 (6)[111, 222, 333, 444, 555, 666]
444 3 (6)[111, 222, 333, 444, 555, 666]
555 4 (6)[111, 222, 333, 444, 555, 666]
666 5 (6)[111, 222, 333, 444, 555, 666]
ll.forEach(function(value,index,arr,xxx){console.log(value,index,arr,xxx)},ll) # 最多三個
111 0 (6)[111, 222, 333, 444, 555, 666] undefined
222 1 (6)[111, 222, 333, 444, 555, 666] undefined
333 2 (6)[111, 222, 333, 444, 555, 666] undefined
444 3 (6)[111, 222, 333, 444, 555, 666] undefined
555 4 (6)[111, 222, 333, 444, 555, 666] undefined
666 5 (6)[111, 222, 333, 444, 555, 666] undefined
-
splice()
ll
(6)[111, 222, 333, 444, 555, 666]
ll.splice(0,3) # 兩個引數 第一個是起始位置 第二個是刪除的個數
(3)[111, 222, 333]
ll
(3)[444, 555, 666]
ll.splice(0,1,777) # 先刪除後新增【會修改原陣列】
[444]
ll
(3)[777, 555, 666]
ll.splice(0,1,[111,222,333,444])
[777]
ll
(3)[Array(4), 555, 666]
-
map()
var l1 = [11,22,33,44,55,66]
undefined
l1.map(function(value){console.log(value)},l1)
11
22
33
44
55
66
l1.map(function(value,index){return value*2},l1)
(6)[22, 44, 66, 88, 110, 132]
l1.map(function(value,index,arr){return value*2},l1)
(6)[22, 44, 66, 88, 110, 132]
運算子
- 算數運算子
# 和 C語言 相同
var x = 10;
var res1 = x++;
var res2 = ++x;
res1 10
res2 12
++表示自增1 類似於 +=1
加號在前先加後賦值 加號在後先賦值後加
- 比較運算子
# 比較運算子
1 == '1' # 弱等於 內部自動轉換成相同的資料型別比較了
true
1 === '1' # 強等於 內部不做型別轉換
1 != '1'
false
1 !== '2'
true
-
邏輯運算子
python中的是 not and or
# python中 and or not
# js中 && || !
5 && '5'
'5'
0 || 1
1
!5 && '5'
false
"""
一定要注意到底什麼時候返回的是布林值 什麼是返回的是資料
按照後端邏輯理解吧
"""
- 賦值運算子
= += -= *= ....
流程控制
- if - else
# if判斷
var age = 28;
# if(條件){條件成立之後指向的程式碼塊}
if (age>18){
console.log('來啊 來啊')
}
# if-else
if (age>18){
console.log('來啊 來啊')
}else{
console.log('沒錢 滾蛋')
}
# if-else if else
if (age<18){
console.log("年齡太小")
}else if(age<24){
console.log('何時')
}else{
console.log('你是個好人')
}
"""
在js中程式碼是沒有縮排的 只不過我們處於python書寫習慣人為的加上了而已
()條件
{}程式碼塊
"""
- switch
"""
提前列舉好可能出現的條件和解決方式
"""
switch(num){
case 0:
console.log('喝酒');
break; # 不加break 匹配到一個之後 就一直往下執行
case 1:
console.log('唱歌');
break;
case 2:
console.log('洗腳');
break;
case 3:
console.log('按摩');
break;
case 4:
console.log('營養快線');
break;
case 5:
console.log('老闆慢走 歡迎下次光臨');
break;
default:
console.log('條件都沒有匹配上 預設走的流程')
}
- for迴圈
# 列印0-9數字
for(let i=0;i<10;i++){
console.log(i)
}
# 迴圈打印出數組裡面的每一個元素
var l1 = [111,222,333,444,555,666]
for(let i=0;i<l1.length;i++){
console.log(l1[i])
}
- while迴圈
# while迴圈
var i = 0
while(i<100){
console.log(i)
i++;
}
-
三元運算子
三元運算子不要寫的過於複雜
# python中三元運算子 res = 1 if 1>2 else 3
# JS中三元運算 res = 1>2?1:3
條件成立取問好後面的1 不成立取冒號後面的3
var res = 2>5?8:10 # 10
var res = 2>5?8:(8>5?666:444) # 666
函式
函式定義:JavaScript中的函式和Python中的非常類似,只是定義方式有點區別。【因為不需要返回特定的型別值,所以和C語言的區別僅僅是function書寫而已】
# 在python定義函式需要用到關鍵字def
# 在js中定義函式需要用到關鍵字function
# 格式
function 函式名(形參1,形參2,形參3...){函式體程式碼}
# 無參函式
function func1(){
console.log('hello world')
}
func1() # 呼叫 加括呼叫 跟python是一樣的
# 有參函式
function func2(a,b){
console.log(a,b)
}
func2(1,2)
func2(1,2,3,4,5,6,7,8,9) # 多了沒關係 只要對應的資料
1 2
func2(1) # 少了也沒關係
1 undefined
# 關鍵字arguments
function func2(a,b){
console.log(arguments) # 能夠獲取到函式接受到的所有的引數
console.log(a,b)
}
# 限定引數的傳遞
function func2(a,b){
if(arguments.length<2){
console.log('傳少了')
}else if (arguments.length>2){
console.log('傳多了')
}else{
console.log('正常執行')
}
}
# 函式的返回值 使用的也是關鍵字return
function index(){
return 666
}
function index(){
return 666,777,888,999
}
res = index();
999
res
999 # 只能拿到最後一個
# 如果想要返回多個,則使用陣列【比上不足,比下有餘,總比C語言方便】
function index(){
return [666,777,888,999]
}
# js不支援解壓賦值
# 匿名函式 就是沒有名字【函式名的傳遞,和python一毛一樣】
function(){
console.log('哈哈哈')
}
var res = function(){
console.log('哈哈哈')
}
# 箭頭函式(要了解一下) 主要用來處理簡單的業務邏輯 類似於python中的匿名函式
var func1 = v => v; """箭頭左邊的是形參 右邊的是返回值"""
等價於
var func1 = function(v){
return v
}
var func2 = (arg1,arg2) => arg1+arg2
等價於
var func1 = function(arg1,arg2){
return arg1+arg2
}
函式的全域性變數和區域性變數
區域性變數:
在JavaScript函式內部宣告的變數(使用 var)是區域性變數,所以只能在函式內部訪問它(該變數的作用域是函式內部)。只要函式執行完畢,本地變數就會被刪除。
全域性變數:
在函式外宣告的變數是全域性變數,網頁上的所有指令碼和函式都能訪問它。
變數生存週期:
JavaScript變數的生命期從它們被宣告的時間開始。
區域性變數會在函式執行以後被刪除。
全域性變數會在頁面關閉後被刪除。
作用域
首先在函式內部查詢變數,找不到則到外層函式查詢,逐步找到最外層。與python作用域關係查詢一模一樣!作用範圍是以{}界定的。
# 跟python查詢變數的順序一致
var city = "BeiJing";
function f() {
var city = "ShangHai";
function inner(){
var city = "ShenZhen";
console.log(city);
}
inner();
}
f(); //輸出結果是?
var city = "BeiJing";
function Bar() {
console.log(city);
}
function f() {
var city = "ShangHai";
return Bar;
}
var ret = f();
ret(); // 列印結果是?
# 閉包的使用,參考python
var city = "BeiJing";
function f(){
var city = "ShangHai";
function inner(){
console.log(city);
}
return inner;
}
var ret = f();
ret();
自定義物件
JavaScript中的所有事物都是物件:字串、數字、陣列、日期,等等。在JavaScript中,物件是擁有屬性和方法的資料。
JavaScript的物件(Object)本質上是鍵值對的集合(Hash結構),但是隻能用字串作為鍵。
我們在學習基本資料型別的時候已經帶大家瞭解了,JavaScript中的Number物件、String物件、Array物件等。
# 你可以看成是我們python中的字典 但是js中的自定義物件要比python裡面的字典操作起來更加的方便
# 建立自定義物件 {}
"""第一種建立自定義物件的方式"""
var d1 = {'name':'yangyi','age':18}
var d = {'name':'yangyi','age':18}
typeof d
"object"
d['name']
"yangyi"
d.name # 比python從字典獲取值更加的方便【python中使用get方法】
"yangyi"
d.age
18
# 支援for迴圈 暴露給外界可以直接獲取的也是鍵
for(let i in d){
console.log(i,d[i])
}
"""第二種建立自定義物件的方式 需要使用關鍵字 new"""
var d2 = new Object() # {}
d2.name = 'yangyi'
{name: "yangyi"}
d2['age'] = 18
{name: "yangyi", age: 18}
Date物件
# 時間都是該物件被定義的時候的,不會動態重新整理
let d3 = new Date()
Fri May 15 2020 14:41:06 GMT+0800 (中國標準時間)
d3.toLocaleString()
"2020/5/15 下午2:41:06"
# 也支援自己手動輸入時間
let d4 = new Date('2200/11/11 11:11:11')
d4.toLocaleString()
let d5 = new Date(1111,11,11,11,11,11)
d5.toLocaleString() # 月份從0開始0-11月
"1111/12/11 上午11:11:11"
# 時間物件具體方法
let d6 = new Date();
d6.getDate() 獲取日
d6.getDay() 獲取星期
d6.getMonth() 獲取月份(0-11)
d6.getFullYear() 獲取完整的年份
d6.getHours() 獲取小時
d6.getMinutes() 獲取分鐘
d6.getSeconds() 獲取秒
d6.getMilliseconds() 獲取毫秒
d6.getTime() 時間戳
JSON物件
"""
在python中序列化反序列化
dumps 序列化
loads 反序列化
在js中也有序列化反序列化
JSON.stringify() ---> dumps
JSON.parse() ---> loads
"""
let d7 = {'name':'yangyi','age':18}
let res666 = JSON.stringify(d7)
"{"name":"yangyi","age":18}"
JSON.parse(res666)
{name: "yangyi", age: 18}
RegExp物件
"""
在python中如果需要使用正則 需要藉助於re模組
在js中需要你建立正則物件
"""
# 第一種 有點麻煩
let reg1 = new RegExp('^[a-zA-Z][a-zA-Z0-9]{5,11}')
# 第二種 個人推薦
let reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/
# 匹配內容
reg1.test('egondsb')
reg2.test('egondsb')
# 題目 獲取字串裡面所有的字母s
let sss = 'egondsb dsb dsb'
sss.match(/s/) # 拿到一個就停止了
sss.match(/s/g) # 全域性匹配 g就表示全域性模式
sss.match(/s/)
["s", index: 5, input: "egondsb dsb dsb", groups: undefined]
sss.match(/s/g)
(3)["s", "s", "s"]
# 全域性匹配模式吐槽點
let reg3 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/g
reg2.test('egondsb')
reg3.test('egondsb') # 全域性模式有一個lastIndex屬性
true
reg3.test('egondsb')
false
reg3.test('egondsb')
true
reg3.test('egondsb')
false
reg3.lastIndex
0
reg3.test('egondsb')
true
reg3.lastIndex
7
# 吐槽點二
let reg4 = /^[a-zA-Z][a-zA-Z0-9]{5,11}/
reg4.test()
reg4.test() # 什麼都不傳 預設傳的是undefined
true
reg4.test()
true
reg4.test(undefined)
true
let reg5 = /undefined/
undefined
reg5.test('jason')
false
reg5.test()
true
"""
總結 你在用js書寫正則的時候一定要注意上述問題
一般情況下你後續也不會解除到了
"""
Math物件
abs(x) 返回數的絕對值。
exp(x) 返回 e 的指數。
floor(x) 對數進行下舍入。
log(x) 返回數的自然對數(底為e)。
max(x,y) 返回 x 和 y 中的最高值。
min(x,y) 返回 x 和 y 中的最低值。
pow(x,y) 返回 x 的 y 次冪。
random() 返回 0 ~ 1 之間的隨機數。
round(x) 把數四捨五入為最接近的整數。
sin(x) 返回數的正弦。
sqrt(x) 返回數的平方根。
tan(x) 返回角的正切。