1、请解释 JavaScript 中 this 是如何工做的。javascript
首先:this 永远指向函数运行时所在的对象,而不是函数被建立时所在的对象。匿名函数或不处于任何对象中的函数指向 window 。java
一、 方法调用模式 chrome
当函数被保存为对象的一个属性时,成该函数为该对象的方法。函数中this的值为该对象。express
var foo = { name: 'fooname', getName: function (){ return this.name } } foo.getName(); // this => foo
二、 函数调用模式 编程
当函数并非对象的属性。函数中this的值为全局对象
note:某个方法中的内部函数中的this的值也是全局对象,而非外部函数的thisjson
function foo(){ this.name = 'fooname'; } foo(); // this => window
三、构造器调用模式 跨域
即便用new调用的函数,则其中this将会被绑定到那个新构造的对象。数组
function Foo(){ this.name = 'fooname'; } var foo = new Foo(); // this => foo
四、使用apply或call调用模式 浏览器
该模式调用时,函数中this被绑定到apply或call方法调用时接受的第一个参数。安全
function getName(name){ this.name = name; } var foo = {}; getName.call(foo, name); // this =>foo
改变this的值主要方法(目前想到的,欢迎评论添加):
apply或call方法调用时强制修改,使this指向第一个参数。
使用Function.bind方法创造新的函数,该新函数的中this指向所提供的第一个参数。
2、请解释原型继承 (prototypal inheritance) 的原理。
JavaScript没有“子类”和“父类”的概念,也没有“类”(class)和“实例”(instance)的区分,全靠“原型链”(prototype chain)模式,来实现继承。
每一个函数Sub都有一个属性prototype,prototype指向一个原型对象,原型对象中也有一个指向函数的属性constructor,经过new一个函数Sub能够产生实例instance,调用这个instance的某个属性或方法时,instance会先查找自身是否有这个方法或者属性,没有的话就会去实例的构造函数Sub的原型prototype中查找,即Sub.prototype,若是给原型对象Sub.prototype赋予另外一个类型的实例superInstance,则是在superInstance中查找的,这个superInstance中也有属性prototype指向某个原型对象,以此一级级往上最终到Object.prototype,这样就造成了原型继承。
利用此原理能够本身实现一个inherits函数:
function inherits(subType, superType){ var _prototype = Object.create(superType.prototype); _prototype.constructor = subType; subType.prototype = _prototype; }
3、解释为何接下来这段代码不是 IIFE (当即调用的函数表达式):function foo(){ }(); 要作哪些改动使它变成 IIFE?
(function fn(){..})()
,函数被包含在一个括号内,变成为一个表达式,随后跟着一个(),就当即执行这个函数。
IIFE的一些做用:
4、(function fn(){..})(),函数被包含在一个括号内,变成为一个表达式,随后跟着一个(),就当即执行这个函数。
IIFE的一些做用:
当某个函数调用时会建立一个执行环境以及做用域链,而后根据arguments和其它命名参数初始化造成活动对象。在外部函数调用结束后,其执行环境与做用域链被销毁,可是其活动对象保存在了闭包之中,最后在闭包函数调用结束后才销毁。简单的说,闭包就是可以读取其余函数内部变量的函数。在js中,闭包是指有权访问另外一个函数做用域中的变量的函数。
如何使用:将A函数内部的B函数做为A函数的返回值返回。
为何要:
一、匿名自执行函数
有的场景下函数只须要执行一次,例如init()之类的函数,其内部变量无需维护,咱们可使用闭包。 咱们建立了一个匿名的函数,并当即执行它,因为外部没法引用它内部的变量,所以在函数执行完后会马上释放资源,并且不污染全局对象。
二、封装
模拟面向对象的代码风格进行封装,使私有属性存在成为可能。
5、.call 和 .apply 的区别是什么?
.call和.apply的共同点是都是用来改变函数体内this对象的值。
区别是第二个参数不同。apply()的第二个参数是一个类数组对象arguments,参数都是以数组的形式传入,而call(),传递给他的是一系列参数。例如
Math.max.call(null, 1, 2, 3, 4); //4 Math.max.apply(null, [1, 2, 3, 4]); //4
6、请解释 Function.prototype.bind?
Function.prototype.bind方法会建立一个新函数,当这个新函数被调用时,它的this值是传递给bind()的第一个参数, 它的参数是bind()的其余参数和其本来的参数.
7、请指出 JavaScript 宿主对象 (host objects) 和原生对象 (native objects) 的区别?
宿主对象是指DOM和BOM。
原生对象是Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、Math等对象。
8、请指出如下代码的区别:function Person(){}、var person = Person()、var person = new Person()?
function Person(){}
声明一个函数Person()。
var person = Person()
将函数Person()的结果返回给变量person,若是没有返回值则person为undefined。
var person = new Person()
new一个Person的实例对象。
9、请尽量详尽的解释 Ajax 的工做原理。以及使用 Ajax 都有哪些优劣?
Ajax是无需刷新页面就能从服务器取得数据的一种方法。
Ajax经过XmlHttpRequest对象来向服务器发异步请求,从服务器得到数据,而后用javascript来操做DOM更新页面。
过程
缺点
10、请解释变量声明提高 (hoisting)。
变量的声明前置就是把变量的声明提高到当前做用域的最前面。
函数的声明前置就是把整个函数提高到当前做用域的最前面(位于前置的变量声明后面)。
//变量的声明前置 console.log(num);//undefined var num = 1; 等价于 //变量的声明前置 var num; console.log(num);//undefined num = 1;
11、请描述事件冒泡机制 (event bubbling)。
事件冒泡(event bubbling),事件最开始时由触发的那个元素身上发生,而后沿着DOM树向上传播,直到document对象。若是想阻止事件起泡,可使用e.stopPropagation()。
12、什么是 “use strict”; ? 使用它的好处和坏处分别是什么?
优势
消除Javascript语法的一些不严谨之处,减小一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提升编译器效率,增长运行速度;
为将来新版本的Javascript作好铺垫。
缺点
严格模式改变了语义。依赖这些改变可能会致使没有实现严格模式的浏览器中出现问题或者错误。
十3、请解释 JavaScript 的同源策略 (same-origin policy)。
同源策略限制了一个源(origin)中加载文本或脚本与来自其它源(origin)中资源的交互方式。同源指的是协议、域名、端口相同,同源策略是一种安全协议。
十4、请解释 JSONP 的工做原理,以及它为何不是真正的 Ajax。
JSONP(JSON with Padding)是一种非官方跨域数据交互协议,它容许在服务器端集成< script >标签返回至客户端,经过javascript回调的形式实现跨域访问。
由于同源策略的缘由,咱们不能使用XMLHttpRequest与外部服务器进行通讯,可是< script >能够访问外部资源,因此经过JSON与< script >相结合的办法,能够绕过同源策略从外部服务器直接取得可执行的JavaScript函数。
原理
客户端定义一个函数,好比jsonpCallback,而后建立< script >,src为url + ?jsonp=jsonpCallback这样的形式,以后服务器会生成一个和传递过来jsonpCallback同样名字的参数,并把须要传递的数据当作参数传入,好比jsonpCallback(json),而后返回给客户端,此时客户端就执行了这个服务器端返回的jsonpCallback(json)回调。
通俗的说,就是客户端定义一个函数而后请求,服务器端返回的javascript内容就是调用这个函数,须要的数据都当作参数传入这个函数了。
优势 - 兼容性好,简单易用,支持浏览器与服务器双向通讯
缺点 - 只支持GET请求;存在脚本注入以及跨站请求伪造等安全问题
补充一点,JSONP不使用XMLHttpRequest对象加载资源,不属于真正意义上的AJAX。
十5、== 和 === 有什么不一样?
通俗的说就是===比==要更为严格,===比较过程当中没有任何的类型转换。
十6、什么是三元表达式 (Ternary expression)?“三元 (Ternary)” 表示什么意思?
如名字表示的三元运算符须要三个操做数。
语法是
条件 ? 结果1 : 结果2;
这里你把条件写在问号(?)的前面后面跟着用冒号(:)分隔的结果1和结果2。知足条件时结果1不然结果2。
十7、你怎么看 AMD vs. CommonJS?
浏览器端异步和服务器端同步的模块化编程规范
十8、请举出一个匿名函数的典型用例?
定义回调函数,当即执行函数,做为返回值的函数,使用方法var foo = function() {}定义的函数。
十9、描述如下变量的区别:null,undefined 或 undeclared?该如何检测它们?
未定义的属性、定义未赋值的为undefined,JavaScript访问不会报错;null是一种特殊的object;NaN是一种特殊的number;undeclared 是未声明也未赋值的变量,JavaScript访问会报错。
二10、在何时你会使用 document.write()?
DOM方法,可向文档写入 HTML 表达式或 JavaScript 代码。
二11、如何实现下列代码:[1,2,3,4,5].duplicator(); // [1,2,3,4,5,1,2,3,4,5]
Array.prototype.duplicator = function(){ var l = this.length,i; for(i=0;i<l;i++){ this.push(this[i]) } }
二12、解释 function foo() {} 与 var foo = function() {} 用法的区别
函数声明的两种方法:
这种方式是声明了个变量,而这个变量是个方法,变量在js中是能够改变的。
也:将一个匿名函数赋值给了变量。
这种方式是声明了个方法,foo这个名字没法改变
二十3、请解释可变 (mutable) 和不变 (immutable) 对象的区别。
在 JavaScript 中,对象是引用类型的数据,其优势在于频繁的修改对象时都是在原对象的基础上修改,并不须要从新建立,这样能够有效的利用内存,不会形成内存空间的浪费,对象的这种特性能够称之为 Mutable,中文的字面意思是「可变」。
Immutable 从字面上翻译成中文是「不可变」。每次修改一个 Immutable 对象时都会建立一个新的不可变的对象,在新对象上操做并不会影响到原对象的数据。
二十4、使用 Promises 而非回调 (callbacks) 优缺点是什么?
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最先提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。
所谓Promise,简单说就是一个容器,里面保存着某个将来才会结束的事件(一般是一个异步操做)的结果。从语法上说,Promise是一个对象,从它能够获取异步操做的消息。Promise提供统一的API,各类异步操做均可以用一样的方法进行处理。
有了Promise对象,就能够将异步操做以同步操做的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操做更加容易。
Promise也有一些缺点。
首先,没法取消Promise,一旦新建它就会当即执行,没法中途取消。
其次,若是不设置回调函数,Promise内部抛出的错误,不会反应到外部。
第三,当处于Pending状态时,没法得知目前进展到哪个阶段(刚刚开始仍是即将完成)。
二十5、请解释同步 (synchronous) 和异步 (asynchronous) 函数的区别。
同步调用,在发起一个函数或方法调用时,没有获得结果以前,该调用就不返回,直到返回结果;
异步调用的概念和同步相对,在一个异步调用发起后,被调用者当即返回给调用者,但调用者不能马上获得结果,被调用者在实际处理这个调用的请求完成后,经过状态、通知或回调等方式来通知调用者请求处理的结果。
简单地说,同步就是发出一个请求后什么事都不作,一直等待请求返回后才会继续作事;异步就是发出请求后继续去作其余事,这个请求处理完成后会通知你,这时候就能够处理这个回应了。
二十6、你使用哪些工具和技术来调试 JavaScript 代码?
1.javascript的debugger语句
须要调试js的时候,咱们能够给须要调试的地方经过debugger打断点,代码执行到断点就会暂定,这时候经过单步调试等方式就能够调试js代码
if (waldo) { debugger; }
这时候打开console面板,就能够调试了
2.DOM断点
DOM断点是一个Firebug和chrome DevTools提供的功能,当js须要操做打了断点的DOM时,会自动暂停,相似debugger调试。
使用DOM断点步骤:
选择你要打断点的DOM节点
右键选择Break on..
选择断点类型
另外的调试方法例如alert, console.log,查看元素等就再也不赘述了。
二十7、你会使用怎样的语言结构来遍历对象属性 (object properties) 和数组内容?
for in 语句 通常for循环 数组forEach方法