js高频面试题

一. 闭包

概念:闭包我的理解就是能够读取其他函数内部变量的函数。

1.两种存在形式:
函数作为返回值时 和 函数作为参数传递时
2.闭包的用途:
闭包可以读取函数内部的变量,可以让变量的值始终保持在内存中。
3.闭包有三个特性:
(1)函数嵌套函数
(2)函数内部可以引用外部的参数和变量
(3)参数和变量不会被垃圾回收机制回收

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
面试题:
下面代码的输出及结果是什么?(涉及闭包问题)
答:输出10次10
原因:

setTimeout是一次执行函数数),setTimeout里面的function1秒后执行,也就是说i从0~9时,一共执行了10次的setTimeout()函数,此时的i的值是10,由于for语句的执行速度远小于1秒,所以,1秒后,由setTimeout()函数定时触动的闭包函数function()开始执行,alert(i);i的值已经是10了,所以相继打印10次i.

<script>
    for(var i=0;i<10;i++){ 
        setTimeout(function(){ 
            alert(i); 
        },1000); 
    } 
</script>

改变:想要输出0~9

<script>
	for(var i=0;i<10;i++){
	(function(i){
		setTimeout(function(){
		 alert(i);
		},1000);
	})(i)
	}
</script>

二.js的作用域作用域链

1.作用域:
浏览器给js的一个生存环境(栈内存)。
2.作用域链:
js中的关键字var和function 都可以提前声明和定义,提前声明和定义的放在我们的内存地址(堆内存)中。然后js从上到下逐行执行,遇到变量就去内存地址查找是否存在这个变量。有就使用,没有就继续向父级作用域查找直到window下结束,这种查找机制叫作用域链.
面试题:

<script>
    var a = 123;
    //只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量“提前声明”
    function fun(){
        alert(a);
        var a = 456;  //此处为局部变量,不写var是全局
    }
    fun();
    alert(a);
    //undefined
    //123
</script>

三.js的原型原型链

1.在原型对象里面有一个属性constructor属性指向了构造函数。
2.每个构造函数都有一个prototype属性,我们称之为显式原型对象
3. 每个对象都有一个隐式原型 _ proto _ ,指向的是构造该对象的构造函数的原型对象。

原型对象也是对象,所以如果我们让原型对象指向另外的一个实例,这个实例也有自己的原型对象,如果这个实例的原型对象又等于了另外的实例,一层层下去就形成了一个链条。这就是所谓的原型链。

在这里插入图片描述
在这里插入图片描述

四.js的基础类型和引用类型

1.基本类型值指的是简单的数据段(基本数据类型传的是值)
2.引用类型值指那些可能由多个值构成的对象(引用数据类型传的是地址)。

基本数据类型包括  number string boolean undefined  null 

引用类型包括:array  object function

五.请求get与post的区别

  1. get请求可以主动被浏览器缓存,post请求无法缓存,除非是手动去设置。
  2. get请求的在浏览器回退时候是无害的的,而post会再次请求。
  3. get请求通过url传递,post直接放在请求头中。
  4. get只能支持url编码,post支持多种编码方式。
  5. get请求在浏览器中有长度限制(ie大概为2kb),post不存在。

六.js实现继承

  1. 原型链继承 (子类型的所有实例都可以共享父类型的属性)
  2. 构造函数继承(方法都在构造函数中定义,函数复用变得没有意义)
  3. 组合继承(原型链继承+构造函数继承)(在子类原型上创建不必要的多余的属性,2次调用父类构造函数)
  4. Object.create(原型式继承)
  5. 寄生式继承
  6. 寄生组合式继承

七.call、bind、apply区别(改变this指向)

this指向-谁调用,指向谁
apply和call为立即调用,bind返回对应函数,稍后调用

  • call
    • 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
    • 说明:第一个参数表示this指向新目标,后面相当于传参,以逗号隔开。
  • bind
    • 语法:bind(thisArg[, arg1[, arg2[, …]]])
    • 说明:会创建一个新函数(当调用时,会以创建时传入bind()的第一个参数作为this;多次bind无效,按第一次为准)
  • apply
    • 语法:apply([thisObj[,argArray]])
    • 说明:第一个参数为this新指向,第二个参数以数组方式传参

八.this指向问题

this指向-谁调用,指向谁
1)全局环境就是在里面,这里的this始终指向的是window对象;
2)局部环境里的this,在全局作用域下直接调用函数,this指向window;
3)对象函数调用,哪个对象调用this就指向哪个对象
4)使用 new 实例化对象,在构造函数中的this指向实例化对象。

九.浏览器的回流(重排)和重绘

重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置)

  1. 重排(Reflow):当渲染树的一部分必须更新并且节点的尺寸发生了变化,浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。
  2. 重绘(Repaint):是在一个元素的外观被改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。比如改变某个元素的背景色、文字颜色、边框颜色等等
  3. 引发重排
    1.添加、删除可见的dom
    2.元素的位置改变
    3.元素的尺寸改变(外边距、内边距、边框厚度、宽高、等几何属性)
    4.页面渲染初始化
  4. 引发回流
    1、添加或者删除可见的DOM元素;
    2、元素位置改变;
    3、元素尺寸改变——边距、填充、边框、宽度和高度
    4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;
    5、页面渲染初始化;
    6、浏览器窗口尺寸改变——resize事件发生时;

十.浏览器的同源策略

同源是浏览器最核心也最基本的安全功能,所谓同源是指域名,协议,端口相同

十一.跨域问题

  1. 跨域是由浏览器的同源策略引起的

首先跨域问题是由于浏览器协议,域名,端口,三者有其中一个不一致就属于跨域。

  1. 解决跨域:
  • JSONP跨域
    • JSONP实现跨域请求的原理:简单的说,就是动态创建script标签,然后利用script标签的 src 属性不受同源策略约束来跨域获取数据。
    • 缺点:JSONP只支持get请求、不支持post请求。
    • 组成:回调函数 和 数据。回调函数是用来处理服务器端返回的数据,回调函数的名字一般是在请求中指定的。而数据就是我们需要获取的数据,也就是服务器端的数据。
    • 实现:
 <script>
    function dosomething(jsonData){
    }
</script>
<script src="http://www.b.com/handlerData.php?
   callback=dosomething">
</script>
  • CORS方案
    • CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。
    • 请求方式:post
  header("Access-Control-Allow-Origin", "*");   
  //“*”号表示允许任何域向我们的服务端提交请求
  • document.domain+iframe

十二.浏览器输入url之后最后网页渲染出来经过了什么

  1. 查询ip地址
  2. 建立tcp连接,接入服务器
  3. 浏览器发起http请求
  4. 服务器后台操作并做出http响应
  5. 网页的解析与渲染

十三.浏览器如何渲染页面(加载顺序)

在这里插入图片描述

十四.JS中的DOM和BOM

  1. ECMAScript 基本语法。

  2. BOM (浏览器对象模型)

  3. DOM (文档对象模型)
    (1)CreateElement建一个元素节点
    (2)createTextNode创建一个文本节点
    (3)appendChild添加子节点
    (4)removeChild 删除子节点
    Document:是根节点
    ParentNode:获取父节点
    childNodes:获取所有子节点
    firstChild:第一个子节点
    lastChlid:获取最后一个子节点

十五.垃圾回收机制

原理:
垃圾收集器会定期找出那些不再继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

十六ajax请求详细怎么实现

  1. 创建XMLHttpRequest对象
  2. 注册回调函数
  3. 配置请求信息,open(),get
  4. 发送请求 send
  5. 根据不同的响应进行处理
    取得返回的数据(responseText),请求完成并成功返回(xmlHttp.readyState == 4, xmlHttp.status == 200);对象处理状态:
      0- (未初始化)还没有调用send()方法
      1 - (载入)已调用send()方法,正在发送请求
      2 - (载入完成)send()方法执行完成,
      3 - (交互)正在解析响应内容
      4 - (完成)响应内容解析完成,可以在客户端调用了
//第一步,创建XMLHttpRequest对象
var xmlHttp = new XMLHttpRequest();
function CommentAll() {
    //第二步,注册回调函数
    xmlHttp.onreadystatechange = callback1;
    //{
    //    if (xmlHttp.readyState == 4)
    //        if (xmlHttp.status == 200) {
    //            var responseText = xmlHttp.responseText;

    //        }
    //}
    //第三步,配置请求信息,open(),get
    //get请求下参数加在url后,.ashx?methodName = GetAllComment&str1=str1&str2=str2
    xmlHttp.open("post", "/ashx/myzhuye/Detail.ashx?methodName=GetAllComment", true);

    //post请求下需要配置请求头信息
    //xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    //第四步,发送请求,post请求下,要传递的参数放这
    xmlHttp.send("methodName = GetAllComment&str1=str1&str2=str2");//"
}
//第五步 根据不同的响应进行处理
function callback1() {
    if (xmlHttp.readyState == 4)
        if (xmlHttp.status == 200) {
            //取得返回的数据
            var data = xmlHttp.responseText;
            //json字符串转为json格式
            data = eval(data);
            $.each(data,
                function (i, v) {
                    alert(v);
                });
        }
}

十七.事件委托、事件冒泡、事件捕获

1.事件冒泡:
javascript的事件传播过程中,当事件在一个元素上出发之后,事件会逐级传播给先辈元素,直到document为止,有的浏览器可能到window为止,这就是事件冒泡现象。
使用stopPropagation来阻止事件的冒泡
preventDefault阻止浏览器的默认行为

2.事件委托:
事件委托又可以叫事件代理,事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。(减少dom操作,提高网页性能)
3.事件捕获:
事件捕获恰好与事件冒泡相反,它从顶层祖先元素开始,直到事件触发元素

十八.js中创建对象方法(new与object.create区别)

  1. {} // 对象字面量
  2. new Object()
  3. Object.create() 1和2的区别很小,1不能传参,2可以传参。

new 与 Object.create()的区别

  1. new过程
  1. 创建一个新对象
  2. 将新对象的原型指向构造函数的原型
  3. 执行构造函数,绑定this
  4. 返回这个对象
var obj = new Object()
obj._proto_ = Car.prototype
// 执行构造函数, 绑定this
Car.call(obj)

它调用了对象的构造函数,并通过call将obj的this绑定到了对象上

2.object.create()

var f = function() { }
f.prototype = Car
return new f()

它同样是创建一个新对象,将新对象的原型关联到构造函数
在Object.create的内部,并没有去调用Car构造函数,而是调用了创建新对象的构造函数,因此Car上的属性不会继承到Object.create创建的实例中

十九.new一个对象的过程

  1. 创建一个空对象 (varobj=new Object();)
  2. 设置原型链 obj.proto= Func.prototype;
  3. 让Func中的this指向obj,(使用call方法)并执行Func的函数体。 var result =Func.call(obj);
  4. 判断Func的返回值类型:如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。

二十.箭头函数与普通函数区别

  1. 普通函数中的this指向函数被调用的对象,因此对于不同的调用者,this的值是不同的。
  2. 箭头函数中并没有自己的this(同时,箭头函数中也没有其他的局部变量,如this,argument,super等),所以箭头函数中的this是固定的,它指向定义该函数时所在的对象。

二十一. setTimeout与setInterval

setInterval实现的是根据给定的时间间隔,每隔一段时间调用一次函数或执行一次代码。
setTimeout实现的是根据给定的时间,在经过该时间之后只调用一次函数或执行一次代码。

二十二.本地浏览器存储

js中包含sessionStorage和localStorage以及cookie三种浏览器端的数据存储方式。
共同点:都是保存在浏览器端,且同源的。
区别:

  1. cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有网址路径(path)的概念,可以限制cookie只属于某个网址路径下。
  2. 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
  3. 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
  4. 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值