Github_web_2

五十三:请解释 JavaScript 中 this 是如何工作的。
1.方法调用模式
当一个函数被保存为一个对象的属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。如果调用表达式包含一个提取属性的动作(即包含一个 . 点表达式或[subscript]下标表达式),那么它就是被当做一个方法来调用。
2.函数调用模式
当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的:以此模式调用函数时,this被绑定到全局对象。
3.构造器调用模式
一个函数,如果创建的目的就是希望结合new前缀来调用,那它就被称为构造器函数。按照约定,它们保存在以大写格式命名的变量里。如果调用构造器函数时没有在前面加上new,可能会发生非常糟糕的事情,既没有编译时警告,也没有运行时警告,所以大写约定非常重要。如果在一个函数面前带上new来调用,那么背地里将会创建一个连接到该函数的prototype成员的新对象(新对象为构造函数的一个实例),同时this会被绑定到那个新对象上。
4.Apply调用模式
因为javascript是一门函数式的面向对象编程语言,所以函数可以拥有方法。apply方法让我们构建一个参数数组传递给调用函数。它允许我们选择this的值。apply方法接收两个参数,第1个是要绑定给this的值,第2个就是一个参数数组。call方法与apply类似,将apply第二参数拆开为单个的参数。

五十四:请解释原型继承 (prototypal inheritance) 的原理。
由于所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样。

五十五:你怎么看 AMD vs. CommonJS?
CommonJs 是服务器端模块的规范,Node.js采用了这个规范。根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。
//require方法默认读取js文件,所以可以省略js后缀var test = require('./boobar').foobar; //test为boobar文件中的foobar对象的实例test.bar();//调用方法bar()
CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。
AMD CMD 采用异步模式,方便浏览器环境要从服务器加载模块。AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。AMD异步加载模块。它的模块支持对象、函数、构造器、字符串、JSON等各种类型的模块。适用AMD规范适用define方法定义模块。
//通过数组引入依赖 ,回调函数通过形参传入依赖define(['someModule1', ‘someModule2’], function (someModule1, someModule2) { function foo () { /// something someModule1.test(); } return {foo: foo}});

五十六:请解释为什么接下来这段代码不是 IIFE (立即调用的函数表达式):function foo(){ }();.
以function关键字开头的语句会被解析为函数声明,而函数声明是不允许直接运行的。
只有当解析器把这句话解析为函数表达式,才能够直接运行,怎么办呢?以运算符开头就可以了——

五十七:描述以下变量的区别:null,undefined 或 undeclared?
null表示"没有对象",即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
Object.getPrototypeOf(Object.prototype)
// null
undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。

var i;
i // undefined
function f(x){console.log(x)}
f() // undefined
var  o = new Object();
o.p // undefined
var x = f();
x // undefined
'undefined'是未定义,在变量没有赋值的时候的值即为undefined。
'underclared'即为被污染的命名,访问没有被声明的变量,会抛出异常,终止执行。
'null'是一个空的对象引用

五十八:什么是闭包,如何使用它,为什么要使用它?
当某个函数调用时会创建一个执行环境以及作用域链,然后根据arguments和其它命名参数初始化形成活动对象。在外部函数调用结束后,其执行环境与作用域链被销毁,但是其活动对象保存在了闭包之中,最后在闭包函数调用结束后才销毁。简单的说,闭包就是能够读取其他函数内部变量的函数。
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
//第1种写法 :这种写法没什么特别的,只是给函数添加一些属性。

function Circle(r) {   
    this.r = r;  
}  
Circle.PI = 3.14159;  
Circle.prototype.area = function() {   
    return Circle.PI * this.r * this.r;  
}  
var c = new Circle(1.0);     
alert(c.area());    

//第2种写法 :这种写法是声明一个变量,将一个函数当作值赋给变量。

var Circle = function() {     
    var obj = new Object();     
    obj.PI = 3.14159;     
    obj.area = function( r ) {  
      return this.PI * r * r;     
      }     
    return obj;  
}    
var c = new Circle();  
alert( c.area( 1.0 ) );   

//第3种写法 :这种方法最好理解,就是new 一个对象,然后给对象添加属性和方法。

var Circle = new Object();  
Circle.PI = 3.14159;  
Circle.Area = function( r ) {      
    return this.PI * r * r;  
}  
alert( Circle.Area( 1.0 ) );   

//第4种写法 :这种方法使用较多,也最为方便。

var obj = {}就是声明一个空的对象。
var Circle={     
    "PI":3.14159,   
    "area":function(r){   
        return this.PI * r * r;  
    }  
};  
alert( Circle.area(1.0) );  

闭包的用途

事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。

1)匿名自执行函数

全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的)。

除了每次使用变量都是用var关键字外,我们在实际情况下经常遇到这样一种情况,即有的函数只需要执行一次,其内部变量无需维护,我们可以使用闭包。

我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在函数执行完后会立刻释放资源,关键是不污染全局对象。

2)结果缓存

我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。

3)封装

4)实现类和继承

你喜欢的使用闭包的模式是什么?两种模式用在不同场合。参见jQuery源码,立即调用模式,把$的jQuery源码放在了全局作用域下。返回函数类型的,制作一个随时可以使用的函数。

五十九:请举出一个匿名函数的典型用例?

$.("input").each(
    function(e){
        this.val('OK')
    }
);

六十:你是如何组织自己的代码?是使用模块模式,还是使用经典继承的方法?
在模块模式中使用继承。例如我们的库中有pannel布局型组件和data型组件,其余都依照这两个基本组件继承而来。

六十一:请指出 JavaScript 宿主对象 (host objects) 和原生对象 (native objects) 的区别?
1、原生对象
ECMA-262 把原生对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”。
Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError、ActiveXObject(服务器方面)、Enumerator(集合遍历类)、RegExp(正则表达式)
由此可以看出,简单来说,原生对象就是 ECMA-262 定义的类(引用类型)。
2、内置对象
ECMA-262 把内置对象(built-in object)定义为“由 ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现”。这意味着开发者不必明确实例化内置对象,它已被实例化了。
同样是“独立于宿主环境”。根据定义我们似乎很难分清“内置对象”与“原生对象”的区别。而ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是原生对象,根据定义,每个内置对象都是原生对象)。
如此就可以理解了。内置对象是原生对象的一种。而其包含的两种对象中,Math对象我们经常用到,可这个Global对象是啥东西呢?
Global对象是ECMAScript中最特别的对象,因为实际上它根本不存在!在ECMAScript中,不存在独立的函数,所有函数都必须是某个对象的方法。
类似于isNaN()、parseInt()和parseFloat()方法等,看起来都是函数,而实际上,它们都是Global对象的方法。而且Global对象的方法还不止这些。
3、宿主对象
何为“宿主对象”? ECMAScript中的“宿主”当然就是我们网页的运行环境,即“操作系统”和“浏览器”。所有非原生对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。
所有的 BOM 和 DOM 对象都是宿主对象。因为其对于不同的“宿主”环境所展示的内容不同。其实说白了就是,ECMAScript官方未定义的对象都属于宿主对象,因为其未定义的对象大多数是自己通过ECMAScript程序创建的对象。TML DOM 是 W3C 标准(是 HTML 文档对象模型的英文缩写,Document Object Model for HTML)。
HTML DOM 定义了用于 HTML 的一系列标准的对象,以及访问和处理 HTML 文档的标准方法。
通过 DOM,可以访问所有的 HTML 元素,连同它们所包含的文本和属性。可以对其中的内容进行修改和删除,同时也可以创建新的元素。

六十二:请指出以下代码的区别:function Person(){}、var person = Person()、var person = new Person()?
1、定义一个函数为Person()  
2、定义一个匿名函数指向person  
3、实例化一个person、原型来自于函数Person

六十三:.call 和 .apply 的区别是什么?
call和apply都是调用一个对象的一个方法,以另一个对象替换当前对象。它们都属于Function.prototype的一个方法,所以每个function实例都有call和apply属性。这两个方法可以用来代替另一个对象调用一个方法,可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。  
区别在于,两者传递的参数不同,虽然函数第一个参数都是要传入给当前对象的对象,但是,apply的第二个参数是一个参数数组,将多个参数组合成为一个数组传入;而call第二个参数则是直接的参数列表。

六十四:请解释 Function.prototype.bind?
bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数的值。
例如,在 f() 函数上调用 bind() 方法并传入参数 obj ,即 f.bind(obj) ,这将返回一个新函数, 新函数会把原始的函数 f() 当做 obj 的方法来调用,就像 obj.f() 似的,当然这时 f() 函数中的 this 对象指向的是 obj 。

Function.prototype.bind = function(scope){
    var fn = this;
    return function(){
        return fn.apply(scope, arguments);
    }
}
var foo = {x: "Foo "};
var bar = function (str) {
    console.log(this.x+(arguments.length===0?'':str));
};
bar();                                   // undefined
var testBindBar = bar.testBind(foo);     // 绑定 foo
testBindBar("Bar!");                     // Foo Bar!

六十五:在什么时候你会使用 document.write()?
加载需要配合JS脚本使用的外部CSS文件
利用下面的语句加载外部样式文件:
<scirpt>
document.write('<link rel="stylesheet" href="style_neads_js.css">');
</script>
将所有需要用到JS的样式都放到这个外部样式表中,如果浏览器不禁用JS,那么该样式表就会被顺利加载,否则页面就不会使用该样式。(Don’t docwrite scripts)
在新的窗口中写入新的页面数据时(新建一个页面就不会重写之前的)
既然在一个已加载完成的页面中调用document.write会重写整个页面,那么在一个新的窗口的空白页面中调用这个方法,就不存在这样的的问题了。
另外,在调用document.write,最好不要把document.open和document.close漏掉,尽管多数时候浏览器会帮忙完成这些操作。即,一个标准的document.write应该是这样的:
document.open();
document.write('anthing')
document.close();
大多数生成的广告代码依旧使用document.write(),虽然这种用法会让人很不爽。

六十六:请指出浏览器特性检测,特性推断和浏览器UA字符串嗅探的区别?
特性检测:为特定浏览器的特性进行测试,并仅当特性存在时即可应用特性。
User-Agent检测:最早的浏览器嗅探即用户代理检测,服务端(以及后来的客户端)根据UA字符串屏蔽某些特定的浏览器查看网站内容。
特性推断:尝试使用多个特性但仅验证了其中之一。根据一个特性的存在推断另一个特性是否存在。问题是,推断是假设并非事实,而且可能导致可维护性的问题。

六十七:请尽可能详尽的解释 Ajax 的工作原理。
5、ajax所包含的技术

大家都知道ajax并非一种新的技术,而是几种原有技术的结合体。它由下列技术组合而成。

1.使用CSS和XHTML来表示。

  1. 使用DOM模型来交互和动态显示。
    3.使用XMLHttpRequest来和服务器进行异步通信。
    4.使用javascript来绑定和调用。
    在上面几中技术中,除了XmlHttpRequest对象以外,其它所有的技术都是基于web标准并且已经得到了广泛使用的,XMLHttpRequest虽然目前还没有被W3C所采纳,但是它已经是一个事实的标准,因为目前几乎所有的主流浏览器都支持它。

6、ajax原理和XmlHttpRequest对象

Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。
 XMLHttpRequest是ajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。
 所以我们先从XMLHttpRequest讲起,来看看它的工作原理。
 首先,我们先来看看XMLHttpRequest这个对象的属性。
  它的属性有:
  onreadystatechange 每次状态改变所触发事件的事件处理程序。
  responseText 从服务器进程返回数据的字符串形式。
  responseXML 从服务器进程返回的DOM兼容的文档数据对象。
  status 从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)
  status Text 伴随状态码的字符串信息
  readyState 对象状态值
    0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
    1 (初始化) 对象已建立,尚未调用send方法
    2 (发送数据) send方法已调用,但是当前的状态及http头未知
    3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,
    4 (完成) 数据接收完毕,此时可以通过通过responseXml和responseText获取完整的回应数据

但是,由于各浏览器之间存在差异,所以创建一个XMLHttpRequest对象可能需要不同的方法。这个差异主要体现在IE和其它浏览器之间。下面是一个比较标准的创建XMLHttpRequest对象的方法。

function CreateXmlHttp() {

    //非IE浏览器创建XmlHttpRequest对象
    if (window.XmlHttpRequest) {
        xmlhttp = new XmlHttpRequest();
    }

    //IE浏览器创建XmlHttpRequest对象
    if (window.ActiveXObject) {
        try {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (e) {
            try {
                xmlhttp = new ActiveXObject("msxml2.XMLHTTP");
            }
            catch (ex) { }
        }
    }
}

function Ustbwuyi() {

    var data = document.getElementById("username").value;
    CreateXmlHttp();
    if (!xmlhttp) {
        alert("创建xmlhttp对象异常!");
        return false;
    }

    xmlhttp.open("POST", url, false);

    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4) {
            document.getElementById("user1").innerHTML = "数据正在加载...";
            if (xmlhttp.status == 200) {
                document.write(xmlhttp.responseText);
            }
        }
    }
    xmlhttp.send();
}

如上所示,函数首先检查XMLHttpRequest的整体状态并且保证它已经完成(readyStatus=4),即数据已经发送完毕。然后根据服务器的设定询问请求状态,如果一切已经就绪(status=200),那么就执行下面需要的操作。
对于XmlHttpRequest的两个方法,open和send,其中open方法指定了:
a、向服务器提交数据的类型,即post还是get。
b、请求的url地址和传递的参数。
c、传输方式,false为同步,true为异步。默认为true。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式。
Send方法用来发送请求。
知道了XMLHttpRequest的工作流程,我们可以看出,XMLHttpRequest是完全用来向服务器发出一个请求的,它的作用也局限于此,但它的作用是整个ajax实现的关键,因为ajax无非是两个过程,发出请求和响应请求。并且它完全是一种客户端的技术。而XMLHttpRequest正是处理了服务器端和客户端通信的问题所以才会如此的重要。
  现在,我们对ajax的原理大概可以有一个了解了。我们可以把服务器端看成一个数据接口,它返回的是一个纯文本流,当然,这个文本流可以是XML格式,可以是Html,可以是Javascript代码,也可以只是一个字符串。这时候,XMLHttpRequest向服务器端请求这个页面,服务器端将文本的结果写入页面,这和普通的web开发流程是一样的,不同的是,客户端在异步获取这个结果后,不是直接显示在页面,而是先由javascript来处理,然后再显示在页面。至于现在流行的很多ajax控件,比如magicajax等,可以返回DataSet等其它数据类型,只是将这个过程封装了的结果,本质上他们并没有什么太大的区别。
7、ajax的优点
Ajax的给我们带来的好处大家基本上都深有体会,在这里我只简单的讲几点:
1、最大的一点是页面无刷新,在页面内与服务器通信,给用户的体验非常好。
  2、使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力。
3、可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
4、基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。

8、ajax的缺点

下面我着重讲一讲ajax的缺陷,因为平时我们大多注意的都是ajax给我们所带来的好处诸如用户体验的提升。而对ajax所带来的缺陷有所忽视。
  下面所阐述的ajax的缺陷都是它先天所产生的。
 1、ajax干掉了back按钮,即对浏览器后退机制的破坏。后退按钮是一个标准的web站点的重要功能,但是它没法和js进行很好的合作。这是ajax所带来的一个比较严重的问题,因为用户往往是希望能够通过后退来取消前一次操作的。那么对于这个问题有没有办法?答案是肯定的,用过Gmail的知道,Gmail下面采用的ajax技术解决了这个问题,在Gmail下面是可以后退的,但是,它也并不能改变ajax的机制,它只是采用的一个比较笨但是有效的办法,即用户单击后退按钮访问历史记录时,通过创建或使用一个隐藏的IFRAME来重现页面上的变更。(例如,当用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态。)
但是,虽然说这个问题是可以解决的,但是它所带来的开发成本是非常高的,和ajax框架所要求的快速开发是相背离的。这是ajax所带来的一个非常严重的问题。
2、安全问题
技术同时也对IT企业带来了新的安全威胁,ajax技术就如同对企业数据建立了一个直接通道。这使得开发者在不经意间会暴露比以前更多的数据和服务器逻辑。ajax的逻辑可以对客户端的安全扫描技术隐藏起来,允许黑客从远端服务器上建立新的攻击。还有ajax也难以避免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于credentials的安全漏洞等。
3、对搜索引擎的支持比较弱。
4、破坏了程序的异常机制。至少从目前看来,像ajax.dll,ajaxpro.dll这些ajax框架是会破坏程序的异常机制的。关于这个问题,我曾经在开发过程中遇到过,但是查了一下网上几乎没有相关的介绍。后来我自己做了一次试验,分别采用ajax和传统的form提交的模式来删除一条数据……给我们的调试带来了很大的困难。
5、另外,像其他方面的一些问题,比如说违背了url和资源定位的初衷。例如,我给你一个url地址,如果采用了ajax技术,也许你在该url地址下面看到的和我在这个url地址下看到的内容是不同的。这个和资源定位的初衷是相背离的。
6、一些手持设备(如手机、PDA等)现在还不能很好的支持ajax,比如说我们在手机的浏览器上打开采用ajax技术的网站时,它目前是不支持的,当然,这个问题和我们没太多关系

六十八:使用 Ajax 都有哪些优劣?
<1>.AJAX干掉了Back和History功能,即对浏览器机制的破坏。
在动态更新页面的情况下,用户无法回到前一个页面状态,因为浏览器仅能记忆历史记录中的静态页面。一个被完整读入的页面与一个已经被动态修改过的页面之间的差别非常微妙;用户通常会希望单击后退按钮能够取消他们的前一次操作,但是在Ajax应用程序中,这将无法实现。
后退按钮是一个标准的web站点的重要功能,但是它没法和js进行很好的合作。这是Ajax所带来的一个比较严重的问题,因为用户往往是希望能够通过后退来取消前一次操作的。那么对于这个问题有没有办法?答案是肯定的,用过Gmail的知道,Gmail下面采用的Ajax技术解决了这个问题,在Gmail下面是可以后退的,但是,它也并不能改变Ajax的机制,它只是采用的一个比较笨但是有效的办法,即用户单击后退按钮访问历史记录时,通过创建或使用一个隐藏的IFRAME来重现页面上的变更。(例如,当用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态。)
但是,虽然说这个问题是可以解决的,但是它所带来的开发成本是非常高的,并与Ajax框架所要求的快速开发是相背离的。这是Ajax所带来的一个非常严重的问题。
一个相关的观点认为,使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中。该问题的解决方案也已出现,大部分都使用URL片断标识符(通常被称为锚点,即URL中#后面的部分)来保持跟踪,允许用户回到指定的某个应用程序状态。(许多浏览器允许JavaScript动态更新锚点,这使得Ajax应用程序能够在更新显示内容的同时更新锚点。)这些解决方案也同时解决了许多关于不支持后退按钮的争论。
<2>.AJAX的安全问题。
AJAX技术给用户带来很好的用户体验的同时也对IT企业带来了新的安全威胁,Ajax技术就如同对企业数据建立了一个直接通道。这使得开发者在不经意间会暴露比以前更多的数据和服务器逻辑。Ajax的逻辑可以对客户端的安全扫描技术隐藏起来,允许黑客从远端服务器上建立新的攻击。还有Ajax也难以避免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于Credentials的安全漏洞等等。
<3>.对搜索引擎支持较弱。
对搜索引擎的支持比较弱。如果使用不当,AJAX会增大网络数据的流量,从而降低整个系统的性能。
<4>.破坏程序的异常处理机制。
至少从目前看来,像Ajax.dll,Ajaxpro.dll这些Ajax框架是会破坏程序的异常机制的。关于这个问题,曾在开发过程中遇到过,但是查了一下网上几乎没有相关的介绍。后来做了一次试验,分别采用Ajax和传统的form提交的模式来删除一条数据……给我们的调试带来了很大的困难。
<5>.违背URL和资源定位的初衷。
例如,我给你一个URL地址,如果采用了Ajax技术,也许你在该URL地址下面看到的和我在这个URL地址下看到的内容是不同的。这个和资源定位的初衷是相背离的。
<6>.AJAX不能很好支持移动设备。
一些手持设备(如手机、PDA等)现在还不能很好的支持Ajax,比如说我们在手机的浏览器上打开采用Ajax技术的网站时,它目前是不支持的。
<7>.客户端过肥,太多客户端代码造成开发上的成本。
编写复杂、容易出错 ;冗余代码比较多(层层包含js文件是AJAX的通病,再加上以往的很多服务端代码现在放到了客户端);破坏了Web的原有标准。

六十九:请解释 JSONP 的工作原理,以及它为什么不是真正的 Ajax。
JSONP (JSON with Padding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标记来动态加载其他域的资源。例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。JSONP在此基础上加入了回调函数,pageB加载完之后会执行pageA中定义的函数,所需要的数据会以参数的形式传递给该函数。JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行,那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。
AJAX是不跨域的,而JSONP是一个是跨域的,还有就是二者接收参数形式不一样!
JSONP是JSON with Padding的简称,一般用来解决Ajax跨域的问题。它是这样产生的:
页面上调用js文件时不受跨域的影响,而且,凡是拥有src属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>。
可以在远程服务器上设法把数据装进js格式的文件里,供客户端调用处理,实现跨域。
目前最常用的数据交换方式是JSON,客户端通过调用远程服务器上动态生成的js格式文件(一般以JSON后缀)。
客户端成功调用JSON文件后,对其进行处理。
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
1、JSONP的客户端具体实现
1.1 上文已指出,页面可执行跨域的js代码(符合安全策略的),那么:

<script type="text/javascript">
  var localHandler = function (data) {
    alert('跨域的remote.js文件可以调用本函数,带来的数据是:' + data.result);
  };
</script>
<script type="text/javascript" src = "http://remoteserver.com/remote.js"></script>
remote.js的代码:
localHandler({
  "result": "我是远程js带来的数据"
});

运行后,成功弹出提示窗口,跨域成功。但问题是,如何让远程js知道它应该调用的本地函数叫什么名字?

1.2 只要服务端提供的js脚本是动态生成的就行了,调用者可以传一个参数过去告诉服务端本地函数的名字,于是服务端就可以按照客户的需求来生成js脚本并相应了。

  var flightHandler = function (data) {
    alert('你查询的航班结果是:票价 ' + data.price + '元,余票' + data.tickets + '张。');
  };
  var url = 'http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler';
  var script = document.createElement('script');
  script.setAttribute('src', url);
  document.getElementsByTagName('head')[0].appendChild(script);

并没有直接把远程js写死,而是编码事项动态查询。这是JSONP的核心部分。在调用的url中传递了一个code参数,告诉服务器要查的是CA1998次航班的信息,而callback参数告诉服务器,本地调用的函数叫做flightHandler。
服务器的flightResult.aspx生成了以下代码提供给页面:

flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
运行一下页面,成功提示窗口,JSONP的执行全过程顺利完成。

七十:你使用过 JavaScript 模板系统吗?
###################################################################################################################################################################

七十一:请解释变量声明提升 (hoisting)
在JS里定义的变量,存在于作用域链里,而在函数执行时会先把变量的声明进行提升,仅仅是把声明进行了提升,而其值的定义还在原来位置。示例如下:

1 var test = function() {
2     console.log(name); // 输出:undefined
3     var name = "jeri";
4     console.log(name); // 输出:jeri
5 }
6 
7 test();

上述代码与下述代码等价。

1 var test = function() {
2     var name;
3     console.log(name); // 输出:undefined
4     name = "jeri";
5     console.log(name); // 输出:jeri
6 }
7 
8 test();

由以上代码可知,在函数执行时,把变量的声明提升到了函数顶部,而其值定义依然在原来位置。
先看一段代码

var v = "hello";
(function(){
  console.log(v);
  var v = "world";
})();

这段代码运行的结果是什么呢?
答案是:undefined
这段代码说明了两个问题,(变量覆盖)
第一,function作用域里的变量v遮盖了上层作用域变量v。代码做少些变动

var v = "hello";
if(true){
  console.log(v);
  var v = "world";
}

输出结果为”hello”,说明javascript是没有块级作用域的。函数是JavaScript中唯一拥有自身作用域的结构。

第二,在function作用域内,变量v的声明被提升了。所以最初的代码相当于:(变量提升)

var v = "hello";
(function(){
  var v; //declaration hoisting
  console.log(v);
  v = "world";
})();

声明、定义与初始化
声明宣称一个名字的存在,定义则为这个名字分配存储空间,而初始化则是为名字分配的存储空间赋初值。
用C++来表述这三个概念

extern int i;//这是声明,表明名字i在某处已经存在了
int i;//这是声明并定义名字i,为i分配存储空间
i = 0;//这是初始化名字i,为其赋初值为0
javascript中则是这样

var v;//声明变量v
v = "hello";//(定义并)初始化变量v
因为javascript为动态语言,其变量并没有固定的类型,其存储空间大小会随初始化与赋值而变化,所以其变量的“定义”就不像传统的静态语言一样了,其定义显得无关紧要。

声明提升
当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明

(function(){
  var a = "1";
  var f = function(){};
  var b = "2";
  var c = "3";
})();

变量a,f,b,c的声明会被提升到函数作用域的最前面,类似如下:

(function(){
  var a,f,b,c;
  a = "1";
  f = function(){};
  b = "2";
  c = "3";
})();

请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:

(function(){
  //var f1,function f2(){}; //hoisting,被隐式提升的声明

  f1(); //ReferenceError: f1 is not defined,Uncaught TypeError: f1 is not a function
  f2(); //被阻塞了,不会执行到这里

  var f1 = function(){};
  function f2(){}
})();

上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。

七十二:请描述事件冒泡机制 (event bubbling)。
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
捕获型事件:事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)。
支持W3C标准的浏览器在添加事件时用addEventListener(event,fn,useCapture)方法,基中第3个参数useCapture是一个Boolean值,用来设置事件是在事件捕获时执行,还是事件冒泡时执行。而不兼容W3C的浏览器(IE)用attachEvent()方法,此方法没有相关设置,不过IE的事件模型默认是在事件冒泡时执行的,也就是在useCapture等于false的时候执行,所以把在处理事件时把useCapture设置为false是比较安全,也实现兼容浏览器的效果。

七十三:"attribute" 和 "property" 的区别是什么?
最后为了更好的区分attribute和property,基本可以总结为attribute节点都是在HTML代码中可见的,而property只是一个普通的名值对属性。

  1. 定义
    Property:属性,所有的HTML元素都由HTMLElement类型表示,HTMLElement类型直接继承自Element并添加了一些属性,添加的这些属性分别对应于每个HTML元素都有下面的这5个标准特性: id,title,lang,dir,className。DOM节点是一个对象,因此,他可以和其他的JavaScript对象一样添加自定义的属性以及方法。property的值可以是任何的数据类型,对大小写敏感,自定义的property不会出现在html代码中,只存在js中。
    Attribute:特性,区别于property,attribute只能是字符串,大小写不敏感,出现在innerHTML中,通过类数组attributes可以罗列所有的attribute。
  2. 相同之处
    标准的 DOM properties 与 attributes 是同步的。公认的(非自定义的)特性会被以属性的形式添加到DOM对象中。如,id,align,style等,这时候操作property或者使用操作特性的DOM方法如getAttribute()都可以操作属性。不过传递给getAttribute()的特性名与实际的特性名相同。因此对于class的特性值获取的时候要传入“class”。
  3. 不同之处
    1).对于有些标准的特性的操作,getAttribute与点号(.)获取的值存在差异性。如href,src,value,style,onclick等事件处理程序。
    2).href:getAttribute获取的是href的实际值,而点号获取的是完整的url,存在浏览器差异。

七十四:为什么扩展 JavaScript 内置对象不是好的做法?
因为你不知道哪一天浏览器或javascript本身就会实现这个方法,而且和你扩展的实现有不一致的表现。到时候你的javascript代码可能已经在无数个页面中执行了数年,而浏览器的实现导致所有使用扩展原型的代码都崩溃了。
  需要给Array原型添加一个distinct的方法,最好检查是否存在同名的方法,避免自定义方法覆盖原生方法:
  Arrray.prototype.distinct =Arrray.prototype.distinct || function(){/...../}

七十五: 请指出 document load 和 document DOMContentLoaded 两个事件的区别
他们的区别是,触发的时机不一样,先触发DOMContentLoaded事件,后触发load事件。

DOM文档加载的步骤为

解析HTML结构。
加载外部脚本和样式表文件。
解析并执行脚本代码。
DOM树构建完成。//DOMContentLoaded
加载图片等外部文件。
页面加载完毕。//load

七十六:== 和 === 有什么不同?
”==”:判断值是否相等。应用一套难以理解的隐式强制转换规则。
”===”判断值及类型是否完全相等。读者不需要涉及任何的隐式转换。
注意:
1)如果两个值的类型不同,它们就不相同。
2)如果两个值是数字,而且值相同,那么除非其中一个或两个都是NaN(这种情况它们不是等同的),否则它们是等同的。值NaN永远不会与其他任何值等同,包括它自身(奇怪的家伙),要检测一个值是否是NaN,可以使用全局函数isNaN()。
3)如果两个值都是字符串,而且在串中同一位置上的字符完全相同,那么它们就完全等同。如果字符串的长度或内容不同,它们就不是等同的。
4)如果两个值都是布尔型true,或者两个值都是布尔型false,那么它们等同。
5)如果两个值引用的是同一个对象、数组或函数,那么它们完全等同。如果它们引用的是不同的对象(数组或函数),它们就不完全等同,即使这两个对象具有完全相同的属性,或两个数组具有完全相同的元素。
######################## # 6)如果两个值都是null或都是undefined,“==”返回true,“===”返回false。

七十七:请解释 JavaScript 的同源策略 (same-origin policy)。
同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。所谓同源是指,域名,协议,端口相同。如果我们又想利用XMLHTTP的无刷新异步交互能力,又不愿意公然突破Javascript的安全策略,可以选择的方案就是给XMLHTTP加上严格的同源限制。

同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。
处理跨域方法:
1)document.domain+iframe的设置
2)动态创建script
3)利用iframe和location.hash
4)window.name实现的跨域数据传输
5)使用HTML5 postMessage

七十八:如何实现下列代码:
[1,2,3,4,5].duplicator(); // [1,2,3,4,5,1,2,3,4,5]

Array.prototype.duplicator = function(){
    var len = this.length;
    for(var i = 0; i < len; ++i){
        this.push(this[i]);
    }
}

七十九:什么是三元表达式 (Ternary expression)?“三元 (Ternary)” 表示什么意思?
三元表达式:? :。三元--三个操作对象。
在表达式boolean-exp ? value0 : value1 中,如果“布尔表达式”的结果为true,就计算“value0”,而且这个计算结果也就是操作符最终产生的值。如果“布尔表达式”的结果为false,就计算“value1”,同样,它的结果也就成为了操作符最终产生的值

八十:什么是 "use strict"; ? 使用它的好处和坏处分别是什么?
在所有的函数 (或者所有最外层函数) 的开始处加入 "use strict"; 指令启动严格模式。
"严格模式"有两种调用方法
1)将"usestrict"放在脚本文件的第一行,则整个脚本都将以"严格模式"运行。如果这行语句不在第一行,则无效,整个脚本以"正常模式"运行。如果不同模式的代码文件合并成一个文件,这一点需要特别注意。
2)将整个脚本文件放在一个立即执行的匿名函数之中。
好处

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。
    坏处 
    同样的代码,在"严格模式"中,可能会有不一样的运行结果;一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行

八十一:请实现一个遍历至 100 的 for loop 循环,在能被 3 整除时输出 "fizz",在能被 5 整除时输出 "buzz",在能同时被 3 和 5 整除时输出 "fizzbuzz"。

function create(100){
    for(var i = 0; i < num; ++i){
        if(i % 3 == 0){
            if(i % 5 == 0){
                console.log('fizzbuzz' + i);
                continue;
            }
            console.log('fizz' + i);
        }else if(i % 5 == 0){
            if(i % 3 == 0){
                console.log('fizzbuzz' + i);
                continue;
            }
            console.log('buzz'+i);
        }
    }
}

八十二:为何通常会认为保留网站现有的全局作用域 (global scope) 不去改变它,是较好的选择?
减少名称冲突
利于模块化

八十三:为何你会使用 load 之类的事件 (event)?此事件有缺点吗?你是否知道其他替代品,以及为何使用它们?
说的简单一点,就是一个页面加载分成三个步骤:
1)浏览器接收到纯文本的HTML
2)HTML根据XHTML的规则,将其解析成为一个DOM树
3)浏览器遍历DOM中带有再次请求信息的节点,例如image,通过这些节点上的信息,将远程的资源获取到本地(或者是从cache中获取)
然后,经过浏览器的解析之后,你看到的就是整个页面了。
其中,$(document).ready()方法的触发时机是在第二步结束,而window.onload()方法的出发时机则是在第三步结束之后。
联想到一个问题,如果我需要在document.ready()方法中,获取图像的大小应该怎么办呢?因为ready()方法的触发时机被人为的提前了,带来了很多好处,但是也必然存在类似这样的弊端。jQuery还是考虑到了这样的情况,并且做了相应的解决方案,在他的文档里面,有一个load()方法,就是用来解决这样的问题。直接把代码copy上来吧,注意onload方法适用于下面几个对象:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
<html>  
    <head>  
        <script type="text/javascript" src="jquery-1.3.1.js"></script>  
        <script type="text/javascript">  
            $(function(){  
                $("#image").load(function(){  
                    alert($("#image").width());  
                });  
            })  
        </script>  
    </head>  
    <body>  
        <select multiple="multiple">  
            <option value="1">Oracle</option>  
            <option value="2">Java</option>  
            <option value="3">C++</option>  
        </select>  
        <img id="image"   
        src="http://t1.baidu.com/it/u=2624739849,4151443416&fm=32&picname=8441c36b01d987e6ca8054e6d69615f8.jpg">  
    </body>  
</html>  
</span>  

八十四:请解释什么是单页应用 (single page app), 以及如何使其对搜索引擎友好 (SEO-friendly)。
单页应用是指在浏览器中运行的应用,它们在使用期间不会重新加载页面。像所有的应用一样,它旨在帮助用户完成任务,比如“编写文档”或者“管理Web服务器”。可以认为单页应用是一种从Web服务器加载的富客户端。
1、注重TDK的写法 既然页面单一,那么就更需要注重网站标题、关键词和描述的写法。标题上来说,要简单明确,包含主要关键词,一句话能概括全文;描述上来讲,一句话活一小段文字提炼出文章的精髓,内容比标题更加详细;关键词,用绝对的与内容相关的词语,多个关键词用逗号分开。
2、外链锚文本的多样化
在外链建设上,切忌内容单一,这样很容易造成网站的过度优化,而我们都知道,网站的过度优化对SEO而言是不利的。
3、网站标签的运用
合理的运用网站标签可以让搜索引擎更好的理解网站的层次内容,比如h标签,strong标签等等。
4、符合国际标准
这里所说的符合国际标准指的是告诉搜索引擎我的网站符合W3C标准,对任何浏览器都是兼容的。
5、代码优化
CSS和JS的优化,尽可能的使用外部导入,从而让网页代码更加简洁,能用CSS就尽量不用JS,毕竟JS对于搜索引擎而言并不友好。
6、图片的优化
这个属于老生常谈了,这里就不多说了。
7、合理设置锚点
有一些单页面为了展示很多产品特点,页面会拉的很长,不利于用户查看,用户体验并不好,如果在单页面网站上设置合理的锚点,用户只需要点击一下快速达到想要看到的内容区域。
8、避免全是图片展示
如果单页面网站为了提升视觉效果从而更多的使用图片,那么就会造成网站文字内容过少,不利于搜索引擎对网站的抓取和索引。
9、内容为王
之前我们就举过百度百科的例子,而作为单页面网站来讲,将用户所有的需求点尽可能完整的展现出来,从而解决用户的烦恼才是单页面网站立足的关键

八十五:使用Promises以及/或者他们的polyfills的经验程度?
#####################################################################################################################################################################################

八十六:使用 Promises 而非回调 (callbacks) 优缺点是什么?
Promises可以避免callback的圣诞树模式(地狱模式)
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。
Promise也有一些缺点。
首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。
其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
第三,当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

八十七:使用一种可以编译成 JavaScript 的语言来写 JavaScript 代码有哪些优缺点?
优点的话不同语言不同,大部分具有简洁,清晰的特点。缺点是你需要学。如果一个项目采用了typescript,那就必须找懂typescript的人,或者培训。

八十八:你使用哪些工具和技术来调试 JavaScript 代码?
console控制台

八十九:你会使用怎样的语言结构来遍历对象属性 (object properties) 和数组内容?

对象属性:for in 方法
var x = {1:"11",2:"22",3:"33"}
for(i in x){console.log(i);}
数组:forEach方法
var y = [1,2,3]
y.forEach(function(i){
    console.log(i);
});

九十:Js 请解释可变 (mutable) 和不变 (immutable) 对象的区别
在 JavaScript 中,对象是引用类型的数据,其优点在于频繁的修改对象时都是在原对象的基础上修改,并不需要重新创建,这样可以有效的利用内存,不会造成内存空间的浪费,对象的这种特性可以称之为 Mutable,中文的字面意思是「可变」。
Immutable 从字面上翻译成中文是「不可变」。每次修改一个 Immutable 对象时都会创建一个新的不可变的对象,在新对象上操作并不会影响到原对象的数据。

请举出 JavaScript 中一个不变性对象 (immutable object) 的例子?
var statement = 'I am an immutable value';
var otherStr = statement.slice(8, 17);
我猜没人会吃惊,statement.slice(8, 17)并没有改变statement变量吧(译者注:如果你吃惊了,赶紧去补基本知识吧)?事实上,string对象上的所有方法里,没有一个会修改原string,它们一律返回新的string。原因简单了,因为string就是是不可变的(Immutable) - 它们不能被修改,我们能做的就是基于原string操作后得到一个新string。
注意了,string可不是javascript里唯一内置的不可变(Immutable)数据类型哦。number也是不可变(Immutable)的

九十一:请解释同步 (synchronous) 和异步 (asynchronous) 函数的区别。
同步调用,在发起一个函数或方法调用时,没有得到结果之前,该调用就不返回,直到返回结果;
异步调用的概念和同步相对,在一个异步调用发起后,被调用者立即返回给调用者,但调用者不能立刻得到结果,被调用者在实际处理这个调用的请求完成后,通过状态、通知或回调等方式来通知调用者请求处理的结果。
简单地说,同步就是发出一个请求后什么事都不做,一直等待请求返回后才会继续做事;异步就是发出请求后继续去做其他事,这个请求处理完成后会通知你,这时候就可以处理这个回应了。
单从任务调用来讲,对于同一个任务,异步调用并不能加快这个任务的执行速度和效率,相反会降低执行速度和效率。站在整个系统的层面上考虑,异步调用使得整个系统的性能效率提高,各个组件之间运行配合更加协调。这才是异步调用的真正优点。

九十二:什么是事件循环 (event loop)?
二、任务队列
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。
JavaScript语言的设计者意识到,这时CPU完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。
于是,JavaScript就有了两种执行方式:一种是CPU按顺序执行,前一个任务结束,再执行下一个任务,这叫做同步执行;另一种是CPU跳过等待时间长的任务,先处理后面的任务,这叫做异步执行。程序员自主选择,采用哪种执行方式。
具体来说,异步执行的运行机制如下。(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)
(1)所有任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。系统把异步任务放到"任务队列"之中,然后继续执行后续的任务。
(3)一旦"执行栈"中的所有任务执行完毕,系统就会读取"任务队列"。如果这个时候,异步任务已经结束了等待状态,就会从"任务队列"进入执行栈,恢复执行。
(4)主线程不断重复上面的第三步。
只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。
三、事件和回调函数
"任务队列"实质上是一个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。
"任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当异步任务从"任务队列"回到执行栈,回调函数就会执行。
"任务队列"是一个先进先出的数据结构,排在前面的事件,优先返回主线程。主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动返回主线程。但是,由于存在后文提到的"定时器"功能,主线程要检查一下执行时间,某些事件必须要在规定的时间返回主线程。
四、Event Loop
主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。

九十三:请问调用栈 (call stack) 和任务队列 (task queue) 的区别是什么?
调用栈负责程序本身的运行,称为"主线程";
任务队列负责主线程与其他进程(主要是各种I/O操作)的通信,被称为"Event Loop线程"(可以译为"消息线程")
每当遇到I/O的时候,主线程就让Event Loop线程去通知相应的I/O程序,然后接着往后运行,所以不存在红色的等待时间。等到I/O程序完成操作,Event Loop线程再把结果返回主线程。主线程就调用事先设定的回调函数,完成整个任务。

九十四:解释 function foo() {} 与 var foo = function() {} 用法的区别
方法一:foo在进入函数执行上下文开始执行代码的时候,foo是undefined的,知道执行完var foo = function () { }这句,foo才会得到赋值; 方法二:在进入函数执行上下文开始执行代码的时候,foo已经是一个function了。
简单的说 如果我们使用 匿名函数var FUNCTION_NAME = function() { /* FUNCTION_BODY */};
这种方式, 编译后变量声明FUNCTION_NAME 会“被提前”了,但是他的赋值(也就是FUNCTION_BODY)并不会被提前。也就是,匿名函数只有在被调用时才被初始化。如果我们使用 function FUNCTION_NAME ()
这种方式, 编译后函数声明和他的赋值都会被提前。也就是说函数声明过程在整个程序执行之前的预处理就完成了,所以只要处于同一个作用域,就可以访问到,即使在定义之前调用它也可以。

九十五:对代码进行测试的有什么优缺点?
一边写代码,一边检查代码中的小错误或者小疏忽,提前解决代码中可能存在的笔误;
掌握代码,积累代码编写经验,积累调试经验,积累分析问题、解决问题的经验;
训练动手能力,单元测试代码不是业务代码,开发、维护过程中不需要特别关注质量要求,底限是达到验证业务代码逻辑性的目的,因而比修改代码要省心、省事;
不需要准备项目运行环境,单元测试代码在运行时的外部依赖比较少,执行验证、调试代码的代价会很低;
增加工作复杂度

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容