從無到有的學習JavaScript——第一篇(基礎篇)

1. JavaScript的變量

1.1 變量定義

一個 JavaScript 標識符必須以字母、下劃線(_)或者美元符號($)開頭;後續的字符也可以是數字(0-9),因爲 JavaScript 語言是區分大小寫的,所以字母可以是從“A”到“Z”的大寫字母和從“a”到“z”的小寫字母。

a = 100

var b = 200  // 變量定義時初始化

let c = 'abc'

console.log(d)   // 不會報錯,直接打印undefined

var d  // 變量申明,可以申明提升

let f   // 變量申明,ES6新增的關鍵字

d = 500  // 變量賦值,相當於定義全局變量

 

const g = 600  // 常量定義,常量必須申明時賦值,之後不能再改變
 

// 明天會更好

var a 
let b
console.log(1, a, b)
// 1 undefined undefined
a = 100
b = 'a string'
console.log(2, a, b)
// 2 100 'a string'

// 常量必須聲明時賦值,之後不能在改
const c = 100
console.log(c)
// c = 200  // 會報錯,常量不允許修改

var y  // 只是聲明,y值爲undefined 
var x = 5  // 規範的聲明並初始化,聲明全局變量或局部變量

z = 6  
/* 不規範的初始化,不推薦,在嚴格模式下回產生異常,在賦值之前不能引用,
   因爲它沒有申明。一旦這樣賦值,就是全局作用域。
*/


function hello()
{
    var m  // 只是申明,m爲undefined,作用域在函數中
    m = 100  // m爲局部變量
}

// console.log(m)  // 未申明變量m,異常

var申明一個變量,會把變量提升到當前全局或函數作用域。let申明一個語句塊作用域中的局部變量,const申明一個常量。JS中的變量申明和初始化時可以分開的。如果明確知道一個標識符定義後不再修改,應該儘量申明成const常量,減少被 修改的風險,減少bug。

1.2 變量提升

JavaScript變量的另一個不同尋常的地方是,你可以先使用變量稍後再聲明變量而不會引發異常。這一概念稱爲變量提升;Javascript變量感覺上是被提升或 移到了函數或語句的最前面,但是提升後的變量將返回undefined值。因此在使用或引用某個變量之後進行申明和初始化操作,這個被提升的變量將返回undefined值。

  console.log(x === undefined)  //true 
  var x = 5

var myvar = 'my value'

function a(){
    console.log(myvar)  // undefined
    var myvar = 'local value'
}

a()

// 上面的函數等價於下面的函數
function a(){
    var myvar
    console.log(myvar)
    myvar = 'local value'
}

a()

函數提升:對於函數來說,只有函數申明會被提升到頂部,而函數表達式不會提升。

foo()  // bar

function foo(){
    console.log('bar')
}

baz()  // 類型錯誤:baz不是一個函數,只是一個函數表達式

var baz = function(){
    console.log('bar2')
}

2. 數據類型

 

ES是動態語言,弱類型語言。雖然先申明瞭變量,但是變量可以重新賦值任何類型。

2.1 數據類型測試

// 類型轉換
// 弱類型語言

console.log("============string===============")
console.log(a = 3 + 'sun', typeof(a))
console.log(a = null + 'sun', typeof(a))
console.log(a = undefined + 'sun', typeof(a))
console.log(a = true + 'sun', typeof(a))
/* 
============string===============
3sun string
nullsun string
undefinedsun string
truesun string
*/

// number
console.log('==========number===============')
console.log(a = null + 8, typeof(a))
console.log(a = undefined + 8, typeof(a))  // undefined沒法轉換成一個對應的數字
console.log(a = true + 8, typeof(a))
console.log(a = false + 8, typeof(a))
/*
==========number===============
8 'number'
NaN 'number'  // NaN not a number
9 'number'
8 'number'
*/

// boolean
console.log('===========bool===========')
console.log(a = null + true, typeof(a))
console.log(a = null + false, typeof(a))
console.log(a = undefined + true, typeof(a))  // undefined無法轉換成一個對應的數字
console.log(a = undefined + false, typeof(a))
console.log(a = null & true, typeof(a))
console.log(a = undefined & true, typeof(a))  // 0
// 短路
console.log(a = null && true, typeof(a))  // 邏輯運算符null直接就是false短路
console.log(a = false && null, typeof(a))  // 邏輯運算符,false短路直接返回false
console.log(a = false && 'sun', typeof(a))
console.log(a = true && 'sun', typeof(a))
console.log(a = true && '', typeof(a))  // 結果a爲空字符串
console.log(a = {} && 'sun', typeof(a))
console.log(a = [] && 'sun', typeof(a))
// 注意[], {}與python中不同,在JS中,對象等價於true
/* 
===========bool===========
1 'number'
0 'number'
NaN 'number'
NaN 'number'
0 'number'
0 'number'
null 'object'
false 'boolean'
false 'boolean'
sun string
 string
sun string
sun string
*/

// null
console.log('=========null============')
console.log(a = null + undefined, typeof(a))
// NaN 'number'

弱類型,不需要強制類型轉換,會隱式類型轉換。NaN,即not a number,轉換數字失敗,它和任何值都不等,和自己也不等,只能使用Number.isNaN(NaN).

總結:遇到字符串,加號就是拼接字符串,所有非字符串隱式轉換爲字符串,如果沒有字符串,加號把其他所有類型都當數字處理,非數字類型隱式轉換成數字。undefined特殊,因爲它沒有定義值,所以轉換成數字失敗得到一個特殊值NaN。如果運算符是邏輯運算符,短路符,返回就是短路時的類型。沒有隱式轉換。除非你十分明確確,否則不要依賴隱式轉換,寫代碼的時候,往往爲了程序的健壯,請顯示轉換。

2.2 字符串

將一個值使用單引號或者雙引號引用起來就是字符串。ES6提供了反引號定義一個字符串,就可以支持多行,還支持插值。


let a = 'abc'
let b = "123"
let c = `line
    line2
    line3
`  // 支持多行
console.log(c)
/*
line
    line2
    line3

*/

// 字符串插值,要求在反引號字符串中,python3.6支持
let name = "tom", age = 19
console.log(`Hi, my name is ${name}. I am ${age}`)
// Hi, my name is tom. I am 19

2.3 轉義字符

2.4 字符串操作方法

字符串方法很多,跟python類似。

let school = 'magedu'

console.log(school.charAt(2))  // g,字符串下標從0開始
console.log(school[2])  // g
console.log(school.toLocaleUpperCase())  // MAGEDU
console.log(school.concat('.com'))  // 連接
console.log(school.slice(3))  //切片,支持負索引
console.log(school.slice(3, 5))  // ed 前包後不包,跟python切片是一樣的
console.log(school.slice(-2, -1))  // d
console.log(school.slice(-3))  // 後三個

let url = "www.magedu.com"
console.log(url.split('.'))  // 結果是列表,跟python是一樣的
console.log(url.substr(4, 6))  // 返回子串從何處開始,取多長,注意下從0開始
// magedu
console.log(url.substring(7, 10))  // 返回子串從何處開始,到什麼爲止
// 注意是前包後不包

let s = 'magedu.edu'
console.log(s.indexOf('ed'))  // 3
console.log(s.indexOf('ed', 4))  // 7
console.log(s.replace('.edu', '.com'))
// magedu.com
s = ' \tmag edu \r\n'
console.log(s.trim())  // 去除兩端的空白字符,trimleft、trimright是非標函數,少用
// mag edu

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章