js面试题知识点整理

2019-11-17  本文已影响0人  落魂灬

一、js面试题

  1. JavaScript 中的 this 究竟指向谁,箭头函数的 this 有什么不同
  1. 深拷贝和浅拷贝的区别?如何实现?
    两者的区别:一个对象浅复制后,是深层次的对象地址的复制,并没有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会发生改变,而深复制的则是开辟了一个新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。
    JSON.stringify与JSON.parse可以实现深拷贝,还可以借用JQ的extend方法。

// 原始对象
var obj = { 
    a:1, 
    arr: [2,3],
    say:function(){
        console.log('hello')
    },
    obj1:{
        arr:[34,55,5],
        hand:function(){
            console.log('hand')
        },
        obj3:{
            a:1,
            take:function(){
                console.log('take')
            }
        }
    }
};
 
// 开始浅复制
var shallowObj = shallowCopy(obj);
 
// 定义浅复制逻辑
function shallowCopy(src) {
  var dst = {};
  for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
      dst[prop] = src[prop];
    }
  }
  return dst;
}
 
// 改变复制后的新对象的属性值(第二层以及更深层次)
shallowObj.obj1.obj3.take = function(){
    console.log('shallowObj_take') 
}
shallowObj.obj1.hand = function(){
    console.log('shallowObj_hand')
}
 
// 打印新对象的方法调用
shallowObj.obj1.obj3.take();  // shallowObj_take
shallowObj.obj1.hand();      // shallowObj_hand
 
// 打印原对象的方法调用
obj.obj1.obj3.take();   // shallowObj_take
obj.obj1.hand();     // shallowObj_hand
 
问题出现了:原对象的方法被新对象的修改,而产生变化。
原因是复制的是对象的地址指针,两个属性共同指向一个对象,只要其一发生变化,另一个也随之变化
function deepClone(obj){
    let _obj = JSON.stringify(obj),
            objClone = JSON.parse(_obj);
    return objClone
}    
let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
  1. js的事件委托是什么,原理是什么?
    事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。用事件委托就可以只用一次dom操作就能完成所有的效果。
  2. 如何判断一个变量是否为数组(isArray)
1、instanceof
function isArray (obj) {
  return obj instanceof Array;
}
2、Array对象的 isArray方法
function isArray (obj) {
  return Array.isArray(obj);
}
3、Object.prototype.toString
function isArray (obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
}
  1. 'DOM2级事件'规定的事件流包含3个阶段:事件捕获,处于目标,事件冒泡
    阻止事件冒泡:event.stopPropagation()
    阻止默认行为:e.preventDefault()

  2. 回调地狱和回调函数
    回调地狱(函数作为参数层层嵌套)
    回调函数(一个函数作为参数需要依赖另一个函数执行调用)

  3. 数组的基本方法
    push和unshift,返回值是length
    pop和shift,返回值是删除的当前项
    slice:抽取当前数组中的一段元素组合成一个新数组。第一个参数从哪里开始,第二个参数是到哪结束
    数组splice第一个参数是索引,第二个参数是想修改或者删除几个元素,第三个是添加的内容
    split把字符串分割成数组
    Array.prototype.includes():判断数组中是否包含某指定的值

  4. 数组去重的方法

  1. 判断一个变量是不是数组的可靠的方法:
  1. typeof和instanceof的区别
    typeof返回的类型都是字符串形式
    instanceof,后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。

  2. call & apply & bind() 之间的区别:
    call和apply都是改变this指向的方法,区别在于call可以写多个参数,而apply只能写两个参数,第二个参数是一个数组,用于存放要传的参数。
    bind()返回的是一个新函数,必须调用它才会执行

  3. 基本数据类型
    (ES6之前)其中5种为基本类型:string,number,boolean,null,undefined,
    ES6出来的Symbol也是原始数据类型 ,表示独一无二的值
    基本类型的存储方式都是栈存储,引用类型的存储方式都是堆存储

  4. 栈和队列的区别?
    栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。
    队列先进先出,栈先进后出。
    栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删除

  5. 对闭包的理解
    使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念
    闭包有三个特性:
    1.函数嵌套函数
    2.函数内部可以引用外部的参数和变量
    3.参数和变量不会被垃圾回收机制回收

  6. 跨域的解决方案

步骤:
去创建一个script标签
script的src属性设置接口地址
接口参数,必须要带一个自定义函数名 要不然后台无法返回数据。
通过定义函数名去接收后台返回数据
//去创建一个script标签
var script = document.createElement("script");
//script的src属性设置接口地址 并带一个callback回调函数名称
script.src = "http://127.0.0.1:8888/index.php?callback=jsonpCallback";
//插入到页面
document.head.appendChild(script);
//通过定义函数名去接收后台返回数据
function jsonpCallback(data){
//注意 jsonp返回的数据是json对象可以直接使用
//ajax 取得数据是json字符串需要转换成json对象才可以使用。
}

二、vue面试题

  1. route 和router 的区别
  1. Vue的双向数据绑定原理是什么?
    vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
  2. <keep-alive></keep-alive>的作用是什么?
    <keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
上一篇下一篇

猜你喜欢

热点阅读