在 JavaScript 中,BOM(Browser Object Model)指的是浏览器对象模型,它是一种用于表示和操作浏览器窗口、文档、历史记录等对象的模型。BOM 是 JavaScript 在浏览器环境中的核心组成部分,它与 DOM(文档对象模型)一起构成了 Web 开发的基石。BOM的分类window 对象:表示浏览器窗口,包含许多属性和方法,如 alert()、confirm()、prompt() 等。window 对象是 BOM 的核心,它代表了整个浏览器窗口,并且是所有其他 BOM 对象的父对象。history 对象:表示浏览器历史记录,包含许多属性和方法,如 back()、forward()、go() 等。history 对象使得 JavaScript 能够访问和操作浏览器的历史记录,从而实现页面导航功能。navigator 对象:表示浏览器的信息,包含许多属性和方法,如 appName、appVersion、platform 等。navigator 对象使得 JavaScript 能够获取浏览器的相关信息,从而实现浏览器检测功能。screen 对象:表示客户端屏幕的信息,包含许多属性和方法,如 width、height、availWidth 等。screen 对象使得 JavaScript 能够获取客户端屏幕的相关信息,从而实现页面布局功能。location 对象:表示当前页面的 URL 信息,包含许多属性和方法,如 href、protocol、host 等。location 对象使得 JavaScript 能够访问和操作当前页面的 URL,从而实现页面跳转功能。>Navigator用来表示浏览器的相关信息userAgent 返回一个用来描述浏览器信息的字符串<script> // console.log(navigator.userAgent) let sBrowser; const sUsrAg = navigator.userAgent; // The order matters here, and this may report false positives for unlisted browsers. if (sUsrAg.indexOf("Firefox") > -1) { sBrowser = "Mozilla Firefox"; // "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0" } else if (sUsrAg.indexOf("SamsungBrowser") > -1) { sBrowser = "Samsung Internet"; // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36 } else if (sUsrAg.indexOf("Opera") > -1 || sUsrAg.indexOf("OPR") > -1) { sBrowser = "Opera"; // "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 OPR/57.0.3098.106" } else if (sUsrAg.indexOf("Trident") > -1) { sBrowser = "Microsoft Internet Explorer"; // "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; Zoom 3.6.0; wbx 1.0.0; rv:11.0) like Gecko" } else if (sUsrAg.indexOf("Edge") > -1) { sBrowser = "Microsoft Edge (Legacy)"; // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299" } else if (sUsrAg.indexOf("Edg") > -1) { sBrowser = "Microsoft Edge (Chromium)"; // Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64 } else if (sUsrAg.indexOf("Chrome") > -1) { sBrowser = "Google Chrome or Chromium"; // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/66.0.3359.181 Chrome/66.0.3359.181 Safari/537.36" } else if (sUsrAg.indexOf("Safari") > -1) { sBrowser = "Apple Safari"; // "Mozilla/5.0 (iPhone; CPU iPhone OS 11_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Mobile/15E148 Safari/604.1 980x1306" } else { sBrowser = "unknown"; } alert(`You are using: ${sBrowser}`); </script>>Location 表示浏览器地址的详细信息location.assign( ) 跳转到一个新的地址location.replace( ) 跳转新的地址(无法回退)location.reload( ) 刷新页面,可以通过 true 来刷新缓存location.href( ) 获取当前地址 <button id=“btn”> 点我一下 </button><script> const btn = document.getElementById("btn") btn.addEventListener("click", () => { // console.log(location.href) // location = "https://w-flac.org.cn" // location.assign("https://w-flac.org.cn") // location.replace("https://w-flac.org.cn") location.reload(true) }) </script>>History表示浏览器的历史记录history.back( ) 回退按钮history.forward ( ) 前进按钮history.go( ) 向前或向后<button id=“btn”> 点我一下 </button><script> const btn = document.getElementById("btn") btn.onclick = () => { // console.log(history.length) // history.back() // history.forward() history.go(-1) } </script>>定时器通过定时器可以使代码在指定时间后执行setTimeout( ) 代码只执行一次参数:回调函数间隔的时间关闭定时器:clearTimeout( )<script> const timer = setTimeout(()=>{ alert("我是定时器中的代码") }, 3000) clearTimeout(timer) </script>setInterval( ) 代码每间隔一段时间执行一次参数:回调函数间隔的时间关闭定时器:clearInterval( )<h1 id="num"></h1><script> const numH1 = document.getElementById("num"); let num = 0; const timer = setInterval(() => { num++; numH1.textContent = num; if (num === 200) { clearInterval(timer); } }, 30); </script>>事件循环(event loop)在函数每次执行时,都会产生一个新的执行环境;执行环境负责存储函数执行时产生的一切数据。Q:函数的执行环境要存储到哪里呢?A:函数的执行环境存储到了一个叫做调用栈的地方。栈,是一种数据结构,特点:后进先出;队列,也是一种数据结构,特点:先进先出。调用栈(call stack)调用栈负责存储函数的执行环境。当一个函数被调用时,它的执行环境会作为一个栈帧;当插入到调用栈的栈顶,函数执行完毕时,其栈帧会自动从栈中弹出。<script> function fn() { let a = 10 let b = 20 function fn2() { console.log("fn2") } fn2() console.log("fn~") } fn() console.log(1111) </script>消息列队消息队列负责存储将要执行的函数。当我们触发一个事件时,其响应函数并不是直接就添加到调用栈中的,因为调用栈中有可能会存在一些还没有执行完的代码。事件触发后,JS 引擎是将事件响应函数插入到消息列队中排队。<button id=“btn”> 点我一下 </button> <button id="btn02">点我一下2</button></script> const btn = document.getElementById("btn") const btn02 = document.getElementById("btn02") btn.onclick = function () { alert(1111) const begin = Date.now() while (Date.now() - begin < 3000) {} } btn02.onclick = function () { alert(2222) } </script>而定时器的本质的就是在指定时间后,将函数添加到消息队列中<script> // console.time() // setTimeout(function(){ // console.timeEnd() // console.log("定时器执行了~") // }, 3000) // 使程序卡6s // const begin = Date.now() // while (Date.now() - begin < 6000) {} /* setInterval() 每间隔一段时间就将函数添加到消息队列中 但是如果函数执行的速度比较慢,它是无法确保每次执行的间隔都是一样的 */ // console.time("间隔") // setInterval(function(){ // console.timeEnd("间隔") // // console.log("定时器执行了~~") // alert("定时器执行~") // console.time("间隔") // }, 3000) /* 希望可以确保函数每次执行都有相同间隔 */ // console.time("间隔") // setTimeout(function fn() { // console.timeEnd("间隔") // alert("哈哈") // console.time("间隔") // // 在setTimeout的回调函数的最后,在调用一个setTimeout // setTimeout(fn, 3000) // }, 3000) setTimeout(()=>{ console.log(11111) }, 0) console.log(222222) </script>