本篇適合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中文网!