前端面试题快问快答(3)

162 阅读6分钟

闭包?

  • 闭包就是能够读取其他函数内部变量的函数
  • 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常⻅的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量 , 利用闭包可以突破作用链域
  • 闭包的特性:
    • 函数内再嵌套函数
    • 内部函数可以引用外层的参数和变量
    • 参数和变量不会被垃圾回收机制回收

说说你对闭包的理解

  • 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在 js 中,函数即闭包,只有函数才会产生作用域的概念
  • 闭包 的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中
  • 闭包的另一个用处,是封装对象的私有属性和私有方法
  • 好处:能够实现封装和缓存等
  • 坏处:就是消耗内存、不正当使用会造成内存溢出的问题 使用闭包的注意点
  • 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网⻚的性能问题,在 IE 中可能导致内存泄露
  • 解决方法是,在退出函数之前,将不使用的局部变量全部删除

说说你对作用域链的理解?

  • 作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到 window 对象即被终止,作用域链向下访问变量是不被允许的
  • 简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可⻅性和生命周期

JavaScript 原型,原型链 ? 有什么特点?

  • 每个对象都会在其内部初始化一个属性,就是 prototype ( 原型 ) ,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去 prototype 里找这个属性,这个prototype 又会有自己的 prototype ,于是就这样一直找下去,也就是我们平时所说的原型链的概念

  • 关系: instance.constructor.prototype = instance.__proto__

  • 特点:

    • JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变
  • 当我们需要一个属性的时, Javascript 引擎会先看当前对象中是否有这个属性, 如果没有的,就会查找他的 Prototype 对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。

请解释什么是事件代理?

事件代理( Event Delegation ),又称之为事件委托。是 JavaScript 中常用绑定事 件的常用技巧。顾名思义, “ 事件代理 ” 即是把原本需要绑定的事件委托给父元素,让父元 素担当事件监听的职务。

事件代理的原理是 DOM 元素的事件冒泡。

使用事件代理的好处是

  • 可以提高性能
  • 可以大量节省内存占用,减少事件注册,比如在 table 上代理所有 td 的 click 事件就非常棒
  • 可以实现当新增子对象时无需再次对其绑定

事件模型?

中定义事件的发生经历三个阶段:捕获阶段( capturing )、目标阶段( targetin )、冒泡阶段( bubbling )

  • 冒泡型事件:当你使用事件冒泡时,子级元素先触发,父级元素后触发

  • 捕获型事件:当你使用事件捕获时,父级元素先触发,子级元素后触发

  • DOM 事件流:同时支持两种事件模型:捕获型事件和冒泡型事件

  • 阻止冒泡:在 W3c 中,使用 stopPropagation() 方法;在 IE 下设置 cancelBubble = true

  • 阻止捕获:阻止事件的默认行为,例如 click - <a> 后的跳转。在 W3c 中,使用 preventDefault() 方法,在 IE 下设置 window.event.returnValue = false

Ajax 原理?

  • AJax的原理简单来说是在用户和服务器之间加了 — 个中间层 ( AJAX 引擎 ) ,通过XmlHttpRequest 对象来向服务器发异步请求,从服务器获得数据,然后用 javascrip t来操作 DOM 而更新⻚面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据。
  • Ajax 的过程只涉及 JavaScript 、 XMLHttpRequest 和 DOM 。 XMLHttpRequest 是aja x 的核心机制。
/** 1.创建连接**/
var xhr = null;
xhr = new XMLHttpRequest()
/** 2.连接服务器**/
xhr.open('get', url, true)
/** 3.发送请求 **/
xhr.send(null);
/** 4.接受请求 **/
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
    if(xhr.status == 200){
    success(xhr.responseText);
           } else {
/** false **/
    fail && fail(xhr.status);
        }
    }
}

为什么要有同源限制?

同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议举例说明:比如一个黑客程序,他利用 Iframe 把真正的银行登录⻚面嵌到他的⻚面上,当你使用真实的用户名,密码登录时,他的⻚面就可以通过 Javascript 读取到你的表单中 input 中的内容,这样用户名,密码就轻松到手了。

javascript 有哪些方法定义对象?

  • 对象字面量: var obj = {};
  • 构造函数: var obj = new Object();
  • Object.create(): var obj = Object.create(Object.prototype);

null , undefined 的区别?

  • undefined 表示不存在这个值;
  • undefined : 是一个表示 " 无 " 的原始值或者说表示 " 缺少值 " ,就是此处应该有一个值,但是还没有定义;
  • null 表示一个对象被定义了,值为 “ 空值 ”;
  • null : 是一个对象 ( 空对象 , 没有任何属性和方法 ); 在验证 null 时,一定要使用 === ,因为 == 无法分别 null 和 undefined

Javascript 中 callee 和 caller 的作用?

  • caller是返回一个对函数的引用,该函数调用了当前函数;
  • callee是返回正在被执行的 function 函数,也就是所指定的 function 对象的正文。

那么问题来了?如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第 n 个月能繁殖成多少对兔子?(使用 callee 完成)

let result = [];
function fn(n) {
  // 典型的斐波那契数列
  if (n == 1) {
    return 1;
  } else if (n == 2) {
    return 1;
  } else {
    if (result[n]) {
      return result[n];
    } else {
      //argument.callee() 表示 fn()
      result[n] = arguments.callee(n - 1) + arguments.callee(n - 2);
      return result[n];
    }
  }
}