ECMAScript《JavaScript 闯关记》之 BOM

ECMAScript 是 JavaScript 的核心,但假如一旦在 Web 中使 JavaScript,那么
BOM(浏览器对象模型)则真切才是确实的基本。BOM
提供了成百上千目标,用于访问浏览器的效益,这些力量跟另外网页内容无关。多年来,缺少事实上的正统导致
BOM 有为数不少问题,因为浏览器提供商会按照各自的想法随意去扩大其。W3C
为了将浏览器被 JavaScript 最基本的一部分条件,已经将 BOM
的要害方面纳入了 HTML5 的正规化中。

window 对象

BOM 的为主目标是 window,它意味着浏览器的一个实例。在浏览器被,window
对象来还角色,它既是是经过 JavaScript 访问浏览器窗口的一个接口,又是
ECMAScript 规定的 Global
对象。这意味着在网页中定义的其他一个对象、变量和函数,都为 window
作为其 Global 对象,因此有且访问
isNaN()isFinite()parseInt()parseFloat() 等方法。

大局作用域

由于 window 对象又装着 ECMAScript 中 Global
对象的角色,因此具有以大局作用域中宣示的变量、函数都见面化为 window
对象的性质和方法。来拘禁下的例子。

var age = 29;
function sayAge(){
    console.log(this.age);
}

console.log(window.age);    // 29
sayAge();                   // 29
window.sayAge();            // 29

弃全局变量会成 window 对象的属性不摆,定义全局变量与在 window
对象及一直定义属性还是生一些区别:全局变量不能够由此 delete
运算符删除,而直白以 window 对象及之概念之属性可以。例如:

var age = 29;
window.color = "red";

// 在 IE < 9 时抛出错误,在其他所有浏览器中都返回 false 
delete window.age;

// 在 IE < 9 时抛出错误,在其他所有浏览器中都返回 true
delete window.color;        // return true

console.log(window.age);    // 29
console.log(window.color);  // undefined

使用 var 语词添加的 window 属性有一个曰吧 Configurable
的特点,这个特性的价为默认设置为 false,因此这样定义之属性不得以经过
delete 运算符删除。IE8 及重新早版本在碰到使用 delete 删除 window
属性的口舌时,不管该属性最初是安创造的,都见面扔来荒唐,以显示警告。IE9
及重新强版本不会见丢来错误。

另外,还要记住一起事:尝试看未声明的变量会扔来错误,但是经过查询
window 对象,可以理解某个可能不声明的变量是否在。例如:

// 这里会抛出错误,因为 oldValue 未定义
var newValue = oldValue;

// 这里不会抛出错误,因为这是一次属性查询
// newValue 的值是 undefined
var newValue = window.oldValue;

窗口关系和框架

如若页面中含有框架,则每个框架还备好的 window 对象,并且保留于
frames 集合中。在 frames
集合中,可以经数值索引(从0开始,从漏洞百出到右,从上到下)或者框架名称来走访相应的
window 对象。每个 window 对象还有一个 name
属性,其中蕴蓄框架的称。下面是一个含有框架的页面:

<html>
    <head>
        <title>Frameset Example</title>
    </head>
    <frameset rows="160,*">
        <frame src="frame.htm" name="topFrame">
        <frameset cols="50%,50%">
            <frame src="anotherframe.htm" name="leftFrame">
            <frame src="yetanotherframe.htm" name="rightFrame">
        </frameset>
    </frameset>
</html>

本着之例子而言,可以通过 window.frames[0] 或者
window.frames["topFrame"] 来引用上方的框架。不过最好好下 top 而非
window 来引用这些框架(例如 top.frames[0]),因为 top
对象始终对准最高(最外)层的框架,也便是浏览器窗口。使用她可包以一个框架中是地走访另一个框架。因为对此当一个框架中编的外代码来说,其中的
window 对象对的都是异常框架的一定实例,而不最高层的框架。

top 相对的其它一个 window 对象是
parent。顾名思义,parent(父)对象始终对准当前框架的直白上层框架。在少数情况下,parent
有或相当 top;但当没框架的景下,parent 一定当
top(此时她都等 window)。

跟框架有关的结尾一个靶是 self,它始终指向 window;实际上,self
window 对象可以交换使用。引入 self 对象的目的仅仅是为了和 top
parent 对象对应起来,因此它不坏包含其他价值。

持有这些目标还是 window 对象的习性,可以通过
window.parentwindow.top
等花样来走访。同时,这为象征可以拿不同层次之 window
对象连缀起来,例如 window.parent.parent.frames[0]

在应用框架的状况下,浏览器被见面在多个 Global
对象。在每个框架中定义之全局变量会自行变成框架中 window
对象的性质。由于每个 window
对象还含原生类型的构造函数,因此每个框架还起同一仿好之构造函数,这些构造函数一一对应,但连无等于。例如,top.Object
并不等于 top.frames[0].Object。这个问题会见影响及对越框架传递的对象下
instanceof 运算符。

导航和开辟窗口

使用 window.open() 方法既可导航及一个特定的
URL,也得打开一个初的浏览器窗口。这个艺术好接纳4个参数:要加载的URL、窗口目标、一个特征字符串以及一个意味着初页面是否代表浏览器历史记录中即加载页面的布尔值。通常就须传递第一个参数,最后一个参数就在匪打开新窗口的情形下下。

如果为 window.open()
传递了次独参数,而且该参数是曾生窗口或者框架的称号,那么即便会见于备该名的窗口还是框架中加载第一个参数指定的
URL。看下的例子。

// 等同于 <a href="http://shijiajie.com" target="newWindow"></a>
window.open("http://shijiajie.com/", "newWindow");

弹来窗口

如果给 window.open()
传递的次只参数并无是一个已有的窗口还是框架,那么该办法就见面基于在第三单参数位置及传出的字符串创建一个新窗口还是新标签页。如果无传来第三个参数,那么就是见面打开一个分包任何默认设置(工具栏、地址栏和状态栏等)的初浏览器窗口(或者打开一个新标签页)。在未打开新窗口的情景下,会忽视第三单参数。

老三独参数是一个逗号分隔的装字符串,表示在新窗口中都显示怎么特点。下表列出了足以出现于此字符串中之设置选项。

设置 说明
fullscreen yes或no 表示浏览器窗口是否最大化。仅限IE
height 数值 表示新窗口的高度。不能小于100
left 数值 表示新窗口的左坐标。不能是负值
location yes或no 表示是否在浏览器窗口中显示地址栏。不同浏览器的默认值不同。如果设置为no,地址栏可能会隐藏,也可能会被禁用(取决于浏览器)
menubar yes或no 表示是否在浏览器窗口中显示菜单栏。默认值为no
resizable yes或no 表示是否可以通过拖动浏览器窗口的边框改变其大小。默认值为no
scrollbars yes或no 表示如果内容在视口中显示不下,是否允许滚动。默认值为no
status yes或no 表示是否在浏览器窗口中显示状态栏。默认值为no
toolbar yes或no 表示是否在浏览器窗口中显示工具栏。默认值为no
top 数值 表示新窗口的上坐标。不能是负值
width 数值 表示新窗口的宽度。不能小于100

立即行代码会打开一个新的可以调大小的窗口,窗口开大小为400×400像从,并且距离屏幕及沿同左各10如从。

window.open("http://shijiajie.com/","newWindow",
    "height=400,width=400,top=10,left=10,resizable=yes");

window.open() 方法会返回一个针对性新窗口的援。引用的对象与任何
window
对象约相像,但咱得以本着那开展再多控制。例如,有些浏览器在默认情况下或未允许我们针对主浏览器窗口调整大小或者运动位置,但却许我们对通过window.open()创建的窗口调整大小要挪动位置。通过这个返回的对象,可以像操作其他窗口同样操作新开拓的窗口,如下所示。

var win = window.open("http://shijiajie.com/","newWindow",
    "height=400,width=400,top=10,left=10,resizable=yes");

// 调整大小
win.resizeTo(500,500);

// 移动位置
win.moveTo(100,100);

// 关闭窗口
win.close();

但是,close() 方法就适用于经过 window.open()
打开的弹奏有窗口。对于浏览器的主窗口,如果没有取得用户之允许是勿可知关闭它的。

新创办的 window 对象有一个 opener
属性,其中保存在打开它的原来窗口对象。这个特性只当弹有窗口被的尽外层
window 对象(top)中生定义,而且针对调用 window.open()
的窗口还是框架。例如:

var win = window.open("http://shijiajie.com/","newWindow",
    "height=400,width=400,top=10,left=10,resizable=yes");

console.log(win.opener === window);   // true

虽弹来窗口中发生一个指南针指向打开它的原始窗口,但土生土长窗口中并没有这样的指针指为弹来窗口。窗口并无跟记录其打开的弹奏有窗口,因此我们只好以必要的时自己来手动实现跟踪。

弹来窗口屏蔽程序

都有一段时间,广告商在网上以弹有窗口上了肆无忌惮的档次。他们经常把弹有窗口打扮变成网对话框的长相,引诱用户失去点击其中的广告。由于看起像是系统对话框,一般用户很麻烦识别是的确是假。为了缓解者题材,大多数浏览器内置有弹来窗口屏蔽程序,将大部分用户不思量看到弹出窗口屏蔽掉。

遂,在弹来窗口于挡住时,就当考虑少种植可能性。如果是浏览器内置的屏蔽程序阻止的弹奏有窗口,那么
window.open() 很可能会见返回
null,如果是浏览器扩展或外程序阻止的弹奏有窗口,那么 window.open()
通常会扔来一个错误。因此,要惦记准确地检测出弹出窗口是否为挡住,必须在检测返回值的以,将对准
window.open() 的调用封装在一个 try-catch 块中,如下所示。

var blocked = false;

try {
    var win = window.open("http://shijiajie.com", "_blank");
    if (win == null){
        blocked = true;
    }
} catch (ex){
    blocked = true;
}
if (blocked){
    console.log("The popup was blocked!");
}

暂停调用和过调用

JavaScript
是单线程语言,但其同意通过设置超时值和刹车时间价值来调度代码在特定的时刻执行。前者是于指定的辰后执行代码,而后者则是各级隔指定的时间即实行同样次代码。

逾期调用需要以 window 对象的 setTimeout()
方法,它接受两只参数:要推行之代码和以毫秒表示的年华(即以执行代码前用等待多少毫秒)。其中,第一只参数可以是一个涵盖
JavaScript 代码的字符串(就与在 eval()
函数吃利用的字符串一样),也得以是一个函数。例如,下面对 setTimeout()
的个别次等调整用都见面在同等秒钟后出示一个警告框。

// 不建议传递字符串
setTimeout("console.log('Hello world!') ", 1000);

// 推荐的调用方式
setTimeout(function() { 
    console.log("Hello world!"); 
}, 1000);

虽然就点儿种调用方式都不曾问题,但由于传递字符串可能引致性损失,因此无建议为字符串作为第一独参数。

仲独参数是一个表示等多长时间的毫秒数,但经该日后指定的代码不肯定会尽。JavaScript
是一个单线程序的解释器,因此一定时间外只能执行同一段子代码。为了控制而实施之代码,就出一个
JavaScript
任务队列。这些职责会仍用它们增长到队的逐条执行。setTimeout()
的第二只参数告诉 JavaScript
再过多长时间把当前任务添加到行列中。如果队列是拖欠的,那么长的代码会即时执行;如果队列不是拖欠的,那么它们将等前的代码执行完了后头又履行。

调用 setTimeout() 之后,该方法会返回一个数值
ID,表示过调用。这个超时调用 ID
是计划实施代码的唯一标识符,可以通过其来取消超时调用。要撤销尚未履行的晚点调用计划,可以调用
clearTimeout() 方法并以相应的超时调用 ID
作为参数传递给它们,如下所示。

// 设置超时调用
var timeoutId = setTimeout(function() {
    console.log("Hello world!");
}, 1000);

// 注意:把它取消
clearTimeout(timeoutId);

倘若是于指定的时从没过去之前调用
clearTimeout(),就可了取消超时调用。前面的代码在安装过调用之后马上还要调用了
clearTimeout(),结果虽跟什么啊未尝生出同样。

暂停调用与过调用类似,只不过它见面依照指定的年华间隔重复执行代码,直至间歇调用被注销或页面被卸载。设置间歇调用的计是
setInterval(),它承受之参数与 setTimeout()
相同:要实践之代码(字符串或函数)和每次执行前需要等的毫秒数。下面来拘禁一个例。

// 不建议传递字符串
setInterval ("console.log('Hello world!') ", 10000);

// 推荐的调用方式
setInterval (function() { 
    console.log("Hello world!"); 
}, 10000);

调用 setInterval() 方法同样为会见回一个抛锚调用 ID,该 ID
可用于在将来某个时刻取消间歇调用。要注销尚未施行的刹车调用,可以下
clearInterval() 方法并传到相应的暂停调用
ID。取消间歇调用的根本要远远盖取消超时调用,因为在无加以干预的动静下,间歇调用将会见直接执行到页面卸载。以下是一个广泛的运用间歇调用的例证。

var num = 0;
var max = 10;
var intervalId = null;

function incrementNumber() {
    num++;
    // 如果执行次数达到了max设定的值,则取消后续尚未执行的调用
    if (num == max) {
        clearInterval(intervalId);
        console.log("Done");
    }
}

intervalId = setInterval(incrementNumber, 500);

每当是事例中,变量num每半秒钟递增一差,当递增到绝可怜价值时就是会见取消以前设定的间歇调用。这个模式也得采用过调用来促成,如下所示。

var num = 0;
var max = 10;

function incrementNumber() {
    num++;

    // 如果执行次数未达到max设定的值,则设置另一次超时调用
    if (num < max) {
        setTimeout(incrementNumber, 500);
    } else {
        console.log("Done");
    }
}

setTimeout(incrementNumber, 500);

看得出,在使过调用时,没有必要跟超时调用
ID,因为每次执行代码之后,如果不再设置任何一样蹩脚过调用,调用就见面活动停止。一般认为,使用过期调用来法间歇调用的是千篇一律种植超级模式。在开发环境下,很少用确的间歇调用,原因是继一个间断调用可能会见以面前一个抛锚调用了之前启动。而例如前示例中那么采用过调用,则净好避这一点。所以,最好不要动间歇调用。

系统对话框

浏览器通过 alert()confirm()prompt()
方法可调用系统对话框向用户展示信息。系统对话框与以浏览器中展示的网页没有关系,也不含有
HTML。它们的外观由操作系统及(或)浏览器设置决定,而非是出于 CSS
决定。此外,通过就几乎单办法打开的对话框都是联合同模态的。也就是说,显示这些对话框的当儿代码会已实施,而关闭这些对话框后代码又见面过来执行。

率先栽对话框是调用 alert()
方法生成的。它于用户展示一个系对话框,其中含有指定的文本及一个
OK(“确定”)按钮。通常以 alert()
生成的“警告”对话框向用户展示有他们无法控制的信息,例如错误信息。而用户只能在看罢信息继关对话框。

老二栽对话框是调用 confirm()
方法生成的。从于用户展示信息的点来拘禁,这种“确认”对话框很像是一个“警告”对话框。但双边的要害分在于“确认”对话框除了显示OK按钮外,还见面显一个
Cancel(“取消”)按钮,两单按钮可以于用户决定是否履给定的操作。

为了确定用户是单击了OK还是Cancel,可以检查 confirm()
方法返回的布尔值:true 表示单击了OK,false
表示单击了Cancel或单击了右上比赛的 X 按钮。确认对话框的典型用法如下。

if (confirm("Are you sure?")) {
    alert("I'm so glad you're sure! ");
} else {
    alert("I'm sorry to hear you're not sure.");
}

说到底一种植对话框是经过调用 prompt()
方法生成的,这是一个“提示”框,用于提示用户输入有文书。提示框中除展示
OK 和 Cancel
按钮之外,还见面来得一个文书输入域,以供应用户在里边输入内容。prompt()
方法接受两只参数:要显得为用户的文本提示和文件输入域的默认值(可以是一个空字符串)。

假若用户单击了 OK 按钮,则 promp() 返回文本输入域的价;如果用户单击了
Cancel 或从不单击 OK 而是经外方关闭了对话框,则该方法返回
null。下面是一个例证。

var result = prompt("What is your name? ", "");
if (result !== null) {
    alert("Welcome, " + result);
}

概括,这些体系对话框很抱为用户展示信息并请用户作出决定。由于未涉及
HTML、CSS 或 JavaScript,因此它是增长 Web 应用程序的均等栽便利措施。

location 对象

location
对象提供了和目前窗口被加载的文档有关的信息,还提供了片导航功能。事实上,location
对象是怪特别的一个对象,因为她既是 window 对象的特性,也是 document
对象的属性;换句话说,window.locationdocument.location
引用的是暨一个靶。location
对象的用不只表现在它保存着脚下文档的信息,还表现在其用 URL
解析为单身的部分,让开发人员可以经过不同的性质访问这些有些。下表列出了
location 对象的富有属性。

属性名 例子 说明
hash "#contents" 返回 URL 中的 hash(#号后跟零或多个字符),如果 URL 中不包含散列,则返回空字符串
host "shijiajie.com:80" 返回服务器名称和端口号(如果有)
hostname "shijiajie.com" 返回不带端口号的服务器名称
href "http:/shijiajie.com" 返回当前加载页面的完整URL。而 location 对象的 toString() 方法也返回这个值
pathname "/WileyCDA/" 返回URL中的目录和(或)文件名
port "8080" 返回 URL 中指定的端口号。如果 URL 中不包含端口号,则这个属性返回空字符串
protocol "http:" 返回页面使用的协议。通常是 http: 或 https:
search "?q=javascript" 返回URL的查询字符串。这个字符串以问号开头

询问字符串参数

尽管经过地方的性能可以看到 location
对象的大多数信,但内部顾URL包含的查询字符串的特性并无便宜。尽管
location.search 返回从问号到 URL
末尾的保有内容,但却没有主意逐个看中的每个查询字符串参数。为是,可以像下这样创建一个函数,用以分析查询字符串,然后回来包含有参数的一个对象:

/*
 * 这个函数用来解析来自URL的查询串中的name=value参数对
 * 它将name=value对存储在一个对象的属性中,并返回该对象
 * 这样来使用它
 *
 * var args = urlArgs(); // 从URL中解析参数
 * var q = args.q || ""; // 如果参数定义了的话就使用参数;否则使用一个默认值
 * var n = args.n ? parseInt(args.n) : 10;
 */
function urlArgs() {
    var args = {};                                  // 定义一个空对象
    var query = location.search.substring(1);       // 查找到查询串,并去掉'? '
    var pairs = query.split("&");                   // 根据"&"符号将查询字符串分隔开
    for (var i = 0; i < pairs.length; i++) {        // 对于每个片段
        var pos = pairs[i].indexOf('=');            // 查找"name=value"
        if (pos == -1) continue;                    // 如果没有找到的话,就跳过
        var name = pairs[i].substring(0, pos);      // 提取name
        var value = pairs[i].substring(pos + 1);    // 提取value
        value = decodeURIComponent(value);          // 对value进行解码
        args[name] = value;                         // 存储为属性
    }
    return args;                                    // 返回解析后的参数
}

职务操作

使用 location
对象好经过广大计来转浏览器的职。首先,也是最最常用的不二法门,就是行使
assign()主意并为那个传递一个 URL,如下所示。

location.assign("http://shijiajie.com");

如此,就得马上打开新URL并以浏览器的历史记录中生成一长长的记下。如果是用
location.hrefwindow.location 设置为一个URL值,也会见因为该值调用
assign() 方法。例如,下列两尽代码和显式调用 assign()
方法的功能了等同。

window.location = "http://shijiajie.com";
location.href = "http://shijiajie.com";

在这些反浏览器位置的措施吃,最常用的凡安装 location.href 属性。

另外,修改 location
对象ECMAScript的别样属性为足以变更目前加载的页面。下面的例子展示了经过以
hashsearchhostnamepathnameport 属性设置也新值来转
URL。

// 假设初始 URL 为 http://shijiajie.com/about/
location.href = "http://shijiajie.com/about/"

// 将 URL 修改为 "http://shijiajie.com/about/#ds-thread"
location.hash = "#ds-thread";

// 将 URL 修改为 "http://shijiajie.com/about/?args=123"
location.search = "?args=123";

// 将 URL 修改为 "https://segmentfault.com/"
location.hostname = "segmentfault.com";

// 将 URL 修改为 "http://segmentfault.com/u/stone0090/"
location.pathname = "u/stone0090";

// 将 URL 修改为 "https://segmentfault.com:8080/"
location.port = 8080;

当通过上述任何一样栽办法修改URL之后,浏览器的历史记录中尽管会见坏成一长长的新记录,因此用户通过单击“后退”按钮都见面导航及前面一个页面。要禁用这种作为,可以利用
replace() 方法。这个主意才受一个参数,即如导航及之
URL;结果虽然会导致浏览器位置变动,但非会见以历史记录中生成新记录。在调用
replace() 方法后,用户不克回前一个页面,来拘禁下面的例证:

<!DOCTYPE html>
<html>
<head>
    <title>You won't be able to get back here</title>
</head>
    <body>
    <p>Enjoy this page for a second, because you won't be coming back here.</p>
    <script type="text/javascript">
        setTimeout(function () {
            location.replace("http://shijiajie.com/");
        }, 1000);
    </script>
</body>
</html>

设用这页面加载到浏览器被,浏览器就是会当1秒钟后重新定向到
shijiajie.com。然后,“后退”按钮将处禁用状态,如果无又输入完的
URL,则无从赶回示例页面。

与职务有关的末梢一个措施是
reload(),作用是重新加载当前形的页面。如果调用 reload()
时不传递任何参数,页面就见面以最实惠的方还加载。也就是说,如果页面自上次请以来并从未改观过,页面就会见自浏览器缓存中再次加载。如果如强制从服务器又加载,则需像下这样为该措施传递参数
true

location.reload();        // 重新加载(有可能从缓存中加载)
location.reload(true);    // 重新加载(从服务器重新加载)

位于 reload()
调用之后的代码可能会见呢可能无会见执行,这如取决于网络延迟或系统资源等因素。为之,最好以
reload() 放在代码的最终一行。

history 对象

history 对象保存着用户上网的历史记录,从窗口于辟的那么一刻终于打。因为
historywindow
对象的性能,因此每个浏览器窗口、每个标签页乃至每个框架,都生好之
history 对象及特定的 window
对象关联。出于安全者的考虑,开发人员无法获悉用户浏览过的
URL。不过,借由用户访问了之页面列表,同样可在非清楚实际 URL
的事态下实现后降及进化。

使用 go()
方法可当用户的历史记录中随意跳转,可以为后呢得进。这个法子接受一个参数,表示于后抑上跳转的页面数的一个整数值。负数表示向后过反(类似于单击浏览器的“后退”按钮),正数表示向前跳转(类似于单击浏览器的“前进”按钮)。来拘禁下的例证。

// 后退一页
history.go(-1);

// 前进一页
history.go(1);

// 前进两页
history.go(2);

呢可吃 go()
方法传递一个字符串参数,此时浏览器会跨反到历史记录中包含该字符串的第一只位置——可能后退,也恐怕发展,具体要扣何人岗位最近。如果历史记录中莫分包该字符串,那么是方式什么啊非举行,例如:

// 跳转到最近的 shijiajie.com 页面
history.go("shijiajie.com");

另外,还足以下简单个简写方法 back()forward() 来代替
go()。顾名思义,这点儿只方式好学浏览器的“后退”和“前进”按钮。

// 后退一页
history.back();

// 前进一页
history.forward();

除上述几单办法外,history 对象还有一个 length
属性,保存着历史记录的数据。这个数包括拥有历史记录,即具有为后与前进的笔录。对于加载到窗口、标签页或框架中之第一个页面而言,history.length
等于0。通过像下这样测试该属性的值,可以规定用户是否一致开始便打开了卿的页面。

if (history.length == 0){
    //这应该是用户打开窗口后的第一个页面
}

虽然 history
并无常用,但当创建于定义之“后退”和“前进”按钮,以及检测时页面是未是用户历史记录中的率先独页面时,还是得利用它们。

小结

BOM(浏览器对象模型)以 window
对象啊依托,表示浏览器窗口及页面可见区域。同时,window 对象或
ECMAScript 中的 Global
对象,因而有全局变量和函数都是它们的习性,且有原生的构造函数及其他函数也都是为她的命名空间下。本章讨论了下列
BOM 的有。

  • 每当运框架时,每个框架都起自己之 window
    对象同具有原生构造函数及其他函数的副本。每个框架还封存在 frames
    集合中,可以通过岗位或通过名称来拜访。
  • 发出局部窗口指针,可以用来引用其他框架,包括大框架。
  • top 对象始终本着最外侧之框架,也尽管是全部浏览器窗口。
  • parent 对象表示包含当前框架的框架,而 self 对象则回指 window
  • 使用 location
    对象好经过编程方式来聘浏览器的导航系统。设置相应的习性,可以逐段或整体性地改浏览器的
    URL。
  • 调用 replace() 方法可以导航及一个新 URL,同时该 URL
    会替换浏览器历史记录中时形的页面。
  • navigator
    对象提供了与浏览器有关的消息。到底提供什么样信息,很怪程度达到取决用户的浏览器;不过,也发生一些国有的性质(如
    userAgent)存在叫具有浏览器中。

BOM中还有个别单目标:screenhistory,但她的作用有限。screen
对象中保留在和客户端显示器有关的音讯,这些信息一般只是用于站点分析。history
对象呢访浏览器的历史记录开了一个小缝隙,开发人员可以为此判断历史记录的多寡,也得以以历史记录中往后或上导航及任意页面。

关卡

// 挑战一
setTimeout(function () {
    console.log("1");
}, 0)
console.log("2");   // ???

// 挑战二
for (var i = 0;i<5;i++) {
    setTimeout(function () {
        console.log(i);     // ???
    }, 0)
};

// 挑战三
var a = 1;
var obj = {
    a : 2,
    b : function(){
        setTimeout(function () {
            console.log(this.a);
        }, 0)
    }
}
obj.b();    // ???

// 挑战四
var a = 1;
var obj = {
    a : 2,
    b : function(){
        setTimeout(function () {
            console.log(this.a);
        }.call(this), 0);
    }
}
obj.b();    // ???

更多

关爱微信公众号「劼哥舍」回复「答案」,获取关卡详解。
关注
https://github.com/stone0090/javascript-lessons,获取最新动态。