js常见面试题

作者: 小宇cool | 来源:发表于2020-07-06 12:28 被阅读0次
1.undefined 和 null 有什么区别?

他们的相同之处: 他们都是javascript的7种基本类型, 它们都是虚值, 他们转为布尔值都是false, undefined == null 返回true. 严格相等下返回false, 因为他们的类型不同,

区别在于undefined是指为指定特定的变量的默认值.或者没有显示返回值的函数.还包括对象中不存在的属性, 这些js引擎都会为其分配undefined值.

let a;
const obj = {name:"ww"};
console.log(obj.age) // undefined
function add(){}
console.log(a)// undefined;
console.log(add())// undefined;

null是表示不代表任何值的值, null是已明确给定定义变量的值, 在使用typeof 判断null的类型时返回的是object;

typeof null // object
2 &&运算符可以做什么?

&&符也可以叫做逻辑与,在其操作数找到第一个虚值,虚值即false并返回它,如果没有找到任何虚值,则返回最后一个真值表达式.它采用短路来防止不必要的工作;

通过用于判断条件表达式是否都成立, 如果都成立,则返回true, 否者返回false;

let a = 32;
if(a  > 20 && a % 2 == 0){ // 只有当判断条件都为true时,才会打印a
    console.log(a)
}
3 . ||运算符可以做什么

||也可以叫做逻辑或, 在其操作数中找到第一个真值表达式并返回它,它也使用了短路来防止了不必要的工作,在es6支持函数参数默认值之前, 它用于初始化函数中的默认值.

function log(target){
    var = target || "params";
    console.log(target)
}

上面的代码中当函数log的参数target没有传递时, 此时target为false, 此时|| 操作符返回 第二个操作数 params;

通常 || 也用与if判断条件, 只有当判断条件中有一个为true, 整体就返回true

4 使用+或一元运算符是将字符串转为数字的最快方法吗?

根据MDN文档, +是将字符串转为数字的最快方法, 因为如果值是数字, 他不会执行任何操作.

let str = "32,21"
let result = str.split(",").map((v) => +v);
console.log(result)//  [32, 21]

上面的代码可以很优雅的将类型数组的字符串 转为一个真正的数组

5. DOM是什么

DOM 表示文档对象模型. 是HTML和XML文档接口(API). 当浏览器第一次读取HTML文档时, 它会创建一个大对象, 一个基于HTML文档的非常大的对象, 这个对象就是DOM.它是一种HTML文档建模的树状结构.通常DOM用于交互和修改DOM结构或特定元素的节点.

假设我们有如下的HTML结构;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>hello document</h1>
</body>
</html>

等价的DOM是这样的

image-20200623195756291.png

在js中, document对象表示DOM,它为我们提供了许多方法, 我们可以用这些方法来选择元素或者更新元素内容等等.

6. 什么是事件传播?

当事件发生在DOM元素上时, 改事件并不完全发生在那个元素上.在冒泡阶段中事件冒泡向上传播到父级.,一直到window为止. 而个捕获阶段时,事件从window开始向下触发元素, 事件活event.target.

事件传播有三个阶段 顺序如下:

  1. 捕获阶段 -- 事件从window开始.然后向下到每个元素, 直到到达目标元素.
  2. 目标阶段 -- 事件已达到目标元素.
  3. 冒泡阶段 -- 事件从目标元素冒泡, 然后上升到每个元素, 直到window.
7 什么是事件冒泡?

当事件发生在DOM元素上时, 该事件并不完全发生在那个元素上. 在冒泡阶段,事件冒泡.事件会一直往它到底父级向上传播,直到window为止.

假设我们有如下的htmll结构代码

<div class="parent">
    <div class="child"></div>
</div>

js部分如下

 let parent = document.querySelector(".parent"),
        child =  document.querySelector(".child");
parent.addEventListener("click", function(){
    console.log("parent");
},false)
child.addEventListener("click", function(){
    console.log("child");
},false)

addEventListener的方法接受第三个可选参数, 其默认值为false,此时事件在冒泡阶段执行,如果为true,则在捕获阶段执行.

当我们点击child触发点击事件时. 此时事件在冒泡阶段执行,控制台会先打印child,然后在打印parent.事件会一直传播到window对象上, 这就是事件冒泡.

8 . 什么是事件捕获?

当事件发生在DOM上时, 改事件并不完全只发生在那个元素上,在捕获阶段,事件从window开始传播, 一直到触发事件的元素时结束

如果把上道题的绑定的事件监听第三个参数为true时, 此时事件在捕获阶段执行, 此时如果点击了child, 控制台会先打印parent,然后在打印child

9 . event.preventDefalut ()和 event.stopProPagation ()方法之间有什么区别?

event.preventDefalut()方法用来阻止元素的默认行为.如果在表单元素中使用, 它将会阻止其提交, 如果在锚元素中使用. 它将会阻止其导航.元素的默认行为通常是元素身上自带的事件行为.例如当点击a标签时,会跳转到别的网页.

event.stopProPagation 方法()通常用来阻止捕获和冒泡阶段中当前事件的进一步传播。
10 . 如何知道是否在元素中使用event.stopProPagation属性?

我们可以通过事件对象调用event.defalutPrevented属性, 它返回一个布尔值用来表明在特定元素中是否调用了

event.stopProPagation();

10 . 为什么此代码 obj.some.x会发生错误?
const obj = {}
console.log(obj.some.x)

因为obj本身并没有some属性,此时obj.some为undefined, 对象不存在的属性,默认为undefined,显然undefined并没有属性x, 访问试图访问就会报错.

12 . 什么是event.target

简单来说, event.target就是当前发生事件的目标元素或触发事件的元素.

假设我们有下面的html结构代码

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

假设我们给button和div都绑定了点击事件, 当我们点击了button时,此时event.target为button元素.

当我们点击了div,此时event.target为div元素.

因此我们得出结论, event.target就是触发事件的元素.

13 什么是event.currentTarget?

event.currentTarget是我们在其显式附加事件处理程序的元素.

同上,当我们点击了button元素时, 如果我们在控制台打印event.currentTarget,此时不仅会打印button也会打印div元素.我们可以得出结论,event.currentTarget会监听触发了事件的所有元素.并将他们返回.

14 .== 和 === 有什么区别?

== 运算符也叫 相等, 用来判断两个操作数是否相等. 这里的相等定义非常宽松,在比较的时候可以允许类型转换, === 用于严格比较. 只要类型不一致就会返回fasle;

在== 比较下,假设如果我们要比较 x 和 y的值

  1. 当俩数类型都相同时, 则js 引擎会换成 === 操作符进行比较
  2. 当俩数类型一个为string另一个为number时, 那么此时类型为string的会发生隐式类型转换,转为number类型进行比较
  3. 当俩数类型中有一个为boolean类型时,俩数都会被转为数字类型进行比较.
console.log("1" == 1) //true
console.log("1" === 1) //false
15 .为什么在JS中比较两个相似的对象会返回false?
let one = {a:1};
let two = {a:1};
let c = a;
console.log(a === b) // false ,因为他们在内存指向的不是同一个对象
console.log(a === c) // true

js比较基本数据类型时,比较的时他们的值,而在引用数据类型比较时, js会比较他们的引用或储存变量的内存地址.所以第一个返回false.第二个返回true, 因为他们都在内存中都指向同一个地址或引用

16. !! 运算符能做什么?

!!运算符可以将右侧的值强制转为布尔值.这也是将值转为布尔值的一种简单方法.

console.log(!!null) // false;
console.log(!!undefined1)// fallse
17 . 如何在一行中计算多个表达式的值?

可以使用,运算符在一行中计算多个表达式.它从左往右求值,并返回最后一个项目或最后一个操作数的值

let x = 4;
x = (x++,x = addSix(x), x *= 5, x += 10);
function addSix(num){
    return num + 6
}

上面的结果最后得到的x的值为65,首先我们让x++到5,如何调用函数返回11并赋值给x, 然后在计算x 加上x * 5然后 赋值给x,此时x为55.接着在让x += 10 此时x为 65;

18. 什么是提升?

提升就是用来描述变量和函数移动到其(全局或函数)作用域顶部的术语

为了理解提升,需要了解一下执行上下文.执行上下文是当前正在执行的代码环境.执行上下文有两个阶段:编译执行

编译-在此阶段,JS引擎会获取所有的函数声明并将其提升到作用域顶部, 以便我们稍后可以引用它们并获取所有的变量声明(使用var关键字声明), 还会为它们提供默认值undefined

执行 - 在这个阶段,它将值赋值给之前提升的变量, 并执行或调用函数(对象中的方法).

注意只有使用var声明的变量, 或者函数声明才会提升,其他使用箭头函数,或者函数表达式,let和cosnt声明的变量,这些都不会提升

变量提升和函数提升在代码中的位置是不会变的,而是在编译阶段放在内存中

console.log(a) //变量a存在提升,此时a的默认值为undefined, 所以此时打印undefined
var a = 1;
console.log(a) // 1
console.log(sayHi("ww"));// helloww
function sayHi(name){
    return "hello" + name 
}

上面的代码在编译阶段其实是这样的

function sayHi(name){
    return "hello" + name
}
var a;// 默认值为undefined
// 等待编译完成., 然后开始"执行"阶段;
console.log(a);// undefined
a = 1;// 此时变量给 a 赋值
console.log(a) //1;
console.log(sayHi("ww"))

函数声明会提提升到作用域最顶层并赋值,所以我们可以在函数声明之前调用函数,

19 . 什么是作用域?

javascript中作用域是指我们能够有效访问变量或函数中的区域.JS有三种类型的作用域:全局作用域,函数作用域块级作用域(ES6)

全局作用域-- 在全局命名空间中声明的变量或函数位于全局作用域, 因此在代码中的任何区域都可以访问到他们

var say = "hello"
function global(name){
    console.log(say) // hello
    return "hello" + name
}
global()

函数作用域-- 在函数中声明的变量,函数和参数都可以在函数内部访问, 但不能在外部访问,只能在函数内部进行访问.

function myFn(){
    var a = 45;
}
console.log(a)//  a is not defined

块级作用域-- 在块{ } 中声明的变量(let,const)只能在其中访问。

function fn(){
    if(true) {
        let x = 2
    }
    console.log(x)
}
fn()//x is not defined

作用域链一种用于查找变量的规则,如果变量在当前作用域内不存在,它就会往外部作用域链内查找,如果该变量还是不存在,他会一直找直到全局作用域,如果找到了就可以使用它,否者就报错.这种查找过程就叫作用域链

作用域链只能从内部作用域往外部作用域进行查找,不能从当前作用域往内部作用域查找.

20 . 什么是闭包?

闭包是一种函数和对其周围状态的引用捆绑在一起构成闭包.也就是是闭包可以让你从函数内部作用域访问函数内部作用域.在js中,每当函数被创建,就会在函数生成时形成闭包.

var three = "three";
function fn(one){
    return function(two){
        console.log(one,two,three)
    }
}
fn("one")("two")

上面的代码会打印 one, two,three,当我们调用了函数fn时,此时我们传递的值会被赋值给变量one,此时fn函数作用域内就有变量one,因为fn调用完返回了一个新函数,此时我们可以加括号继续调用,此时我们传递了一个参数,此时返回的函数内部变量two的值就为two, 当返回的函数在内部进行打印时,它会在作用域链依次查找变量one,two,three,因为此时产生了闭包,所以我们可以访问到外部函数内的变量one,然后接着访问到了自身作用域的two,接着访问到了全局作用域的three.

21 . 虚值是什么?

简单的来说虚值就是在转换为布尔值时变为false的值.

const falseValues = ["",null,undefined,NaN,false,0]
22 . 如何检测值是否为虚值?

使用Boolean函数或者!!运算符

23. "use strict"是干嘛用的?

use strict是ES5的特性, 它使我的的代码在函数或整个脚本中处于严格模式.严格模式帮助我们在代码的早起避免bug,并为其添加限制.

设立严格模式的目的,主要有几个:

  1. 消除javascript语法的一些不合理, 不严谨之处, 减少一些怪异行为
  2. 消除代码运行的一些不安全之处, 保证代码运行的安全
  3. 提高编译器效率, 增加运行速度
  4. 为未来新版本的javascript做好铺垫
  5. 规范我们写代码的时要遵守的限制.减少了bug.
24 javascript中this值是什么?

基本上. this指的是当真执行或调用改函数的对象的值.this的值的变化取决于我们使用它的上下文和我们在哪里使用它.

const student = {
    Name:"张三",
    Score:45,
    getStudentInfo(){
        return "学生姓名为" + this.Name + "成绩为" + this.Score
    }
}
console.log(student.getStudentInfo())// 学生姓名为张三成绩为45
let child = studnet.getStudentInfo;
console.log(child())// 学生姓名为undefined成绩为undefined
child = studnet.getStudentInfo.bind(student)
console.log(child())// 学生姓名为张三成绩为45

上面的代码中我们通过对象student调用了getStudentInfo方法, 此时函数内部this指向了student,所以我们可以得到this.name和this.age的值. 说明了this指向了当前调用函数的对象的值

如果我们通过child执行函数时,此时调用函数的对象则时window, 因为window上没有Name和Score属性,所以返undefined,如果我们要让child的函数this绑定在student,可以通过bind方法显式的改变函数的this指向.此时我们就可以在控制台打印出想要的数据.

相关文章

  • 2021 web高频面试题新人可看

    当日目标 1 常见面试题分布情况? 2 高频面试题 1 常见面试题分布情况 公司面试题一般分为js,vue,小程序...

  • WEB前端常见面试题及答案2.0

    第一版请见:WEB前端常见面试题及答案 1、js内存机制 JS内存空间分为栈(stack)、堆(heap)、池(一...

  • JS 函数的执行时机

    1. 常见的面试题代码解释 // 6 个 6JS是单线程运行的,setTimeout(code,millisec)...

  • js基础面试题

    面试题:延迟加载JS有哪些方式? 面试题:JS数据类型有哪些? 面试题:JS数据类型考题 考题一: 考题二: 面试...

  • js 面试题 函数声明 变量声明

    一个常见的函数声明和变量的面试题 题目一: 题目二: 想回答出来上面的面试题来,先要理解js中函数声明提升、变量声...

  • 前端vue面试题分享(附答案)

    本篇文章给大家分享一些常见的前端vue面试题,有一定的参考价值,希望对大家有所帮助。 vue面试题 vue.js的...

  • JS常见面试题

    1.基本数据类型有哪些? Undefined、Null、Boolean、Number、String 2.原型,原型...

  • js常见面试题

    总结了一些常见的js面试题,欢迎大家评论补充。!!!注意不要一味的死记硬背,掌握原理才是关键。 数组去重 var ...

  • 常见js笔试面试题

    1 js基础知识 1. javascript typeof返会的数据类型有哪些 object,string,und...

  • js常见原理面试题

    1. 实现一个call函数 2. 实现一个apply函数 3. 实现一个bind函数 4. instanceof原...

网友评论

    本文标题:js常见面试题

    本文链接:https://www.haomeiwen.com/subject/qyewqktx.html