美文网首页前端面试壮B的神马
高级前端面试题目大全(二)

高级前端面试题目大全(二)

作者: Aniugel | 来源:发表于2019-12-10 14:43 被阅读0次

第 21 - 30 题

第 21 题:有以下 4 个判断数组的方法,请分别介绍它们之间的区别和优劣

Object.prototype.toString.call() 、 instanceof 以及 Array.isArray() constructor

1. Object.prototype.toString.call()

每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的话,会返回 [Object type],其中 type 为对象的类型。但当除了 Object 类型的对象外,其他类型直接使用 toString 方法时,会直接返回都是内容的字符串,所以我们需要使用call或者apply方法来改变toString方法的执行上下文。

const an = ['Hello','An'];
an.toString(); // "Hello,An"
Object.prototype.toString.call(an); // "[object Array]"

这种方法对于所有基本的数据类型都能进行判断,即使是 null 和 undefined

Object.prototype.toString.call('An') // "[object String]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(Symbol(1)) // "[object Symbol]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call({name: 'An'}) // "[object Object]"

Object.prototype.toString.call() 常用于判断浏览器内置对象时。
更多实现可见 谈谈 Object.prototype.toString

2. instanceof

instanceof 的内部机制是通过判断对象的原型链中是不是能找到类型的 prototype

用来检测引用类型是Array/Function/Object,无法检测基本类型

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false  
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true    
console.log(undefined instanceof Undefined);// 报错
console.log(null instanceof Null);//报错

使用 instanceof判断一个对象是否为数组,instanceof 会判断这个对象的原型链上是否会找到对应的 Array 的原型,找到返回 true,否则返回 false

[]  instanceof Array; // true

instanceof 只能用来判断对象类型,原始类型不可以。并且所有对象类型 instanceof Object 都是 true。

[]  instanceof Object; // true

3. Array.isArray()

  • 功能:用来判断对象是否为数组

  • instanceof 与 isArray

    当检测Array实例时,Array.isArray 优于 instanceof ,因为 Array.isArray 可以检测出 iframes

    var iframe = document.createElement('iframe');
    document.body.appendChild(iframe);
    xArray = window.frames[window.frames.length-1].Array;
    var arr = new xArray(1,2,3); // [1,2,3]
    
    // Correctly checking for Array
    Array.isArray(arr);  // true
    Object.prototype.toString.call(arr); // true
    // Considered harmful, because doesn't work though iframes
    arr instanceof Array; // false
    
  • Array.isArray()Object.prototype.toString.call()

    Array.isArray()是ES5新增的方法(有些低版本的浏览器不支持),当不存在 Array.isArray() ,可以用 Object.prototype.toString.call() 实现。

    if (!Array.isArray) {
      Array.isArray = function(arg) {
        return Object.prototype.toString.call(arg) === '[object Array]';
      };
    }
    

4.constructor

console.log((2).constructor === Number); //true
console.log((true).constructor === Boolean); //true
console.log(('str').constructor === String); //true
console.log(([]).constructor === Array); //true
console.log((function() {}).constructor === Function); //true
console.log(({}).constructor === Object); //true

但是如果创建的对象更改了原型,是无法检测到最初的类型

5.typeof()

用来检测: undefined、string、number、boolean、symbol、object、function
无法检测引用类型里的Array

function Fn(){}; //原来是方法
Fn.prototype=new Array(); //改变原型为数组
var f=new Fn();
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true

解析:第 21 题

第 22 题:介绍下重绘和回流(Repaint & Reflow),以及如何进行优化

解析:第 22 题

第 23 题:介绍下观察者模式和订阅-发布模式的区别,各自适用于什么场景

解析:第 23 题

第 24 题:聊聊 Redux 和 Vuex 的设计思想

解析:第 24 题

第 25 题:说说浏览器和 Node 事件循环的区别

解析:第 25 题

第 26 题:介绍模块化发展历程

可从IIFE、AMD、CMD、CommonJS、UMD、webpack(require.ensure)、ES Module、<script type="module"> 这几个角度考虑。

解析:第 26 题

第 27 题:全局作用域中,用 const 和 let 声明的变量不在 window 上,那到底在哪里?如何去获取?。

解析:第 27 题

第 28 题:cookie 和 token 都存放在 header 中,为什么不会劫持 token?

1、首先token不是防止XSS的,而是为了防止CSRF的;
2、CSRF攻击的原因是浏览器会自动带上cookie,而浏览器不会自动带上token

cookie:用户点击了链接,cookie未失效,导致发起请求后后端以为是用户正常操作,于是进行扣款操作。
token:用户点击链接,由于浏览器不会自动带上token,所以即使发了请求,后端的token验证不会通过,所以不会进行扣款操作。
这是就是为什么只劫持cookie不劫持token的原因。

解析:第 28 题

第 29 题:聊聊 Vue 的双向数据绑定,Model 如何改变 View,View 又是如何改变 Model 的

解析:第 29 题

第 31 - 40 题

第 30 题:两个数组合并成一个数组

请把两个数组 ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'] 和 ['A', 'B', 'C', 'D'],合并为 ['A1', 'A2', 'A', 'B1', 'B2', 'B', 'C1', 'C2', 'C', 'D1', 'D2', 'D']。

    let a1 = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2']
    let a2 = ['A', 'B', 'C', 'D'].map((item) => {
        // 加了个3可以排列有序,最后把3给去掉
        return item + 3
    })
    let a3 = [...a1, ...a2].sort().map((item) => {
        if (item.includes('3')) {
            return item.split('')[0]
        }
        return item
    })
    console.log(a3)

解析: 第 30 题

第 31 题:改造下面的代码,使之输出0 - 9,写出你能想到的所有解法。

for (var i = 0; i< 10; i++){
    setTimeout(() => {
        console.log(i);
    }, 1000)
}

答案:

    // 方法一:将var改为let,因为let有作用域的概念
    for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            console.log(i);
        }, 1000)
    }
    // 方法二:采用闭包
    for (let i = 0; i < 10; i++) {
        ((i) => {
            setTimeout(() => {
                console.log(i);
            }, 1000)
        })(i)

    }

解析:第 31 题

第 32 题:Virtual DOM 真的比操作原生 DOM 快吗?谈谈你的想法。

解析:第 32 题

第 33 题:下面的代码打印什么内容,为什么?

var b = 10;
(function b(){
    b = 20;
    console.log(b); 
})();

1打印结果内容如下:
ƒ b() {
b = 20;
console.log(b)
}
2原因:
作用域:执行上下文中包含作用于链:
在理解作用域链之前,先介绍一下作用域,作用域可以理解为执行上下文中申明的变量和作用的范围;包括块级作用域/函数作用域;
特性:声明提前:一个声明在函数体内都是可见的,函数声明优先于变量声明;
在非匿名自执行函数中,函数变量为只读状态无法修改;

解析:第 33 题

第 34 题:简单改造下面的代码,使之分别打印 10 和 20。

var b = 10;
(function b(){
    b = 20;
    console.log(b); 
})();
    // 10
    var b = 10;
    (function b() {
        b = 20;
        console.log(this.b);
        console.log(window.b);
    })();
    // 20
    var b = 10;
    (function b() {
        var b = 20;
        console.log(b);
    })();

解析:第 34 题

第 35 题:浏览器缓存读取规则

可以分成 Service Worker、Memory Cache、Disk Cache 和 Push Cache,那请求的时候 from memory cache 和 from disk cache 的依据是什么,哪些数据什么时候存放在 Memory Cache 和 Disk Cache中?

解析:第 35 题

第 36 题:使用迭代的方式实现 flatten 函数。

解析:第 36 题

<script type="text/javascript">
    let arr = [1, 2, [3, 4, 5, [6, 7], 8]]


    // 字符串转换
    let newArr = arr.join(',').split(',').map(Number)
    console.log(newArr)


    // 迭代方法
    function flatten(arr) {
        // 当数组中元素有一个为数组时进行拆分操作
        while (arr.some(item => Array.isArray(item))) {
            arr = [].concat(...arr)
        }
        return arr
    }
    console.log(flatten(arr))


    // 递归一
    function flatten(arr) {
        let arrs = [];
        arr.map(item => {
            if (Array.isArray(item)) {
                // 把数组里面元素的数组打散
                arrs.push(...flatten(item))
            } else {
                arrs.push(item)
            }
        })
        return arrs
    }
    console.log(flatten(arr))



    // 递归二
    function wrap() {
        var ret = [];
        return function flat(a) {
            for (var item of a) {
                if (item.constructor === Array) {
                    ret.concat(flat(item))
                } else {
                    ret.push(item)
                }
            }
            return ret
        }
    }
    console.log(wrap()(arr));



    // 队列
    function flatten1(arr) {
        const newArr = [...arr];
        const res = [];
        while (newArr.length) {
            const item = newArr.shift(); // 出队
            if (Array.isArray(item)) {
                newArr.unshift(...item); // 入队
            } else {
                res.push(item);
            }
        }
        return res;
    }
</script>

第 37 题:为什么 Vuex 的 mutation 和 Redux 的 reducer 中不能做异步操作?

解析:第 37 题

第 38 题:(京东)下面代码中 a 在什么情况下会打印 1?

var a = ?;
if(a == 1 && a == 2 && a == 3){
    console.log(1);
}

这题考察的应该是类型的隐式转换,考引用类型在比较运算符时候,隐式转换会调用本类型toString或valueOf方法.

    // 方法一
    var a = [1, 2, 3];
    a.toString = a.shift;
    if (a == 1 && a == 2 && a == 3) {
        console.log(1);
    }
    // 方法二 toString()
    var a = {
        i: 1,
        toString() {
            return a.i++
        }
    }
    if (a == 1 && a == 2 && a == 3) {
        console.log(1);
    }
    // 方法二 valueOf()
    var a = {
        i: 1,
        toString() {
            return a.i++
        }
    }
    if (a == 1 && a == 2 && a == 3) {
        console.log(1);
    }

解析:第 38 题

第 39 题:介绍下 BFC 及其应用。

BFC 就是块级格式上下文,是页面盒模型布局中的一种 CSS 渲染模式,相当于一个独立的容器,里面的元素和外部的元素相互不影响。创建 BFC 的方式有:

BFC 产生条件
1、html 根元素
2、float 浮动
3、绝对定位
4、overflow 不为 visiable
5、display 为表格布局或者弹性布局

BFC 主要的作用
1.自适应两栏布局
2.div外边距重叠问题,以及子集margin不起作用问题
3.父级高度坍塌问题
4.变成一个隔离的独立容器

解析:第 39 题

第 40 题:在 Vue 中,子组件为何不可以修改父组件传递的 Prop

如果修改了,Vue 是如何监控到属性的修改并给出警告的。

解析:第 40 题

相关文章

网友评论

    本文标题:高级前端面试题目大全(二)

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