javascript篇--1.6万字带你回忆那些遗忘的JS知识点

发文前,小编想先对上一篇文章-css篇纠正错误以及针对文章提出的优化的小伙伴表示感谢,大家的每一个建议或意见都很宝贵🌻🌻。javascript

继上两篇文章html篇CSS篇以后,本篇文章对于常见的有关Javascript部分的内容进行了大体的整合。文中涉及的知识面仍是蛮广的,小编在整理的时候也顺道温习了一遍。css

文章字数1.5万+,篇幅比较长,仍是建议收藏吧,慢慢看。所谓温故而知新,本篇文章做为温习知识点仍是挺有用的(尤为是准备跳槽的小伙伴抱佛脚尤其有用哈哈哈哈)🥴。html

PS: 文中,为了方便阅读,小编一如既往作了分割线。java


1.🤪JavaScript 中 this 是如何工做的

首先,在js中,this是指正在执行的很熟的“全部者”,更确切的说,是指将当前函数做为方法的对象。node

javascript中的this有一套彻底不用于其它语言的对this的处理机制。在如下五种状况下,this的指向各不相同。linux

全局范围

当在全局范围内的时候,使用this将会指向全局对象(this->window)程序员

对象方法调用

这里的this是在对象中的.当函数被保存为对象的一个属性时,成该函数为该对象的方法,函数中this的值为该对象。web

咱们先看个例子:ajax

const object = {
    a: 1, 
    func: function() {
        console.log(this.a)
    }
}

object.fun()  //1  (this->object)
复制代码
function func() {
     console.log(this.a)
}
const object = {
    a: 1, 
    b: func
}

object.fun()  // 1 (this->object)
复制代码

这里的两个this指向的是对象object,此时咱们能够这么理解,函数不管在对象内部或外部定义,实现的效果同样。由于做为对象的属性的函数,对于对象来讲是独立的算法

可是须要注意有时候,对象中的也会存在this绑定丢失的问题,这也是咱们下面将的使用applycall调用模式。

使用apply或call调用模式

看下面例子:

function func() {
     console.log(this.a)
}
const object = {
    a: 1, 
    b: func
}
const fun = object.b;

fun()  // undefined
复制代码

此时fun()打印出来的值并非对象中的1,而是undefined。由此可看出,此时的this指向的并非object对象。咱们再给代码添加一个全局的a看看状况:

function func() {
     console.log(this.a)
}
const object = {
    a: 1, 
    b: func
}
const fun = object.b;

var a = 2;
fun()  // 2
复制代码

此时的func打印出来的是全局变量的值--2,说明此时的this是指向外部全局变量的。这种状况主要是由由于this的隐式绑定致使的this绑定丢失

咱们能够理解为: 执行“ fun= object.b”以后fun的调用和object.b调用的结果是不一样的,由于这个函数赋值的过程没法把b所绑定的this也传递过

决绝方式:经过this的显示绑定解决。

咱们能够经过使用 callapply以及bind来解决,此时函数内的this将会被显示设置为函数调用的第一个参数。以下代码:

function func() {
     console.log(this.a)
}
const object = {
    a: 1, 
    b: func
}
var a = 2;
const fun = object.b;

fun.call(object) 或者  fun.apply(object) 或者  const funb = fun.bind(object) ; funb() // 1
复制代码

此时this指向的就是object内部的a,这就解决了this绑定丢失的问题。

🌈🌈注意

  • bind是提供了一个可执行的函数,可是自己并不会执行,须要咱们手动去执行;
  • callapply它们是提供了一个可当即执行的函数,在绑定this的同时,也会当即去执行该函数。这也是为何咱们在最后一个bind方法中再次须要的单独再调用一次funb()方法的缘由。

函数调用

此时的this也会指向全局对象。咱们也能够这么理解:当没有明确的调用对象的时候,行数的this仍是在全局范围内的,因此this会绑定到全局的window对象

调用构造函数

先看个例子:

function func() {
    this.b = a;
    console.log(b)
 }
 func(20);  // 20,此时的b是20
 
 const funb = new func(30)
 funb.b;  // 30
复制代码

能够看到,当执行new操做的时候,会建立一个新的对象,而且将构造函数的this指向所建立的新对象。

2.请解释原型继承 的原理

有关原型链以及其继承的原理,小编在以前的文章毒鸡汤中,在前面的部分图文结合,已经作了比较详细的介绍,有兴趣的童鞋能够去瞅瞅,小编这里就不过多介绍了(又能够偷懒了)。

3.什么是闭包 (closure),如何使用它,为何要使用它

有关闭包部分,亦是在毒鸡汤中有所体现。

4. 同步 (synchronous) 和异步 (asynchronous) 函数的区别在哪里

同步

同步(阻塞模式)指的是:当发送一个请求时,须要等待返回,而后才能发送另外一个请求。其有个等待的过程。此外,同步也能够避免出现死锁,读脏数据的发生。

异步

异步(非阻塞模式)指的是:当发送一个请求时,不须要等待返回,能够随时发送下一个请求。其不须要等待。

区别: 最明显的就是一个须要等待,一个不须要等待。

拓展: 在项目过程当中,能够根据需求,来考虑功能是使用同步仍是异步。通常,有些功能为了缩短用户的等待时间,都会优先采用异步的方式;可是对于数据库保存等操做,通常采用的是同步的方式。

5.JavaScript 宿主对象 (host objects) 和原生对象 (native objects) 以及内置(build-in objects)对象的区别

概念

  • 宿主对象: 宿主对象不是引擎的原生对象,而是由宿主框架经过某种机制注册到js引擎中的对象;
  • 内置对象: 在引擎初始化阶段就被建立好的对象,是原生对象的一个子集;
  • 原生对象: 除了内置对象以外,还包括了一些在运行过程当中动态建立的对象;

内容

  • 原生对象包括: Object, Function, Array, String, Boolean, Number, Date, RegExp, Error, EvalError, RangeError, ReferenceError, SyntaxError, Typerror, URLError等;
  • 内置对象包括: Global(全局对象), Math ;(注意全部的内置对象都是原生对象)
  • 宿主对象包括: 有宿主提供的对象,在浏览器中window对象以及其下边的全部子对象(例如dom等),在node中是global以及其子对象,也包含自定义的类对象。

区别

  • 内置对象是原生对象的一个子集;前者总在引擎初始化阶段就被建立好对象,然后者还包括了一些在运行过程当中动态建立的对象;
  • 宿主对象不是引擎的原生对象,而是有宿主框架经过某种机制注册到js引擎当中的对象;

6.如下代码有什么区别:function Person(){}、var person = Person()、var person = new Person()

  • 第一: function Person(){}是声明了一个名为Person的函数;
  • 第二: var person = Person()是直接调用了Person函数,并将返回值做为值赋值给变量person
  • 第三: var person = new Person()建立了一个Person实例对象;

7.什么是变量声明提高 (hoisting)

首先咱们先看个例子:

console.log(num); //undefined
var num = 5;
console.log(num) // 5
复制代码

到这里,有基础的小伙伴可能看出来这是为何了。没错,就是变量声明提高!一个变量的生命周期包含3个阶段

  • 声明--从建立一个新的变量开始,例如:var num
  • 初始化--初始化变量给变量赋值,例如: num = 5
  • 使用--使用变量的值,例如console.log(num)

上面的例子其实等价于:

var num;
console.log(num); //undefined  由于变量num提高了,可是值并无提高,因此打印出来是undefined
num = 5;
console.log(num) // 5
复制代码

🌈🌈注意: 若是变量是在函数做用域内,那么它的做用域就是函数做用域。不然,它就是全局做用域。

拓展

拓展1之函数优先

函数声明和函数表达式在语法上是的等价的,可是有一点不一样的是,js引擎加载它们的方式不同。简单来讲就是:函数声明会被提高到其做用域顶部,而函数表达式不会。

具体能够看如下两点:

  • 函数声明会提高,可是函数表达式的函数体不会提高;
  • 函数是javascript的一等公民,当一个变量名和函数同名时,函数声明优先变量声明,而且会忽略同名的变量声明。

拓展2之let,const和var

在此长话短说,总的来讲就是letconst的声明会造成块级做用域,不存在变量提高且不能重复声明同一变量(或常量)。而var声明的变量会挂载在window上,存在变量提高且能够命名重复。

8.什么是 “use strict”; ? 使用其的优缺点

“use strict”-- 严格模式ES5添加的一种运行模式,目的是为了是javascript在更严格的条件下运行。

优势(设立的目的)

  • 消除js语法的一些不合理,不严谨之处,减小一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行安全;
  • 提升编译效率,增长运行速度;
  • 为将来新版本的javascript作好铺垫;

🌈🌈注意: 通过测试,目前IE6-9都不支持严格模式。

缺点

如今网站的js通常都会进行压缩,压缩过程当中,有些文件使用了严格模式,有些却没有。这种状况下原本是严格模式的文件,被merge后,这个串就到了文件中间,不只没有指示严格模式,在压缩后也会浪费字节。

9.什么是事件循环 (event loop)

javascript是单线程执行的,从上到下一次运行。在js中分为两个任务,宏任务和微任务。通常状况下,首先执行的是宏任务(就是一般说的第一时间执行全部同步代码),遇到微任务时,先加入队列,宏任务执行完毕再执行微任务。微任务执行完毕以后再往下执行宏任务,执行完后再次执行全部微任务。

简单的理解就是: 宏任务-> 微任务-> 宏任务 ->微任务;

终于详细的执行机制,有兴趣的小伙伴小编建议请移步至毒鸡汤瞅瞅。

10.bind,call 和 apply 的区别

类似之处

  • 它们的第一个参数都是this要指向的对象;
  • 都是用来改变函数的this指向的;
  • 均可以利用后继参数传参;

区别

  • 执行方面:使用callapply以后函数可自动执行,可是使用bind须要手动执行;
  • 参数接收方面callapply接收的第一个参数是在其中运行函数的做用域,不一样的是在接收的第二个参数时,apply接收的是一个数组,而call接收的是参数列表,须要跟函数保持一一对应。

🌈🌈注意callapply扩充了函数的做用域

应用场景

  • 若是不须要关心具体有多少参数被传入函数的时候(或者参数较多状况下),能够选用apply
  • 若是肯定函数能够接收多少个参数(或参数较少状况下),而且想一目了然的表达形参和实参的对象关系的,能够选用call;
  • 若是想未来再调用方法,不须要当即获得函数的返回结果的,能够选用bind;

🚚...................................................ᴅᴜᴅᴜ!

11. 🤥什么是事件委托以及冒泡事件和默认事件如何阻止

概念事件冒泡是指嵌套最深的元素触发一个事件,而后这个事件顺着嵌套顺序在父元素上触发。而事件委托,是利用事件冒泡原理,让本身所触发的事件,让其父元素代替执行。

冒泡阻止方式:使用event.cancelBubble = true或者event.stopPropgation()(低于IE9)。

默认事件阻止方式e.preventDefault();return false;

12. 如何检查一个数字是否为整数

比较简单的方式是能够将其数字对1进行取模,看看是否存在余数。看如下代码:

function isInt(number) {
    return number % 1 === 0;
};

console.log(isInt(2.1));  // false
console.log(isInt(2));  // true
复制代码

13. 什么是IIFE(当即调用函数表达式)

它是当即调用函数表达式(Immediately-Invoked Function Expression),简称为IIFE。指的是函数被建立后当即执行。看下面代码:

(function IIFE(){
 console.log( "Hello!" );
})();    

// "Hello!"
复制代码

这种当即调用函数表达式通常应用于避免污染全局命名空间条件下。由于 IIFE(与任何其余正常函数同样)内部的全部变量在其做用域以外都是不可见的。

14. 原型设计模式

原型模式可用于建立新对象,可是它建立的并非初始化的对象,而是使用原型对象的值进行初始化的对象。原型模式也成为属性模式

原型模式在初始化业务对象是很是有用,业务对象中的值与数据库的默认值相匹配。原型对象中的默认值被复制到新建立的业务对象中。目前js在构造新对象及其原型时使用了这个模式。

原型模式包含如下主要角色

  • 抽象原型类: 规定了具体原型对象必须实现的接口;
  • 具体原型类: 实现了抽象原型类的clone()方法,它是可被复制的对象;
  • 访问类: 使用具体原型类中的clone()方法来复制新的对象;

15. jsonp的原理,以及为何不是真正的ajax

Jsonp原理: 利用浏览器能够动态的插入一段JS代码并执行;

为何不是真正的AJAX

  • 首先,ajaxjsonp在调用方式上虽然长得差很少(目的同样,都是请求一个url,而后把服务器返回的数据进行处理),可是ajaxjsonp本质上是不一样的东西;
  • 哪里不一样?核心不一样!ajax的核心是经过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本;
  • 此外,须要注意的是,ajaxjsonp的区别不在因而否跨域。由于ajax经过服务端代理同样能够实现跨域,jsonp自己也不排斥同域的数据的获取。还有就是jsonp是一种方式或者说是非强制协议,如同ajax同样,它也不必定非要jsonp格式来传递数据;
  • jsonp只支持get请求,ajax支持getpost请求.

16. Javascript的事件流模型都有什么

  • “事件冒泡”: 当触发一个节点的事件时,会从当前节点开始,依次触发其祖先节点的同类型事件,直到DOM根节点。(逐级向上)
  • “事件捕获”: 当触发一个节点的事件时,会从DOM根节点开始,依次触发其祖先节点的同类型事件,直到当前节点自身。(逐级向下)
  • “DOM事件流”dom同时支持两种事件模型,但捕获性事件先开始,从document开始也结束于documentdom模型的独特之处在于文本也能够触发事件。简单的说分为三个阶段:事件捕捉目标阶段事件冒泡

17. new操做符具体干了些啥

首先咱们须要明白的是:new关键字主要的做用仍是在于继承

对于const a = new Foo();new干的事情。以下代码:

const obj = new Object();   // 声明一个新的空对象obj
obj.__propto__ = Person.prototype;  // 让obj的__proto__指向函数原型的prototype

Person.call(obj); // this指向obj对象

person = obj; // 将obj对象赋值给person对象
复制代码

而后咱们来捋一捋,new一共经历了几个阶段?(4个)

  • 建立一个空对象;
  • 设置原型链;
  • Functhis指向obj,并执行Func函数体;
  • 判断Func(构造函数)的返回值类型;

18. js延迟加载的方式有哪些?

  • defer属性(页面load后执行):脚本会被延迟到整个页面都解析完毕以后再执行。如果设置了defer属性,就等于告诉浏览器当即下载,可是会延迟执行。注意defer属性只适用于外部脚本文件。
  • async 属性(页面load前执行):为了避免让页面等待脚本下载和执行,异步加载页面和其余内容。async一样也只适用于外部文件(不会影响页面加载,可是不能控制加载的顺序)。
  • 动态建立DOM方式;
  • 使用jQuerygetScript()方法;
  • 使用setTimeout延迟方法;
  • js文件最后加载。

19. Flash和ajax各自的优缺点,以及在使用中如何取舍

  • 于Flash来讲flash是个处理多媒体,矢量图形以及访问机器等;可是对于CSS,文本处理有不足,不容易被搜索;
  • 于Ajax来讲AjaxCSS,文本处理有很好的支持,亦支持搜索;可是对多媒体,矢量图形以及访问机器等不足;

共同点

  • 与服务器的无刷新传递消息;
  • 能够检测用户的离线和在线状态;
  • 能够操做DOM

20. Cookie在客户机上是如何存储的

cookies是服务器暂时放在咱们电脑里的文本文件,好让服务器来辨认咱们的计算机。

当咱们在浏览网站的时候,web服务器会先发送小部分资料放在咱们的计算机中,cookies会帮助咱们,将咱们在网站上打印的文字或一些选择记录下来,当咱们再次访问同一个网站,web服务器会先检查有没有它上次留下的cookies资料。

如有,会依据cookies里面的内容来判断使用者,从而给咱们推出相应的网页内容。

🚚...................................................ᴅᴜᴅᴜ!

21. 🤨什么是Json

  • json是一种轻量级的数据交换格式;
  • 独立于语言平台,解析器和库支持许多不一样的编程语言;
  • 它的语法表示三种类型值:简单值(numberstringbooleannull),数组,对象;

22. 线程与进程的区别

一个程序至少有一个进程,一个进程至少有一个线程。线程的划分尺度小于进程,使得多线程程序的并发性高。这里咱们能够简单的把进程理解成火车,线程理解为车箱

区别

  • 线程在进程下运行,不能单独运行(单纯的一节节车箱没法运行);
  • 一个进程能够包含多个线程(一辆火车有不少车箱);
  • 不一样进程之间的数据难以共享(列车在行驶时,乘客很难从一列火车换到另外一列火车);
  • 同一进程下的线程数据共享便捷(乘客在同一列火车上从一节车箱换到另外一节很方便);
  • 进程要比线程花费更多的计算机资源(车箱仅仅是跑,或者还要发动动力带它跑,花的力气更多);
  • 进程之间互不影响,可是同一个进程中要是有一个线程出现问题将致使整个进程有问题(一辆类车要是某一节车箱出问题好比起火,会致使火车暂停);
  • 进程能够拓展到多机,而线程最多扩展到多核cpu。(不一样的火车能够开在不一样的轨道上,而同一火车的车箱只能形式在当前火车行驶的轨道上);
  • 进程使用的内存地址能够上锁,即一个线程使用某些共享内存时,其余线程必须等它结束才能使用这块内存。(例如使用火车上的洗手间-“互斥锁”);
  • 进程使用的内存地址能够限定使用量(例如火车上的卧铺,最多只容许多少我的睡,若是安排满了就须要等待,待有空床位出来了才能进去--“信号量”);

23. 若是网页内容须要支持多语言,须要考虑些什么

  • 应用字符集的选择,选择utf-8编码;
  • 语言书写习惯以及导航结构;
  • 数据库驱动型网站;

24. JavaScrip的一些编写原则

  • 不要再同一行声明多个变量;
  • 使用 ===!== 来作比较;
  • 使用字面量的方式来建立数组、对象,来代替new Array这种形式;
  • switch语句必需要带default分支;
  • fon-in循环中的变量,用var关键字说明做用域,防止变量污染;
  • 尽量的用三元表达式代替if..else..条件语句;
  • 比较数据类型如下6中状况是falsefalse""0nullundefinedNaN;其他的都是true
  • 数据类型检测用typeof,对象类型检测用instanceof
  • 异步加载第三方的内容; ...

25. 闭包是什么,有什么特性,对页面有什么影响

闭包是可以读取其余函数内部变量的函数,使得函数不被GC回收。可是滥用闭包,会致使内存泄漏;

26. document load 和document ready的区别

  • document load:是在结构和样式,外部js和图片加载完才执行js;
  • document ready: 是dom树建立完成就执行的方法,原生是没有这种方法的。

27. 如何中断ajax请求

  • 设置超时时间让ajax自动断开;
  • 手动中止ajax请求,其核心是调用XML对象的abort方法,ajax.abort()

28. 宏任务和微任务

  • 宏任务: 当前调用栈中执行的任务称为宏任务。包括总体代码scriptsetTimeoutsetInterval
  • 微任务: 当前(这次事件循环中)宏任务执行完,在下一个宏任务开始以前须要执行的任务为微任务。包含回调事件,Promiseprocess.nextTick(node.js);

🌈🌈注意: 宏任务中的事件放在callback queue中,由事件触发线程维护;微任务的事件放在微任务队列中,由js引擎线程维护。

29. get和post的区别

  • get传参方式是经过地址栏URL传递,是能够直接看到get传递的参数,post传参方式参数URL不可见,get把请求的数据在URL后经过?链接,经过&进行参数分割。psot将参数存放在HTTP的包体内;
  • get传递数据是经过URL进行传递,对传递的数据长度是受到URL大小的限制,URL最大长度是2048个字符。post没有长度限制;
  • get回退不会有影响,post回退会从新进行提交;
  • get请求能够被缓存,post不能够被缓存;
  • get请求只URL编码,post支持多种编码方式;
  • get只支持ASCII字符,post提交没有字符类型限制;
  • get请求的记录会留在历史记录中,post请求不会留在历史记录;

30. 常见的http的响应码及含义

(1)、1xx(临时响应)

  • 100: 请求者应当继续提出请求。
  • 101(切换协议) :请求者已要求服务器切换协议,服务器已确认并准备进行切换。

(2)、2xx(成功)

  • 200: 请求成功并返回正确接口结果;
  • 201: 表示资源被正确建立。
  • 202: 请求正确,但结果正在处理中,这时候客户端能够经过轮询等机制继续请求。
  • 203: 非受权信息,服务器已成功处理了请求,但返回的信息可能来自另外一个源;
  • 204: 无内容,服务器成功处理了请求,但没有返回任何内容;
  • 205: 重置内容,服务器成功处理了请求,内容被重置;
  • 206: 部份内容,服务器成功处理了部分请求;

(3)、3xx(已重定向)

  • 300: 已经请求成功,可是有多个结果返回;
  • 301: 请求成功,可是资源被永久转移;
  • 302: 临时移动,请求的网页暂时跳转到其余页面,即暂时重定向;
  • 303: 使用get访问新的地址来获取资源;
  • 304: 请求的资源并无被修改过;
  • 305: 使用代理,请求者应该使用代理访问该页面;
  • 306: 临时重定向,请求的资源临时从其余位置响应;

(4)、4xx(请求错误)

  • 400: 请求出现错误,好比请求头不对等;
  • 401: 没有提供认证信息。请求的时候没有带上 Token 等;
  • 402: 为之后须要所保留的状态码;
  • 403: 请求的资源不容许访问,无权限;
  • 405: 方法禁用,服务器禁用了请求中指定的方法;
  • 406:不接受,没法使用请求的内容响应请求的页面;
  • 407: 请求者须要使用代理受权;
  • 408: 服务器请求超时;
  • 409: 服务器在完成请求时发生冲突;
  • 410:请求的资源已永久删除;
  • 411: 须要有效长度。服务器不接受不含有效内容长度标头字段的请求;
  • 412: 服务器未知足请求者在请求中设置的其中一个前提条件;
  • 413: 请求实体过大,超出服务器的处理能力;
  • 414: 请求网址过长,服务器没法处理;
  • 415: 请求格式不被请求页面支持;
  • 416: 页面没法提供请求的范围;
  • 417: 服务器未知足指望请求标头字段的要求;

(5)、5xx(服务器错误)

  • 500: 服务器内部错误,没法完成请求;
  • 501: 请求尚未被实现,服务器不具有完整的请求功能;
  • 502: 错误网关,服务器做为网关或代理,从上游服务器收到无效响应;
  • 503: 服务不可用;
  • 504:网关超时,服务器做为网关或代理。可是没有及时从上游服务器收到请求;
  • 505HTTP版本不支持,服务器不支持请求中所用的HTTP协议版本。

🚚...................................................ᴅᴜᴅᴜ!

31. 😤IE和DOM事件流的区别

  • 从执行顺序看IE采用的是冒泡型事件,而DOM是先捕获后冒泡事件;

咱们能够看个例子:

<body> 
<div> 
<button>点击</button> 
</div> 
</body> 

// 冒泡型事件模型: button->div->body (IE事件流) 
// 捕获型事件模型: body->div->button (Netscape事件流) 
// DOM事件模型: body->div->button->button->div->body (先捕获后冒泡) 
复制代码
  • 参数方面看,低版本的ie没有回调函数,只能进行冒泡;
  • 从第一个参数是否加"on"问题看,低版本IE不支持addEventListener(),支持attachEvent,第一个参数须要加on
  • 从this的指向问题看IE指向windows,不指向触发的函数;

32. javascript是一种什么样的语言

  • 解释性脚本语言,代码不能进行预编译;
  • 主要用来向html页面添加交互行为;
  • 能够直接嵌入到html页面,或单独写成js文件。建议单独写成文件,有利于结构和行为分离,利于维护;
  • 跨平台性,在绝大多数浏览器支持下,能够在多种平台下运行,例如windowslinux等;

33. DOM和BOM是什么

首先咱们须要知道:javascript是由ECMAScript,DOM,BOM三部分构成的

  • ECMAScript是一种语言,是对规定的语法,操做,关键字,语句的一个描述,javascript实现了ECMAScript;
  • DOM是文档对象模型,包括了获取元素,修改样式以及操做元素等三方面的内容,也是一般咱们用的最多的操做,其提供了不少兼容性的写法;
  • BOM是浏览器对象模型,包括浏览器的一些操做,window.onload, window.open等还有浏览器时间,监听窗口的改变onresize,监听滚动事件onscroll等;

34. 如何实现多个标签之间的通讯

  • 调用 localStorage

(1)、在一个标签内使用localStoragesetItem(key, value)添加(删除或修改)内容;

(2)、在另外一个标签页面监听storage事件;

(3)、获得localStorage存储的值,便可实现不用页面之间的通讯。

  • 调用 cookie+setInterval()

(1)、将要传递的信息存储在cookie中,能够设置定时读取cookie的信息,便可随时获取想要传递的信息。

  • 使用 Webworker

(1)、webworker做为浏览器的一个新特性,能够提供一个额外的线程来执行一些js代码,而且对浏览器用户界面不影响;

(2)、普通的Webworkernew worker()便可建立,这种webworker是当前页面专有的。而后还有种共享worker(SharedWorker),这种是能够多个标签页、iframe共同使用;

  • 使用 SharedWorker

(1)、SharedWorker能够被多个window共同使用,但必须保证这些标签页都是同源的(相同的协议,主机和端口号);

35. 哪些操做会形成内存泄露

内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。

如下几点回形成内存泄露:

  • 过量使用闭包会引发内存泄露(解决:将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对dom的引用);
  • 控制台日志(解决:项目完成后记得删除多余的控制台打印);
  • 循环,也就是两个对象彼此引用且彼此保留;
  • setTimeout的第一个参数是字符串而不是函数的时候也会形成内存泄露(解决:尽可能不要讲第一个参数定义为字符串);
  • 意外的全局变量也会引发内存泄漏(解决:使用严格模式避免)。
  • 没有清理DOM元素(解决: 手动删除);

36. js垃圾回收的几种方式

javascript具备自动垃圾回收机制,垃圾器回收会按照固定的时间间隔周期性的执行。

常见的垃圾回收机制有两种: 标记清除引用计数

标记清除

原理: 当变量进入环境时,将这个变量标记为“进入环境”。当变量离开时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。

工做流程

  • 垃圾回收器,在运行的时候会给存储在内存中的全部变量都加上标记;
  • 去掉环境中的变量以及被环境中的变量引用的变量的标记;
  • 再被加上标记的会被视为准备删除的变量;
  • 垃圾回收器完成内存清除工做,销毁那些带标记的值并回收他们所占用的内存空间;

引用计数

原理: 跟踪记录每一个值被引用的次数,声明一个变量,并将引用 类型赋值给这个变量,则这个值的引用次数+1,当变量的值变成了另外一个,则这个值的引用次数-1,当值的引用次数为0的时候,就回收。

工做流程

  • 声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用值的引用次数就是1
  • 同一个值又被赋值给另外一个变量,这个引用类型值此时的引用次数+1
  • 当包含这个引用类型值的变量又被赋值成另外一个值,那么这个引用呢性值的引用次数-1
  • 当引用次数变成0时,说明目前没法访问此值;
  • 当垃圾收集器下一次运行时,它会释放引用次数是0的值所占的内存;

37. 什么放在内存中?什么不放在内存中?

  • 基本类型(Boolean, String, Number, Null, Undefined, Symbol(新增))的值保存在内存中。从一个变量向另外一个变量赋值基本类型的值,会建立这个值的一个副本;
  • 引用数据类型(object)的值是个对象,保存在堆内存中

🌈🌈注意

  • 包含引用类型值的变量实际上包含的并非对象自己,而是一个指向该对象的指针。从一个变量向另外一个变量复制引用类型的值,复制的实际上是指针,所以两个变量最终指向的都是同一个对象;
  • javascript不容许直接访问内存中的位置,也就是不能直接访问操做对象的内存空间。在操做对象时,实际上在操做对象的引用而不是实际的对象;

38. 堆和栈的区别

(1)、堆和栈空间分配的区别

  • 堆(操做系统): 通常由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式相似于链表;
  • 栈(操做系统): 由操做系统自动分配释放,存放函数的参数值,局部变量的值等。其操做方式相似于数据结构中的栈;

(2)、堆和栈缓存方式的区别

  • 堆是存放在二级缓存中的,声明周期由虚拟机的垃圾回收算法决定(这里,并非成为孤儿对象就能被回收)。因此调用这些对象的速度要相对来的低一些;
  • 栈使用的是一级缓存,它们一般都是被调用时处于缓存空间中,调用完毕当即释放;

(3)、堆和栈结构区别

  • 堆(数据结构):堆能够被当作是一棵树,如: 堆排序;
  • 栈(数据结构):是一种先进后出的数据结构;

39. 在浏览器中输入URL到整个页面显示在用户面前时这个过程当中到底发生了什么(详解)

(1)、DNS解析

  • 检查浏览器自身的DNS缓存;
  • 若没有,搜索操做系统自身的DNS缓存;
  • 若没有,尝试读取hosts文件;
  • 若没有,可向本地配置的首选DNS服务器发起请求;
  • .win系统若没有好到,能够操做系统查找NetBIOS name cache或查询wins服务器或广播查找或读取LMHOSTS文件;

(若以上都没有,则解析失败)

(2)、TCP三次握手

(3)、浏览器向服务器发送http请求

一旦创建了TCP连接,web浏览器就会向web服务器发送请求命令。

(4)、浏览器发送请求头信息

浏览器发送其请求命令以后,还要以头信息的形式想web服务器发送一些别的信息,以后浏览器发送了一空白行开通知服务器,它已经结束了该头信息的发送。

(5)、服务器处理请求

服务器收到http请求以后,肯定用相应的一眼来处理请求。读取参数并进行逻辑操做后,生成指定的数据。

(6)、服务器作出响应

客户端向服务器发送请求后,服务端向客户端作出应答。

(7)、服务器发送应答头信息

正如客户端会随同请求发送关于自身的信息同样,服务器也会随同应答向用户发送关于它本身的数据以及被请求的文档。

(8)、服务器发送数据

web服务器向浏览器发送信息后,它会发送一个空白行来表示头信息的发送到此结束。接着,它会以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。

(9)、 TCP关闭(四次挥手)

通常状况下,一旦web服务器向浏览器发送了请求数据,它就要关闭tcp连接。若是浏览器或服务器在其头信息加入了Connection:keep-alive,则会保持长链接状态,也就是TCP连接在发送后仍保持打开状态,浏览器能够继续经过仙童的连接发送请求。

(优势:保持连接节省了为每一个请求创建新连接所属的时间,还节约了网络宽带 )

40. 继承的方法有哪些

  • 原型链继承;
  • 构造函数继承;
  • 实例继承;
  • 组合继承;
  • 拷贝继承;
  • 寄生组合继承;

🚚...................................................ᴅᴜᴅᴜ!

41. 🥴JavaScript和ASP脚本相比,哪一个更快

通常状况下,javascript会更快。javascript是一种客户端语言,所以它不须要web服务器的协助来执行。另外一方面,ASP是服务端语言,所以老是比javascript慢。可是须要注意的是:javascript如今也能够用于服务端语言(例如nodejs)。

42. Java和JavaScript之间的区别

  • 首先,java是一门十分完整,成熟的编程语言;相比之下,javascript是一个能够被引入HTML页面的编程语言。这两种语言并非彻底相互依赖的,而是真对不一样的意图而设计的。
  • 其次,java是一种面向对象编程(OOPS)或结构化的编程语言,相似于C++C;而javascript是客户端脚本语言,它被称为非结构化编程。

43. 什么是负无穷大

负无穷大是javascript中的一个数字,能够经过将负数除以零获得。

44. 什么是未声明和未定义的变量

  • 未声明的变量是指程序中不存在且为声明的变量。若是程序尝试读取为声明的变量的值,运行会报错;
conosle.log(b);

// Uncaught ReferenceError: conosle is not defined
    at <anonymous>:1:1
复制代码
  • 未定义的变量是在程序中声明可是还没有赋予任何值的变量。若是程序中使用了未定义的变量的值,会返回一个undefined
let c;
console.log(c);  // undefined
复制代码

45. javascript中有几种定时器以及其如何工做

定时器用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码。经过函数setTimeoutsetIntervalclearInterval来完成。

  • setTimeoutfunctiondelay)函数用于移动在所述延迟以后调用特定功能的定时器;
  • setIntervalfunctiondelay)函数用于在提到的延迟中重复执行给定的功能,只有在取消时才能中止;
  • clearIntervalid)函数指示定时器中止;

🌈🌈注意: 定时器在一个线程内运行,所以事件可能须要排队等待执行;

46. ViewState和SessionState有什么区别

  • ViewState:特定于会话中的页面;
  • SessionState: 特定于可在web应用程序中的全部页面上访问的用户特定数据;

47. delete操做符的功能是什么

delete操做符用于删除程序中的全部变量或对象,可是不能删除使用var关键字声明的变量。

48. 5 + 8 + '7' 和 5 + '8' + 7 的结果是啥

console.log(5 + 8 + '7');  // 137
console.log(5 + '8' + 7);  // 587
复制代码

能够这样理解:连续的整数能够直接相加,字符串直接相连。

49. 在JavaScript中使用innerHTML的缺点是什么

  • 内容随处可见;
  • 不能像‘追加到innerHTML’同样使用;
  • 即便使用+=like "innerHTML = innerHTML + 'html'",旧的内容仍然会被html替换;
  • 整个innerHTML内容被从新解析并构建成元素,所以它的速度会慢不少;
  • innerHTML不提供验证,所以可能会在文档中插入有效的和破坏性的HTML并将其中断;

50. JavaScript中不一样类型的错误有几种

JS的错误类型通常包含六种常见的派生错误以及手动抛出错误类型。

(1)、常见的几种错误类型

  • SyntaxError: 语法错误,通常指解析代码时发生的语法错误;
  • ReferenceError:引用错误,通常指引用一个不存在的变量时发生的错误。
  • TypeError: 类型错误,通常是变量或参数不是预期类型时发生错误。
  • EvalError eval(): 函数执行错误,通常指当eval()函数没有被正确执行时,会抛出evalError错误;
  • RangeError: 范围错误,通常指当一个值超出有效范围时发生的错误。

🚚...................................................ᴅᴜᴅᴜ!

51. 🥱延迟脚本在JavaScript中的做用

通常状况下,当页面首先加载脚本时,加载期间页面的HTML代码将会暂停解析,直到脚本加载完才能执行。

因此会出现这么一种状况,就是当服务器速度很慢或者脚本很沉重的状况下,会致使网页延迟。在使用Defer时,脚本会延迟执行直到html解析器运行完成。这极大程度上减小了加载时间,提高了显示速度。

52. decodeURI()和encodeURI()是什么

encodeURI()用于将URL转为十六进制编码,而decodeURI()用于将编码的URL转换成正常的URL

53. hash(哈希)表是什么

哈希表(亦称散列表),是根据关键码值直接进行访问的数据结构。也就是说,它经过把关键码映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数也称散列函数,存放记录的数组叫作散列表。

54. 节点有几种类型(三种)

  • 元素节点: nodeType === 1;
  • 属性节点: nodeType === 2
  • 文本节点: nodeType === 3

55. innerHTML和outerHTML的区别

  • innerHTML(元素内包含的内容);
  • outerHTML(本身以及元素内的内容);

56. offsetWidth offsetHeight和clientWidth clientHeight间的区别

  • offsetWidth/offsetHeightcontent宽/高 + padding宽/高 + border宽/高);
  • clientWidth/clientHeight (content宽/高 + padding宽/高);

57. 几种减低页面加载时间的方法

  • 压缩CSSJS文件;
  • 合并CSSJS文件,减小http请求;
  • 外部JSCSS放在最底层;
  • 减小DOM操做,尽量使用变量代替没必要要的DOM操做;
  • 优化图片文件,减少其尺寸,特别是缩略图;
  • 使用多域名负载网页内的多个文件、图片;
  • 服务器开启gzip压缩;

58. 描述AJAX的工做原理

  • 第一步: 建立AJAX对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp));
  • 第二步: 使用open打开链接,格式为open(请求方式,'请求路径',同步/异步);
  • 第三步: 发送send();
  • 第四步:当ajax对象完成第四步(onreadystatechange),数据接收完成。再判断对象状态码(readystate) 当状态码为成功接收的状态码时,HTTP响应彻底接收 。 再判断http响应状态(200-300之间或者304),(缓存)执行回调函数 获取的数据转成字符串格式(responseText)

缺点

  • 对搜索引擎不友好;
  • 跨域问题的限制;
  • 要实现ajax下的先后退功能成本比较大;

59. http的cache机制,以及200状态下如何实现 from cache

含义

浏览器缓存(Browser Caching)是为了加速浏览,浏览器在用户磁盘上岁最近请求过的文档进行存储,当用户再次访问这个文档时,浏览器会从本地磁盘显示此文档,从而提高页面加载速率。

cache的做用

  • 减小延迟,让网站的运行速度更快,带来更好的用户体验;
  • 避免网络拥塞,减小请求量,减小输出带宽;

实现手段

cache-control中的max-age是实现内容cache的重要手段,经常使用的策略有如下三种:

  • max-ageETag的组合;
  • max-age
  • max-ageLast-Modified(If-Modified-Since)的组合;

拓展

在此,拓展一下有关强制缓存(200)和协商缓存(304)部分的内容。

  • 强制缓存(也称强缓存),指当浏览器去请求某个文件的时候,服务端就在respone header里面对该文件作了缓存配置。强制缓存不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中能够看到该请求返回200的状态码;
  • 协商缓存:强制缓存给资源设置了过时时间,在未过时时,能够说是给用户自给自足用的。可是当资源过时时,就须要去请求服务器,这时候请求服务器的过程就能够设置成协商缓存。协商缓存就是须要客户端和服务端进行交互的。协商缓存将缓存信息中的EtagLast-Modified经过请求发给服务器,由服务器校验,返回状态码304时,浏览器就能够直接使用缓存。

共同点: 都是从客户端中读取数据;

区别: 强缓存不会发出请求,协商缓存会发出请求。

缓存中header(头部)的参数:

(1)、强制缓存:

  • Expires(经常使用):response header里的过时时间,浏览器再次加载资源时,若是在这个过时时间内,则命中强缓存。
  • Cache-Control(经常使用):当值设为max-age=120时,则表明在这个请求正确返回时间(浏览器也会记录下来)的2分钟内再次加载资源,就会命中强缓存。
  • no-cache:不使用本地缓存。须要使用缓存协商,来验证是否过时;
  • no-store:不可缓存;
  • public:客户端和代理服务器均可缓存;
  • private:只能有客户端缓存;

(2)、协商缓存

  • Etag:即文件hash,每一个文件惟一。web服务器响应请求时,告诉浏览器当前资源在服务器的惟一标识(生成规则由服务器决定);
  • If-None-Match:当资源过时时(使用Cache-Control标识的max-age),发现资源具备Etag声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定是否命中协商缓存;
  • Last-Modify/If-Modify-Since:文件的修改时间,精确到秒。浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-ModifyLast-modify是一个时间标识该资源的最后修改时间;当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存以前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存;

🌈🌈注意

  • Etag要优于Last-Modified
  • 在优先级上,服务器校验优先考虑Etag
  • 在性能上,Etag要逊于Last-Modified

60. 什么是虚拟DOM,为何要使用以及和真实DOM的区别

含义及使用

这里,小编的理解是:虚拟DOM是真实DOM的内存表示,是一种编程概念,一种模式。它的做用是判断DOM是否改变、哪些部分须要被从新渲染。这样,不须要操纵真实的DOM,同时极大的提升了React的性能。

虚拟DOM使用diff算法,当咱们屡次修改某一部分的内容时,首先在虚拟DOM树从上至下进行同层比对(不影响真实DOM),上层发生变化,下层从新渲染,直到最后修改完成,再在真实DOM中渲染。

使用虚拟DOM的缘由是,能够极大程度上减小DOM节点的回流和重绘问题,节约资源,提高运行效率。

区别

  • 虚拟DOM不会进行重排和重绘;
  • 虚拟DOM进行频繁的修改,而后一次性比较并修改真实DOM中须要修改的部分,最后进行回流和重绘,有效的减小了过多DOM节点回流和重绘资源消耗的问题;
  • 虚拟DOM有效下降大面积(真实DOM节点)的回流和重绘,由于最终与真实DOM比较差别,能够局部渲染。

🚚...................................................ᴅᴜᴅᴜ!

61. 🤫跨域以及解决办法

协议、域名、端口号不一样--跨域(也能够理解为协议、域名、端口号相同--同源策略)

解决跨域的几种办法

  • document.domain + iframe(只有在主域相同的状况下才能使用);
  • 动态建立script
  • location.hash + iframe;
  • window.name + iframe;
  • postMessageHTML5中的XMLHttpRequest Level 2中的API);
  • CORS(跨域资源共享);
  • jsonp;
  • websockets;

62. 常谈的CSRF和XSS

XSS(Cross Site Scripting)

跨站脚本攻击,黑客将恶意脚本代码植入到页面中从而实现盗取用户信息等操做(注意这里操做的是用户,攻击的方式只是代码的嵌入)。

预防措施

  • 对输入,输出的结果进行必要的转义;
  • 尽可能使用post,对get使用时尽可能对路径长度作限制;
  • 使用httponly来方式黑客经过脚本获取用户cookie数据。
  • 于客户自己,养成良好习惯,提升警戒,不随意点来陌生连接;

CSRF(cross-site request forgery)

跨站请求伪造,黑客假装成用户身份来执行一些非用户自愿的恶意以及非法操做(注意,这里是黑客假装成用户操做)。

预防措施

  • 运用验证码;
  • 使用token id令牌;
  • 判断请求的reFerer是否正确;

区别

  • CSRF须要登录后操做,XSS不须要;
  • CSRF是请求页面api来实现非法操做,XSS是向当前页面植入js脚原本修改页面内容。

63. 如何看待AMD和CommonJS

浏览器端异步和服务器端同步的模块化编程规范。

CommonJS:是为了解决 JavaScript 的做用域问题而定义的模块形式,可使每一个模块它自身的命名空间中执行。该规范的主要内容是,模块必须经过 module.exports 导出对外的变量或接口,经过 require() 来导入其余模块的输出到当前模块做用域中,module标识模块自己。

AMD:是全局定义的,当即执行函数提供 moduleexports 两个外部变量,模块就放在这个当即执行函数里面。模块的输出值放在 module.exports 之中,这样就实现了模块的加载。

64. 有几种匿名函数(没有定义函数名的函数)用例

  • 定义回调函数;
  • 当即执行函数;
  • 做为返回值的函数;
  • 使用方法为 var func = function() {};定义的函数;

65. null,undefined 或 undeclared的区别以及如何检测

区别

  • null: 未定义的属性;
  • undefined: 定义可是为赋值的为undefined
  • undecleared: javascript访问不会报错;

检测方式

  • null是一种特殊的object,表示无值;
console.log(typeof null);  // object

const a = null;
if(!a && typeof(a) !== 'undefined' && a!==0) {
    alert('a is null')
} else {
     alert('a is not null')
}
复制代码
  • undefined: 是声明但未赋值的变量;
const a = undefined;
if(typeof(a) === 'undefined') {
    alert('a is undefined')
} else {
     alert('a is not undefined')
}
复制代码
  • undeclaredundeclared 是未声明也未赋值的变量,JavaScript访问会报错。

67. 可变 (mutable) 和不变 (immutable) 对象的区别

  • 可变(mutable): 在JS中,对象是引用类型的数据,其优势在于频繁的修改对象时都是在原对象的基础上修改的,并不须要进行从新建立,这样就能够有效的利用内存,不会形成内存空间的浪费;
  • 不可变(immutable): 每一次修改一个immutable对象时,都会建立一个新的不可变对象,在新对象上的操做不会影响到原对象的数据。

68. 使用 Promises 而非回调 (callbacks) 优缺点是什么

Promise是异步编程的一种解决方案,比传统的解决方案 回调函数和事件 更合理和更强大。它由社区最先提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。

所谓Promise,简单说就是一个容器,里面保存着某个将来才会结束的事件(一般是一个异步操做)的结果。从语法上说,Promise是一个对象,从它能够获取异步操做的消息。Promise提供统一的API,各类异步操做均可以用一样的方法进行处理。

有了Promise对象,就能够将异步操做以同步操做的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操做更加容易。

Promise同时存在一些缺点,例如:

  • 第一: 没法取消Promise,一旦新建它就会当即执行,没法中途取消;
  • 第二:若是不设置回调函数,Promise内部抛出的错误,不会反应到外部;
  • 第三:当处于Pending状态时,没法得知目前进展到哪个阶段(刚刚开始仍是即将完成)。

69. 浏览器特性检测,特性推断和浏览器 UA 字符串嗅探的区别

  • 特性检查更适合针对实现了特定特性的浏览器进行操做。
  • UA字符串因为被浏览器厂商能够随意修改,所以给使用者的感受不太靠谱。

70. 理解 Function.prototype.bind

Function.prototype.bind方法会建立一个新的函数,当这个新函数被调用时,它的this值是传给bind()的第一个参数,它的参数是bind()的其它参数和其本来的参数。

71. 持续更新ing🍀🍀

⏳⏳ ......

写在最后

关于javascript部分的整理,就先整理到这里吧,后继会持续更新。有关开发性能优化篇小编还在整理当中,可是因为最近项目压身,可能会延迟一丢丢吧(生活不易且珍惜🌻🌻)。

整理的过程当中,不免会有疏漏,如果看到有误或者须要补充的知识点,欢迎留言小编💌💌。

相关文章
相关标签/搜索