1 嚴格模式
1.1 什么是嚴格模式
JavaScript除了提供正常模式外,還提供了嚴格模式(strict mode),ES5的嚴格模式是采用具有限制性Javascript變體的一種方式,即在嚴格的條件下運行js代碼,
嚴格模式在IE10以上版本的瀏覽器中才會被支持,舊版本瀏覽器會被忽略,
嚴格模式對正常的javascript語意做了一些更改:
- 消除了Javascrip語法的一些不合理、不嚴謹之處,減少了一些怪異行為,
- 消除了代碼運行的一些不安全之處,保證代碼運行的安全,
- 提高編譯器效率,增加運行速度,
- 禁用了在ECMAScript的未來版本中可能會定義的一些語法,為未來新版本的Javascript做好鋪墊,比
如一些保留字:class,enum,export,extends,import,super不能做變數,
1.2 開啟嚴格模式
嚴格模式可以應用到整個腳本或個別函式中,因此在使用時,我們可以將嚴格模式分為腳本開啟嚴格模式和
為函式開啟嚴格模式兩種情況
- 為腳本整個腳本開啟嚴格模式
為整個腳步檔案開啟嚴格模式,需要在所有陳述句之前做一個特定陳述句"use strict"
<scirpt>
"use strict"
console.log("這是最嚴格模式")
</scirpt>
- 為函式開啟嚴格模式
要給某個函式開啟嚴格模式,需要把"use strict";(或'use strict')宣告放在函式體所有陳述句前,
<script>
function fn() {
'use strict' //下面的代碼按照嚴格模式進行
}
</script>
3.3 嚴格模式中的變化
嚴格模式對javascript的語
法和行為,都做了一些改變
- 變數規定
- 在正常模式中,如果一個變數沒有宣告就賦值,默認的事全域變數,
- var 命令宣告,然后再使用
<script>
‘use strict’
num = 10
console.log(num)
</script>
效果如下圖
嚴禁洗掉已經宣告的變數,
- 嚴格模式下this指向問題
- 以前在全域作用域函式中的this指向window物件,
- 嚴格模式下全域作用域中函式中的this事undefined,
- 以前建構式時不加new也可以呼叫,當普通函式,this指向全域物件,
- 嚴格模式下,如果建構式不加new呼叫,this會報錯, new實體化的建構式指向創建的物件實體,
- 嚴格模式下,定時器里的this指向還是window.
- 嚴格模式下,事件、物件還是指向呼叫者,
- 函式變化
- 嚴格模式下函式不能有重名的引數
- 函式必須宣告在頂層,新版本的js會引入“塊級作用域”(ES6中已引入),為了與新版本接軌,不允許在非函式的代碼塊內宣告函式,如在if,for陳述句中宣告函式,
2 高階函式
高階函式是對其他函式進行操作的函式,它接收函式作為引數或函式作為回傳值輸出,
function fn(callback) {
callback && callback()
}
fn(function(){
alert('lanfeng')
})
function fn() {
return function() {
}
}
fn()
此時fn就是一個高階函式
函式也是一種資料型別,同樣可以作為引數,傳遞給另外一個引數使用,最典型的就是作為回呼函式
3 閉包
3.1 變數作用域
變數根據作用域的不同分為兩種:全域變數和區域變數,
- 函式內部可以使用全域變數
- 函式外部不可以使用區域變數
- 當函式執行完時,本作用域內的區域變數會被銷毀,
3.2 什么是閉包
閉包指有權訪問另外一個函式作用域中變數的函式,也就是說,一個作用域可以訪問另外一個函式內部的區域變數,
//fn 外面的作用域可以訪問fn內部的區域變數
function fn() {
var num = 10
function fun () {
console.log(num) //可以訪問num
}
return fun
}
var f = fn()
f() //10
//fn 外面的作用域可以訪問fn內部的區域變數
function fn() {
var num = 10
// 回傳一個匿名函式
return function() {
console.log(num) //可以訪問num
}
}
var f = fn()
f() //10
閉包的主要作用: 延伸了變數的作用范圍
3.3 閉包案例
- 回圈注冊點擊事件
//html
<ul >
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
//js
//點擊li輸出當前li的索引
//利用動態田徑屬性方式
var lis = document.querySelector('.nav').querySelectorAll('li')
for(var i=0 ;i<lis.length; i++) {
lis.index = i
lis[i].onclick = function() {
console.log(this.index)
}
}
//利用閉包的方式
var lis = document.querySelector('.nav').querySelectorAll('li')
for(var i=0 ;i<lis.length; i++) {
(function(i) {
lis[i].onclick = function() {
console.log(i)
}
})(i)
}
- 回圈中的setTimeout()
//html
<ul >
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
//js
//利用閉包
var lis = document.querySelector('.nav').querySelectorAll('li')
for(var i=0 ;i<lis.length; i++) {
(function(i){
setTimeout(function() {
console.log(lis[i].innerHTML)
},3000)
})(i)
}
- 計算打車價格
var car = (function() {
var start = 13;
var total = 0;
return {
//正常價格
price: function(n) {
if(n <= 3) {
total = start
} else {
total = start + (n-3)* 5
}
return total;
},
// 擁堵之后
yd: function(flag) {
flag? total+ 10 :total
}
}
})()
console.log(car.price(5))
console.log(car.yd(true))
3.4 閉包總結
- 閉包是什么?
閉包就是一個函式(一個作用域可以訪問另外一個函式的區域變數)
- 閉包的作用是什么?
延伸變數的作用范圍
4 遞回
4.1 什么是遞回
如果一個函式在內部可以呼叫其本身,那么這個函式就是遞回函式,
遞回函式的作用和回圈效果一樣
由于遞回很容易發生“堆疊溢位”(stack overflow),所以必須要加退出條件 return
4.2 利用遞回求數學題
- 求123...*n
function fn(n) {
if(n = 1) {
return 1
}
return n * fn(n-1)
}
console.log(fn(3)) // 6
4.3 利用遞回求:根據id回傳對應的資料物件
var data = https://www.cnblogs.com/lfcss/p/[{
id:1,
name:'家電',
goods: [
{
id: 11,
gname: '冰箱'
},
{
id: 12,
gname: '洗衣機'
}
]
},
{
id: 2,
name: '服飾'
}
]
function getObj(arr, id) {
var o = {}
arr.forEach(function(item){
if(item.id === id) {
o= item
} else if(item.goods && item.goods.length>0) {
o =getObj(item.goods, id);
}
})
return o
}
console.log(getObj(data, 1))
5 遞回
5.1 淺拷貝和深拷貝
- 淺拷貝只是拷貝一層,更深層次物件級別的只拷貝參考,
- 深拷貝拷貝多層,每一級別的資料都會拷貝,
- Object.assign(target, ...sources) es6新增方法可以淺拷貝
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
}
}
var o = {}
for(var k in obj) {
// k是屬性名
o[k] = obj[k]
}
console.log(o)
o.msg.age = 20
console.log(obj) //obj發生變化
//用es6語法糖
Object.assign(o, obj)

//深拷貝,應用遞回的方法
function deepCopy(newObj, oldObj) {
for(var k in oldObj) {
//判斷我們的屬性值屬于哪種型別
var item = oldObj[k]
// 判斷是否是陣列
if(item instanceof Array) {
newObj[k] = []
deepCopy(newObj[k], item)
} else if(item instanceof Object) {
//判斷是否是物件
newObj[k] = {}
deepCopy(newObj[k], item)
} else { // 屬于簡單資料型別
newObj[k] = item
}
}
}
deepCopy(o,obj)
console.log(o)
總結
本篇文章主要分享了函式的嚴格模式、高階函式、閉包、遞回、深拷貝、淺拷貝等知識點的用法及應用,如果想了解更多,請掃描二維碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/145762.html
標籤:JavaScript
