一、JS執行機制
(1)JS是單線程
JavaScript語言的一大特點就是單線程,也就是同一時間只能做一件事。因為JavaScript是為了處理頁面中的用戶交互,以及制作DOM二誕生的。比如我們對某個DOM元素進行添加和刪除操作,這個不能同時進行,應該先添加,后刪除。
這樣也會有問題:如果JS執行時間過長,會造成頁面渲染不連貫,導致頁面渲染加載阻塞的感覺
為了解決這個問題,利用多喝CPU的計算能力,HTML5提粗Web Worker標準,允許JavaScript腳本創建多個線程,于是就有了同步和異步。
(2)同步和異步
1.同步
前一個任務結束后再執行后一個任務,程序的執行與任務的排列順序是一致的、同步的。
該怎么理解呢?
就像做飯的同步做法:我們要燒水做飯,等水開了(10分鐘之后),再去切菜,炒菜,一步一步來。
2.異步
在執行這個任務的同時,也在執行別的任務。
再來拿做飯打比方:在燒水的同時,我們來切菜,炒菜。
簡單以一個案例來體驗一下JS的執行過程:
console.log(1);
setTimeout(function () {console.log(3);
}, 1000);
console.log(2);
執行結果是:
由此可以看出,現在的JS可以同時執行任務,也就是可以異步執行?
(3)同步任務
同步任務都在主線程是執行,形成一個執行棧
(4)異步任務
JS的異步任務是通過回調函數實現的
異步任務有三種類型:
- 普通事件:如click,resize等
- 資源加載:如load,error等
- 定時器:包括setInterval,setTimeout等
異步任務相關回調函數添加到任務隊列中(任務隊列也稱為消息隊列)?
(5)JS執行機制
1.先執行執行棧中的同步任務
2.異步任務(回調函數)放入任務隊列中
3.一旦執行棧中的同步任務完成,按次序讀取任務隊列中的異步任務,于是被讀取的異步任務結束等待狀態,進入執行棧,開始執行?
案例:來一個練習題試試,像下面這個代碼該怎么執行呢?究竟是1 2 3還是1 3 2呢?
console.log(1);
setTimeout(function () {console.log(3);
}, 0);
console.log(2);
居然還是1 2 3,,看來這個是一個同步任務,它會形成一個執行棧
但是普通的同步任務只會產生1 2 3的序列,而setTimeout屬于異步任務的定時器類型,它會產生一個任務隊列
?按照執行機制來看,先執行執行棧中的同步任務,先執行
console.log(1);
遇見了異步任務
setTimeout(fn(), 0);
把異步任務放入任務隊列中,不執行,執行完執行棧里的同步任務后再執行,最后的輸出就是我們看見的1 2 3
那如果有多個異步任務該怎么執行呢?我們來看下面這段代碼
console.log(1);
document.onclick = function () {console.log('click');
}
console.log(2);
setTimeout(function () {console.log(3);
}, 1000);
里面的執行過程為:
其中document.onclick那個只有再鼠標點擊后才會放入任務隊列,setTimeout這個只有事件到了才會放入任務隊列,也就是圖中的console.log(3) ,執行完就會清空任務隊列
?由于主線程不斷的重復獲得任務、執行任務、在獲取任務、再執行,所以這種機制被稱為事件循環(even lop)
二、location對象
(1)location對象
window對象給我們提供了一個location屬性用于獲取或設置窗體的URL,并且可以用于解析URL。因為這個屬性返回的是一個對象,所以我們將這個屬性也稱為location對象。
?(2)URL
統一資源定位符(Uniform Resource Locator,URL)是互聯網上標準資源的地址。互聯網上的每個文件都有一個唯一的URL,它包含的信息指出文件的位置以及瀏覽器一個怎么處理它。
URL的一般語法格式為:
protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
組成 | 說明 |
---|---|
protocol | 通信協議,常用的http,ftp,maito等 |
host | 主機(域名) www.itheima.com |
port | 端口號(可選),省略時使用方案的默認端口,如http的默認端口為80 |
path | 路徑,由領或多個'.'符號隔開的字符串,一般用來表示主機上的一個目錄或文件地址 |
query | 參數,以鍵值對的形式,通過&符號分隔開來 |
fragment | 片段,#后面內容,常見于鏈接、錨點 |
(3)location對象的屬性
location對象屬性 | 返回值 |
---|---|
location.href | 獲取或者設置整個URL |
location.host | 返回主機(域名)?www.itheima.com |
location.port | 返回端口號,如果未寫則返回空字符串 |
location.pathname | 返回路徑 |
location.search | 返回參數 |
location.hash | 返回片段 |
敲重點!!!href和search要重點記住
來做一個案例:5秒后跳轉頁面
手動跳轉:
<button>點擊</button>
var btn = document.querySelector('button');
btn.addEventListener('click', function () {location.href = 'http://www.itcast.cn';
})
直接輸出location.href可以得到該頁面的整個URL,賦值可以去往另一個頁面
主播主播,手動跳轉還是太累了,有沒有更強勢的跳轉方式?
有的有的,有一個自動跳轉的方法
先建立一個空的div盒子
<div></div>
然后寫JS,采用定時器實現5s后跳轉頁面
var div = document.querySelector('div');
var timer = 5;
function fn() {div.innerHTML = '您將在' + timer + '秒之后跳轉到首頁';timer--;
}
fn();
setInterval(function () {if (timer == 0) {location.href = 'http://www.itcast.cn';}else {fn();}
}, 1000)
案例:獲取URL參數數據
來練習一下數據在不同頁面中的傳遞
新建一個文件夾,將我們要建立我們這兩個頁面
然后在login.html中使用表單,來將數據傳輸到index.html里
<form action="index.html">用戶名<input type="text" name="uname"><input type="submit" value="登錄">
</form>
?在這個界面里輸入123?
在index這里我們就有了123這個信息
?也就是要用?后面的那一串信息
我們可以用location.search得到?uname=123
但是我們不需要?,則我們用substr去掉
var params=location.search.substr(1);
?然后再利用=分割鍵和值,也就是split('=')
var arr=params.split('=');
再把數據寫入div中
var div = document.querySelector('div');
div.innerHTML = arr[1] + '歡迎您';
這樣就能把數據傳到另一個頁面上啦
?(4)location對象的方法
location對象方法 | 返回值 |
---|---|
location.assign() | 跟href語言,可以跳轉頁面(也稱為重定向頁面) |
location.replace() | 替換當前頁面,因為不記錄李四,所以不能后退界面 |
location.reload() | 程序加載頁面,相當于刷新按鈕或者f5,如果參數為true,強制刷新(Ctrl+f5) |
1.location.assign()
var btn = document.querySelector('button');
btn.addEventListener('click', function () {location.assign('http://www.itcast.cn');
})
記錄瀏覽歷史,可以實現后退功能
2.location.replace()
var btn = document.querySelector('button');
btn.addEventListener('click', function () {location.replace('http://www.itcast.cn');
})
不記錄瀏覽歷史,不可以實現后退功能
3.location.reload();
location.reload();
重新加載,也就是刷新,如果參數是true,則強制刷新
(5)navigator對象
navigator對象包含有關瀏覽器的信息,有很多屬性,最常用的是userAgent,該屬性可以返回有客戶機發送服務器的user—-agent頭部的值。
下面前端代碼可以判斷用戶那個中斷打開頁面,實現跳轉
if(navigator.userAgent.match(/phone|pad|pod|iPod|ios|ipad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowserNG|WebOS|Symbian|Windows Phone)/i))) {window.location.href = "";//手機
}
else {window.location.href = "";//電腦
}
(6)history對象
window對象給我們提供了一個history對象,與瀏覽器歷史記錄進行交互。該對象包含用戶(在瀏覽器窗口中)訪問過的URL。
history對象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前進功能 |
go(參數) | 前進后退功能,如果參數是1,前進一個頁面,如果參數是-1,后退一個頁面 |
1.back()
模擬后退功能
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.back()
})
2.forward()
模擬前進功能
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.forward()
})
3.go()
模擬前進和后退
前進:
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.go(1)
})
后退:
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.go(-1)
})
?history對象一般在實際開發中比較少用,但是會在一下辦公系統中見到。
?