首頁 >web前端 >js教程 >javascript基礎知識解說

javascript基礎知識解說

高洛峰
高洛峰原創
2017-01-21 09:17:201226瀏覽

本篇適合javascript新手或學了前端一段時間,對js概念不清晰的同學~~。

學習目的

本文針對javascript基礎薄弱的同學,可以加深對javascript的理解。

本文將講述以下幾點對於初學者開說javascript(有的是大部分語言都有的)的坑

講解內容如下:

1. 連等

2. i++

3. 包裝物件

2. i++

3. 包裝物件

2. i++

3. 包裝物件

2. i++

3. 包裝物件

2. i++

3.包裝物件

4. 引用型別

5. && 與||

講解部分

1. 連等

小試牛刀

連等是常見的表達式,但是並不是所有情況都適合連等,連等只等只適用於字面量並不適用於引用型別。

// 字面量连等得到想要的结果
var a,b;
a = b = 2;
a // 2
b // 2
// 引用类型连等不可预测
var arr1, arr2;
arr1 = arr2 = []
arr1[0] = 10
arr2[0] // 10
//引用类型连等使得两个引用指向一个对象,操作其中一个,两个值都变

以上程式碼是常見的連等,有時候我們需要兩個變數同賦值為一個值,我們就這樣來操作,但是,如果是引用型別可不能連等賦值哦。

此外,連等賦值會有一個很大的漏洞,就是會將變數洩露到全局中去,上面程式碼我們沒有將其洩露,但看下面程式碼:

function fn (num) {
 var a = b = num;
 a // num
 b // num
}
fn(10)
a // 报错
b // 10
// 我们并不没有定义全局变量b

可以看到,我們執行了fn函數後來,全域作用域中出現了b變量,這是為什麼?看var a = b = num這句話,這句話可以分成兩句來看

var a
a = b = num
//只声明了a

我們其實只聲明了a變量,連等的b並沒有聲明,由此可以知道,b被掛在了全域的window物件上,造成了變數洩漏到了全域。

初出茅廬

上面只是簡單的例子,接下來我們看一個複雜點的例子

var a = {x: 1}
var b = a
a.x = a = {y: 1}
a.x // undefined
b.x // {y: 1}

這個例子是在一個測試題中看到的,乍一看,好像不明覺,但是一點都不難理解。

1. a 和b是引用了類型,同指向了一個物件{x: 1}

2. a.x 引用了原物件的x屬性, a 則為一個引用變數

3. a  = {y: 1}  只是將a這個引用變數的指標指向了另一個物件{y: 1}

4. a.x = a,前者還是代表著原來的物件的x屬性,也就是b引用的物件的x屬性

5. 賦值完畢。

可能你還沒理解,不要急,下面我們將解剖javascript引擎讓你懂的明明白白

庖丁解牛

引擎的工作原理: 引擎在解析javascript表達式時,會進行LHS查詢, RHS查詢(詳見《你不知道的javascript》),我將它們理解為LHS(賦值),RHS(查找)。

下面,就上面例子,我們來示範一下引擎的工作流程

var a = {x: 1}
// 引擎:我将要对a变量LHS(赋值),内容是{x: 1}
// 作用域: 刚声明了a变量,给你。
var b = a
// 引擎: 我将要对a变量RHS(查找)
// 作用域: 你刚刚给它LHS了,给你吧
// 引擎: 我将要对b变量LHS(赋值),内容为a变量指向的对象
// 作用域:刚声明了b变量,给你。
a.x = a = {y: 1}
// 引擎:我将要对a进行LHS(赋值),内容是另一个对象{y:1}
// 作用域:可以,给你,但好像还有其他命令,先不要赋值。
// 引擎: 是的,下一步我还需要对a.x 进行LHS(赋值),内容是将要改变的a变量
// 作用域: 可以,a变量指向的对象有x属性,不过马上a就改变了,不过没关系,b变量也指向那个对象,赋值完后,你可以用b变量引用旧对象。
// 引擎:了解了,我先把a变量赋值为一个新的对象,然后把原来的a变量指向的对象的x属性赋值为 新a。
a.x // undefined
// 引擎: 我需要拿到a变量指向的对象的x属性
// 作用域: 你刚刚改变了a的指向,现在的a指向的对象已经没有x属性了
b.x // {y: 1}
// 引擎: 我需要拿到b变量指向的对象的x属性
// 作用域: 你是想拿到你旧对象的x属性吧,给你,不过已经被你在之前改变了值,现在b.x的值就是a指向的新对象的值。

2. ++操作符

大家最很常用++ 操作符,其實也沒什麼很大奇特之處,但是對於新手入門的你是否真正了解他。

var a = 1;
var b = a++
a // 2
b // 1
var c = 1;
var d = ++ c;
c // 2
d // 2

前++和後++,一個是傳回表達式自增後一個是傳回表達式自增前的值。我們可以把兩個進行分解,看一下過程。

b = a++
// 等价于 ...
b = a
a = a + 1
//.........................
b = ++ a
// 等价于 ...
a = a + 1
b = a

只是一個運算順序問題,這個可能好理解,但是也有一個坑,如下。

前幾天一個人問: 1++ 等於幾?答: 2

估計很多人第一反應就是2,但這大錯特錯!那為什麼不等於2呢,其實1++是報錯了,並不是合法的表達式,原因如下:

1 ++
// 等价于
1 = 1 + 1
// 引擎对 1 进行LHS(赋值),作用域发现他是非法变量,所以会报错 左值无效。

3. 包裝物件

我們在用​​字串取得長度、使用方法截取等行為時,你有沒有想過: 字面值只是個值,為什麼他會有方法屬性,不是應該對象才有的嗎?的確是物件才有的,但是執行表達式時,產生了包裝物件。也許你看過了此知識點,可以跳過。

var str = 'hello'
str.length // 5
str.aaa = 5
str.aaa // undefined

我們定義一個str字串,取得長度為5,但是我們自己加一個屬性aaa缺取得不到,這需要用包裝物件的宣告週期來解答:包裝物件的宣告週期只存在於一個表達式內

var str = 'hello'
str.length
// 等价于
new String(str).length
str.aaa = 5
//等价于
new String(str).aaa = 5
str.aaa
// 等价于
new String(str).aaa

也就是說,每次用到str屬性時,都是先包裝成String對象,操作完後,對象釋放,可見,以上兩次str.aaa是不同的對象,所以第二次獲取aaa屬性當然沒有了。不了解可以百度一下js包裝對象,有詳細的解答。

4. 引用型別

大部分語言都有引用型,其實就是物件變數。 c語言中,我們將引用型別理解為指針,這個指針是動態指向一塊內存,透過程式碼的變化,指針的指向會隨之改變。 js也一樣。 🎜🎜在我們書寫程式碼中,一定要記住引用類型變數和字面值變數的 區別,他們分別有不同的用處。 🎜
var global = new Object()
function setColor (obj) {
 obj.color = 'blue'
 obj = new Object()
 obj.color = 'red'
}
setColor(global)
global.color // blue
🎜這是《javascript高級程式設計》裡面的一個例子,我們傳遞一個物件global到setColor函數裡,在內部進行瞭如上操作,我們列印出global.color是blue,為什麼不是red?這裡就是引用型的結果。 🎜🎜1. global變數是引用型,他指向一個物件,🎜🎜2. 傳遞到setColor函數中,obj就引用了global指向的物件(下面稱為globalObj)🎜🎜3. 給globalObjjj值一個color屬性為賦值blue字串,這時global.color是blue了🎜🎜4. 將obj指向另一個新物件localObj,使得obj與global斷開連接。 🎜🎜5. 將localObj.color賦值為‘red'🎜

可以看出,我们并没有对global对象的color进行'red'赋值,'red'赋值给了另一个对象的color属性。

结论:引用类型传递是将两个变量指向同一个对象,而字面量的传递仅仅是值的赋值传递。我们可以将引用类型传递到函数进行改变,不可以在函数内改变传递进来的字面值。

5. && 与 ||

两者的基本运用相信大家都了解,大部分用来if判断,如:

var a = 2;
var b = false
if (a && b) {
 
 alert('best')
}
if (a || b) {
 alret('good')  // 运行
}

他们的用法不局限于判断 左右两边的 && 和 || 关系,还可以用来提供代码的质量

var obj = {}
if (obj.info.user === 'xu') { // terrible
 // ..
}
if (obj.info && obj.info.user === 'xu' ) { // good
 // ...
}

如果仅仅判断obj.info.user 会报错造成程序终止,但是下面那样判断就大使得代码健壮,不会那么容易崩溃。

重点: && 和 || 并不会返回true和false,他会返回终止此表达式的那个变量值。

true && 6 // 6
NaN && false // NaN
'0' || 6 // '0'
false || true // true
false || 0 && 1 // 0
false || 1 && 0 // 0

&&和||, &&优先级大于||。

&&操作符,如果左边为假,返回左边值,否则,始终返回右边值

||操作符,如果左边为真,返回左边值, 否则,始终返回右边值。

结尾

javascript基础本章简单的介绍在这里,内容并不全面,还请多多见谅。如有错误,请指出。。。。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持PHP中文网!

更多javascript基础知识讲解相关文章请关注PHP中文网!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn