Vue前端面试题--2021.11.29(非vue3)

前段时间总结的部分面试题,有需要的可以看下哈~~😁

什么是构造函数

用 new 关键字来调用的函数,称为构造函数。构造函数首字母一般大写

function Person4() {
  this.gender = '男';
  // return { gender: '中性' };
}
var p4 = new Person4();
console.log(p4.gender);  // '中性' 

什么是继承

继承指的是一个对象可以共享父级对象的一些属性。

什么是原型链

对于对象而言,每个 JS 对象一定对应一个原型对象,并从原型对象继承属性和方法。对象proto属性的值就是它所对应的原型对象。对象的proto指向自己构造函数的 prototype。所以对象的原型链就是obj.proto.proto__....。

function Person() {
  return { };
}
var p = new Person();
console.log(p)
// {}
[[Prototype]]: Object
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
__proto__: (...)
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()

对于函数而言,只有函数才有 prototype 属性,Person.prototype 是一个对象,并且有两个属性, 一个是 constructor 指向其构造函数 Person, 一个是 proto 属性:是一个对象,指向上一层的原型。

console.log(Person.prototype)
// {constructor: ƒ}
// constructor: ƒ Person()
// [[Prototype]]: Object

所有的对象会一层层往上找原型,最终点是 Object,而 Object 的上一层原型就是 null 了。

this的指向

  • 箭头函数的 this 是在创建它时外层 this 的指向
  • 当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象(箭头函数不能当做构造函数)

cookie、localStorage和sessionStorage 三者之间的区别

  • cookie 可设置失效时间/4KB左右/每次都会携带在HTTP头中/只能保存字符串类型/同域名不同页面的数据共享
  • localStorage 除非被手动清除,否则将会永久保存/可以保存5MB的信息。/可以用来夸页面传递参数
  • sessionStorage 仅在当前网页会话下有效,关闭页面或浏览器后就会被清除/可以保存5MB的信息。

ES6常用语法

  • 解构赋值
let [a,b] = [1,2]
let {a,b} = {a:1,b:2}
  • 模板字符串
let str = `${name}的女朋友`;
  • 去除空格 .trim()
  let str = ' 10 10 ';
  console.log(str); // ' 10 10 '
  console.log(str.trim()); // '10 10'
  // 如果要去除所有空格
  let str = ' 10 10 ';
  console.log(str.replace(/ /g, '')); // 1010
  • 箭头函数
(1)箭头函数没有自己的`this`对象,内部的`this`就是定义时上层作用域中的`this`。。

(2)不可以当作构造函数,也就是说,不可以对箭头函数使用`new`命令,否则会抛出一个错误。

(3)不可以使用`arguments`对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

(4)不可以使用`yield`命令,因此箭头函数不能用作 Generator 函数。
  • 扩展运算符 ...
let obj = {...obj1}
let arr = [...arr1,...arr2] //合并数组 对象类似
[...'hello'] 
// [ "h", "e", "l", "l", "o" ]
  • find() ,findIndex() 查找数据/返回下标

  • includes() 方法返回一个布尔值,表示某个数组是否包含给定的值,返回布尔值。

  • .flat() 一维数组转换

let arr = [1,2,[3,4],[5,6,[7,8]]]
console.log(arr.flat(1)); //[1, 2, 3, 4, 5, 6, Array(2)]
console.log(arr.flat(2)); //[1, 2, 3, 4, 5, 6, 7, 8]

数组去重方法

  • 利用ES6 Set去重(ES6中最常用)
Array.from(new Set(arr))
  • 利用for嵌套for,然后splice去重(ES5中最常用)
var arr = [1, 1, 8, 8, 12, 12, 15, 15, 16, 16];

function unlink(arr) {
    for (var i = 0; i < arr.length; i++) {    // 首次遍历数组
        for (var j = i + 1; j < arr.length; j++) {   // 再次遍历数组
            if (arr[i] == arr[j]) {          // 判断连个值是否相等
                arr.splice(j, 1);           // 相等删除后者
                j--;
            }
        }
    }
    return arr
}
console.log(unlink(arr));
  • 利用includes
var arr = [1, 1, 8, 8, 12, 12, 15, 15, 16, 16];
function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var array =[];
    for(var i = 0; i < arr.length; i++) {
            if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
                    array.push(arr[i]);
              }
    }
    return array
}
console.log(unique(arr))

数组排序

  • sort()
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b}); 
// 1,5,10,25,40,100 升序 反之 b-a 降序

类型判断

基本数据类型:Undefined、Null、Boolean、Number、String,Symbol
引用数据类型 :Object

let bool = true;
let num = 1;
let str = 'abc';
let  und= undefined;
let nul = null;
let arr = [1,2,3,4];
let obj = {name:'xiaoming',age:22};
let fun = function(){console.log('hello')};
let s1 = Symbol();
  • typeof判断
console.log(typeof bool); //boolean
console.log(typeof num);//number
console.log(typeof str);//string
console.log(typeof und);//undefined
console.log(typeof nul);//object
console.log(typeof arr);//object
console.log(typeof obj);//object
console.log(typeof fun);//function
console.log(typeof s1); //symbol
  • instanceof判断
console.log(bool instanceof Boolean);// false
console.log(num instanceof Number);// false
console.log(str instanceof String);// false
console.log(und instanceof Object);// false
console.log(nul instanceof Object);// false
console.log(arr instanceof Array);// true
console.log(obj instanceof Object);// true
console.log(fun instanceof Function);// true
console.log(s1 instanceof Symbol);// false
  • constructor判断
    null、undefined没有construstor方法,因此constructor不能判断undefined和null。 但是他是不安全的,因为contructor的指向是可以被改变。
console.log(bool.constructor === Boolean);// true
console.log(num.constructor === Number);// true
console.log(str.constructor === String);// true
console.log(arr.constructor === Array);// true
console.log(obj.constructor === Object);// true
console.log(fun.constructor === Function);// true
console.log(s1.constructor === Symbol);//true
  • Object.prototype.toString.call 判断
console.log(Object.prototype.toString.call(bool));//[object Boolean]
console.log(Object.prototype.toString.call(num));//[object Number]
console.log(Object.prototype.toString.call(str));//[object String]
console.log(Object.prototype.toString.call(und));//[object Undefined]
console.log(Object.prototype.toString.call(nul));//[object Null]
console.log(Object.prototype.toString.call(arr));//[object Array]
console.log(Object.prototype.toString.call(obj));//[object Object]
console.log(Object.prototype.toString.call(fun));//[object Function]
console.log(Object.prototype.toString.call(s1)); //[object Symbol]

vue v-on绑定多个事件

<div v-on="{mousedown:onInput,mouseup:onFocus,click:onBlur}"></div>

防抖和节流

  • 防抖(debounce)
    所谓防抖,就是指触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
    防抖函数分为非立即执行版和立即执行版,此处为 非立即执行版
 function debounce(func, wait) {
  let timeout;
  return function () {
    const context = this;
    const args = [...arguments];
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(context, args)
    }, wait);
  }
}

  • 节流(throttle)
    所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。 节流会稀释函数的执行频率。
    一般有两种方式可以实现,分别是时间戳版和定时器版,此处为 定时器版
function throttle(func, wait) {
    let timeout;
    return function() {
        let context = this;
        let args = arguments;
        if (!timeout) {
            timeout = setTimeout(() => {
                timeout = null;
                func.apply(context, args)
            }, wait)
        }
    }
}

前端性能优化

  • 使用服务端渲染
  • 静态资源使用 CDN(前端只需要引入,静态资源放在这url下面 然后以CDN 厂商哪里指定这个URL)
  • 使用字体图标 iconfont 代替图片图标
  • 善用缓存,不重复加载相同的资源
  • 降低图片质量( webpack打包配置)
  • 尽可能利用 CSS3 效果代替图片
  • 使用 webp 格式的图片

WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一。

  • 使用 requestAnimationFrame 来实现视觉变化

如果采取 setTimeout 或 setInterval 来实现动画的话,回调函数将在帧中的某个时点运行,可能刚好在末尾,而这可能经常会使我们丢失帧,导致卡顿。

  • 降低 CSS 选择器的复杂性

怎样理解 Vue 的单向数据流?

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。
或者通过 .sync 去实现双向通信

// 子组件
props:{
  msg:String
}
...
computed:{
 msgData:{
  get(){
    return this.msg
  },
 set(val){
   this.$emit('update:msg',val)
  }
 }
}
//父组件
<children :msg.sync="data" />

父组件可以监听到子组件的生命周期吗?

可以

// Parent.vue
<Child @mounted="doSomething"/>
    
// Child.vue
mounted() {
  this.$emit("mounted");
}

组件中 data 为什么是一个函数?

因为组件是用来复用的,且 JS 里对象是引用关系,如果组件中 data 是一个对象,那么这样作用域没有隔离,子组件中的 data 属性值会相互影响,如果组件中 data 选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响;而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。

Vue 组件间通信有哪几种方式?

props / $emit 适用 父子组件通信
ref 与 $parent / $children 适用 父子组件通信
EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信

Vue 是如何实现数据双向绑定的?

1.实现一个监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。
2.实现一个解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。
3.实现一个订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
4.实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。


image.png

虚拟 DOM 实现原理?

虚拟dom的比较,就是找出新节点(vnode)和旧节点(oldVnode)之间的差异,然后对差异进行打补丁(patch)
虚拟 DOM 的实现原理主要包括以下 3 部分:

  • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
  • diff 算法 — 比较两棵虚拟 DOM 树的差异;
  • pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

Vue 中的 key 有什么作用?

key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速。

你有对 Vue 项目进行哪些优化?

  • 代码层面的优化

v-if 和 v-show 区分使用场景
computed 和 watch 区分使用场景
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
长列表性能优化
事件的销毁
图片资源懒加载
路由懒加载
第三方插件的按需引入
优化无限列表性能
服务端渲染 SSR or 预渲染

  • Webpack 层面的优化

Webpack 对图片进行压缩
减少 ES6 转为 ES5 的冗余代码
提取公共代码
模板预编译
提取组件的 CSS
优化 SourceMap
构建结果输出分析
Vue 项目的编译优化

vue有哪些优势

  • 轻量级框架
  • 简单易学
  • 双向数据绑定
  • 组件化开发
  • 视图,数据,结构分离
  • 虚拟DOM
  • 提供了丰富的api供开发者使用(computed,watch,$set,#parent,生命周期钩子,mixin等)

为什么要用vuex而不直接定义全局变量

  • 方便集中管理
  • 不会造成命名污染
  • 提供统一的方法修改数据
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容