JS面试题2

1、运算符

  1. 问题:
    ○ 下面代码中,a在什么情况下,会执行输出语句打印1?
  2. 代码:
var a= ? 
if(a==1 && a==2 && a==3){
   console.log(1)
}
  1. 解决
    • 3-1、利用toString()方法
// 1、将a赋值为一个对象
    var a = {
// 2、定义对象a中的属性i为1
      i: 1, 
// 3、在if条件中比较数值时,覆盖会调用的`toString()`方法,直接返回对象a中i值++,因为是后置++,所以初始值还是1,则在进行`a==1`比较时,可以通过
  // 1)后续每次`if比较`时,都会调用到`toString()`方法,继续进行`i++`操作
  // 2)调用`toString()方法`是因为在比较值时,`js`会自动调用该方法
  // 3)完整的比较顺序应该是:
    // A. 和数值进行对比时:需要用到`Number()`转换类型,但是转换之前会先用到`valueOf()`尝试转换
    // B. 如果返回的还是对象,则调用`toString()`,当前在`toString()`这里直接改写了,所以就将数据直接返回了
      toString() {
        return a.i++;
      }
    }
// 4、使用 if 条件语句进行比较
  // 1)在第一次比较时,调用 a.toString(),a.i++ 返回 1,因此 a == 1 为 true
  // 2)在第二次比较时,再次调用 a.toString(),a.i++ 返回 2,因此 a == 2 为 true
  // 3)在第三次比较时,继续调用 a.toString(),a.i++ 返回 3,因此 a == 3 为 true
  // 4)因为三个比较都为 true,因此执行 console.log(1)
    if (a == 1 && a == 2 && a == 3) {console.log(1);}
  • 3-2、利用valueOf()方法
    var a = {
      i: 1,
// 将上面的toString()换成valueOf()即可
      valueOf() {
        return a.i++;
      }
    }
    if (a == 1 && a == 2 && a == 3) {console.log(1);}

2、原型和原型链

2.1、谈谈对Js中原型与原型链的理解?

  1. 每个对象都有一个_proto_ 属性,该属性指向自己的原型对象
  2. 每个构造函数都有一个prototype属性,该属性指向实例对象的原型对象
  3. 原型对象里的constructor指向构造函数本身
  4. 实例对象的constructor属性是从它的原型对象上访问到的

2.2、对一个构造函数实例化后,它的原型链指向什么?

  1. 指向该构造函数实例化出来对象的原型对象
  2. 对于构造函数来讲,可以通过prototype访问到该对象
  3. 对于实例对象来讲,可以通过隐式属性_proto_来访问到

3、谈谈对JS中的执行上下文的理解

  1. 概念:
    a. 简单概括为:代码(全局/函数代码)执行前进行的准备工作
    b. 如:确定作用域、创建局部变量对象,也称为“执行上下文环境”
  2. 执行上下文类型有:
    a. 全局执行上下文
    b. 函数执行上下文:在调用时产生
  3. 注意:

执行上下文的生命周期有两个阶段,执行阶段只是上下文生命周期中的第二步:
创建阶段(进入执行上下文):函数被调用时,进入函数环境,为其创建一个执行上下文
执行阶段(代码执行):执行函数中代码时,此时执行上下文进入执行阶段。

4、谈谈对JS中的执行栈的理解

  1. 执行栈遵循“先进后出,后进先出”的规则,出口在栈的顶部,且只有一个
  2. 执行栈的主要功能是:管理和追踪代码执行的顺序

5、谈谈对JS中的作用域的理解

  1. 概念:
    a. 作用域就是一个独立的地盘,让变量、函数等不会外泄、暴露出去。
    b. 也就是说:作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
  2. 分类:
    a. 全局作用域:在代码中任何地方都能访问到的对象拥有全局作用域
    b. 函数作用域:是指变量在函数内部声明时,该变量只能在该函数内部访问
    c. 块级作用域:是指变量在块(由{}包围的代码块内部)声明时,该变量只能在该块内部访问。

6、谈谈对JS中的作用域链的理解

  1. 概念:
    a. 作用域链是指:在嵌套的函数中,变量和函数的查找过程。
    b. 每个函数都有自己的作用域,但,可以访问外层函数和全局作用域中的变量。
  2. 详解
    全局作用域:最外层,所有代码都能访问。
    函数作用域:每个函数都有自己的作用域,内部函数可以访问外部函数和全局作用域中的变量
    作用域链的形成:当代码执行时,如果在当前作用域找不到某个变量,就会沿着作用域链向上查找,直到找到或到达全局作用域

7、this指向

  1. 在函数体中,非显式/隐式地简单调用函数时:
    a. 在严格模式下:函数内的this会被绑定到undefined
    b. 在非严格模式下:则会被绑定到全局对象window/global
  2. 一般使用new方法调用构造函数时,构造函数内的this会被绑定到新创建的对象(实例对象)上
  3. 一般通过call/apply/bind方法显式调用函数时,函数体内的this会被绑定到指定参数的对象上
  4. 一般通过上下文对象调用函数时,函数体内的this会被绑定到该对象上
  5. 箭头函数中,this的指向是由外层(函数或全局)作用域来决定的

8、闭包

8.1、闭包是什么?

  1. 闭包不是一个具体的技术,而是一种现象,是指:在定义函数时,周围环境中的信息可以在函数中使用
  2. 换句话说:执行函数时,只要在函数中使用了外部的数据,就创建了闭包,作用域链,则是实现闭包的手段

8.2、闭包的应用场景有哪些?

  1. 作用域空间不销毁
  2. 可以在函数外部访问函数内部的变量,也就是:在全局访问局部变量
  3. 保护私有变量:在外部函数声明,在内部函数引用的变量

8.3、怎么销毁闭包?

  1. 如果是自动产生的闭包,我们无需操心闭包的销毁,会自动销毁
  2. 如果是手动创建的闭包:
    a. 可以把被引用的变量设置为null,即:手动清除变量
    b. Js垃圾回收器在进行垃圾回收时,发现此变量已经没有任何引用,就会把设为null的变量给回收了

9、谈谈事件委托以及冒泡原理

9.1、事件委托

  1. 事件委托是利用事件冒泡原理,把事件处理器绑定到一个父元素上,而不是每个子元素都绑定事件处理器。
  2. 这样做可以:提高性能,减少内存消耗,并且可以处理动态添加的子元素

9.2、冒泡原理

  1. 冒泡原理是指事件在DOM树中从目标元素开始向上层元素传播的过程。
  2. 事件首先触发目标元素上的处理函数,然后逐级向上传播至根元素

10、如何阻止默认事件

所谓默认行为,一般是指HTML元素所自带的行为,如:点击一个a元素时会跳转

  1. event.preventDefault()
  2. event.returnValue = false
    ○ 该特性已经从web标准中删除,虽然一些浏览器目前还支持它,但尽量不要使用该特性
  3. return false
    ○ 不建议滥用,同时:jQuery中可以同时阻止冒泡和默认事件

你可能感兴趣的:(面试合集,javascript,原型模式,开发语言,前端,html,跳槽,面试)