(自己整理的,有错误和不足的话,大佬请指出,共同学习)

一:js

1.什么是回调地狱,怎么解决回调地狱问题

经常出现很多将函数作为参数,传入到方法中,然后在方法中调用该方法,常见的就是定时器,各种DOM操作,各种异步请求
 异步的JavaScript程序,或者说使用了回调函数的JavaScript程序
一个函数作为参数需要依赖另一个函数执行调用。
A、拆解 function:将各步拆解为单个的 function
B、通过 Promise 链式调用的方式
function buildCatList(list, returnVal) {
return new Promise(function (resolve, reject) {
setTimeout(function (name) {
var catList = list === ‘’ ? name : list + ‘,’ + name
resolve(catList)
}, 200, returnVal)
})
}

    buildCatList('', 'Panther').then(function (res) {return buildCatList(res, 'Janguar')}).then(function (res) {return buildCatList(res, 'Lion')}).then(function (res) {console.log(res)})

C、通过ES8的异步函数 async / await
async 表示这是一个 async 函数,await 只能用在这个函数里面
await 表示在这里等待 Promise 返回结果后,再继续执行
await 后面跟着的应该是一个 Promise 对象(当然,其他返回值也没关系,只是会立即执行)
await 等待的虽然是 Promise 对象,但不必写 .then() ,可以直接得到返回值

2.遍历数组

var arr = [1,2,3,4,5,6];
for(let i= 0; i<arr.length; i++){
console.log(下标是${i}的元素的值为:${arr[i]});
}
for(let i in arr){
console.log(下标是${i}的元素值为:${arr[i]});
}
var i =0;
for(var ele of arr){
console.log(下标是${i++}的元素值为:${ele});
}
arr.forEach(function(ele,index){
console.log(小标是${index}的元素的值为:${ele});
})

4、数组排序

1、冒泡排序
var arr = [1,9,4,2,6,5,3,2]
var news =‘’
for(var i = 0 ; i < arr.length ; i++){
for(var j =0 ; j < arr.length-i ;j++){
if(arr[j]>arr[j+1]){ //从小到大排序
news=arr[j]
arr[j]=arr[j+1]
arr[j+1]=news
}
}
} console.log(news)
2,快速排序 取中间值 大的放一边,小的放一边
3. sort数字排序
console.log(arr.sort(
function(a,b){
return a-b
}
)); [1, 2, 2, 3, 4, 5, 6, 9]

5、获得数组中最大值,最小值

1、Math.max
因为Math.max参数里面不支持Math.max([params,param2])也就是数组
console.log(Math.max(…arr));
console.log(Math.min(…arr));
2、数组排序后,取收尾下标值,获取

6、数组去重

1.利用for嵌套for,然后splice去重(ES5中最常用)

下面展示一些 内联代码片

function unique(arr){            for(var i=0; i<arr.length; i++){for(var j=i+1; j<arr.length; j++){if(arr[i]==arr[j]){         //第一个等同于第二个,splice方法删除第二个arr.splice(j,1);j--;}}}
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null,NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}]//NaN和{}没有去重,两个null直接消失了

2.利用indexOf去重
// 封装函数

       function unique(arr) { //unique 独特的var newArr = [];for (var i = 0; i < arr.length; i++) {if (newArr.indexOf(arr[i]) == -1)newArr.push(arr[i]); // push() 在数组末尾添加元素}return newArr;}// 代码验证console.log(unique([1, 2, 2, 3, 3, 3,]));// [1,2,3]console.log(unique([NaN, NaN, true, true, 'a', 'a', undefined, undefined, {},         {}]));//  [NaN, NaN, true, "a", undefined, {…}, {…}]3.ES6 的 Set 对象
var arr =[1,2,3,3,1,4];
[...new Set(arr)];  //[1,2,3,4]
Array.from(new Set(arr)  //[1,2,3,4]

7、字符串去重

var str = 'abcvvna'
console.log([...new Set(str)].join(''))

8、为Array对象添加一个去除重复项的方法

Array.prototype.uniq = function(){return Array.from(new Set(this))
}

9、正则表达式 \d 匹配一个数字字符串 等价于 [0-9]

function containsNumber(str){var b=/\d/; return b.test(str)
}

10.数组的实例方法

  1. push 压栈 在当前数组尾部添加数据 var arr = [1,2,3,4,5,6];

     arr.push(8)    输出 [1,2,3,4,5,6,8];
    
  2. pop 弹栈 在当前数组尾部删除数据 var arr = [1,2,3,4,5,6];

    arr.pop()    输出 [1,2,3,4,5]; 长度改变
    
  3. unshift 在当前数组头部添加数据 var arr = [1,2,3,4,5,6];

     arr.unshift(8)    输出 [8,1,2,3,4,5,6];
    
  4. shift 弹栈 在当前数组尾部删除数据 var arr = [1,2,3,4,5,6];

    arr.shift()    输出 [1]; 返回的是被删除的元素
    
  5. join 把数组转为字符串

       var arr =["a","b","c","d","e","f"]console.log(arr.join());      输出   a,b,c,d,e,fconsole.log(arr.join("-"));   输出 a-b-c-d-e-fconsole.log(arr.join(""));    输出  abcdef

6、 indexOf 查找数组中是否存在指定的值
格式:数组对象.indexOf(key,[fromIndex])
key:代表要查找的值
fromIndex:可选参数,指的是从哪个索引(包含)开始往后查找。 如果省略,代表从0开始。
返回:如果存在返回数组元素的下标,否则返回-1;
注意:返回的是第一个相等的元素的下标。找到之后立即停止。
var arr = [34, 5, 76, 54, 34, 23, 56, 76]; console.log(arr.indexOf(76));//2 console.log(arr.indexOf(76, 3));//7
7、 lastIndexOf() 从最后一个元素开始往前找。但是元素的下标还是从前往后的。
8、slice 切割
作用:从当前数组中取出指定的元素,用这些元素生成一个新的数组。
格式:数组对象.slice(start,end)
start:截取的元素的起始坐标。包含。
end:截取的元素的结束坐标。不包含。
9、splice
splice有如下几个功能:
1.删除-用于删除元素,两个参数,第一个参数(要删除第一项的位置),第二个参数(要删除的项数)
2.插入-向数组指定位置插入任意项元素。三个参数,第一个参数(起始位置),第二个参数(0),第三个参数(插入的项数)
3.替换-向数组指定位置插入任意项元素,同时删除任意数量的项,三个参数。第一个参数(起始位置),第二个参数(删除的项数),第三个参数(插入任意数量的项)
具体看代码实现效果:
var list = [;
list.push(1);list.push(2);list.push(3);
console.log(list);l/[1,2,3]
川删除
list.splice(0,1);I/删除>从下标为0开始,项数为1console.log(list);// [2,3]
list.splice(0,2);l/删除>从下标为0开始,项数为2console.log(list);// []
//替换
list.splice(0,1,4);//替换>从下标为0开始,项数为1的数组元素替换成4console.log(list);l/ [4,2,3]
list.splice(0,2,4);/替换>从下标为0开始,项数为2的数组元素替换成4(即4,2整体替换成4)console.log(list);l/[4,3]
/添加
list.splice(1,0,5);//表示在下标为1处添加一项5console.log(list);l/[1,5,2,3]

10、 reverse 翻转
var arr9 = [1,2,3,4,5,6,7];
arr9.reverse(); console.log(arr9); [7,6,5,4,3,2,1];
11、 sort 数组排序

11.遍历数组方法

map()
let arr = [1,2,3]; arr = arr.map(item => { return item * 2 })
filter() find()

12.判断是数组还是对象 Array.isArray()

var arr10 =[1,2]
console.log(Array.isArray(arr10)); 数组返回 true
var obj={
1:5
}
console.log(Array.isArray(obj)); 对象返回 false

13.数值转换

Number() parseInt() parseFloat()

14转换为字符串 toString()

var a=2; a = a+‘’; console.log(a)

15条件操作符

let max =(num1 > num2) ? num1:num2
在这个例子中,max 将被赋予一个最大值。这个表达式的意思是,如果 num1 大于 num2(条件表
达式为 true),则将 num1 赋给 max。否则,将 num2 赋给 max。

16.

① async 表示应该立即开始下载脚本,但不能阻止其他页面动作,只对外部脚本文件有效
② defer 表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效
③ src:表示包含要执行的代码的外部文件。

这是javascript

17. var let const

var、let和count的区别?
都是一个对象声明
1.var可重复声明,并且有变量提升
console.log(a); //var a=undefined
var a=“111”;
var a=1111;
console.log(a);//1111
2.let不能进行重复声明,没有变量提升
块级作用域,只要是{ }就都是块级作用域
3.count通常用来声明一个常量,例如π
不可重复声明
值不可以修改,如果修改必须是对象,对象是引用数据类型

18.数据类型

Undefined Null Boolean Number String Symbol(符号)是ECMAScript新增地,复杂数据类型 Object(对象) function object array date

19 基本数据类型和复杂数据类型的区别

内存的分配不同
基本数据类型存放在栈内存中
复杂数据类型存放在堆内存中,栈中存储的变量,是指向堆中的引用地址

访问机制不同
基本数据类型是按值访问
复杂数据类型按引用访问,JS不允许直接访问保存在堆内存中的对象,在访问一个对象的时候,首先先得到的是这个对象在堆内存中的地址,然后再按照这个地址去获得这个对象中的值

复制变量时不同(a=b)
基本数据类型: a=b;是将b中保存的原始值的副本赋值给新变量a,a和b完全独立,互不影响
复杂数据类型: a=b;将b保存的对象内存的引用地址赋值给了新变量a;a和b指向了同一个堆内存地址,其中一个值发生了改变,另一个也会发生改变

20模板字面量

    let pageHTML = ` <div> <a href="#"> <span>Jake</span> </a> </div>`;

21、 break 和 continue

break 和 continue 语句为执行循环代码提供了更严格的控制手段。其中,break 语句用于立即退
出循环,强制执行循环后的下一条语句。而 continue 语句也用于立即退出循环,但会再次从循环顶部
开始执行。

22、 let now = new Date();

let now = new Date(“5/23/2019”);

23、 RegExp 正则

g:全局模式,表示查找字符串的全部内容,而不是找到第一个匹配的内容就结束。
i:不区分大小写,表示在查找匹配时忽略 pattern 和字符串的大小写。
m:多行模式,表示查找到一行文本末尾时会继续查找。
y:粘附模式,表示只查找从 lastIndex 开始及之后的字符串。
u:Unicode 模式,启用 Unicode 匹配。
s:dotAll 模式,表示元字符.匹配任何字符(包括\n 或\r)。
// 匹配字符串中的所有"at"  let pattern1= /at/g;

24.集合引用类型

创建对象 Object

使用new操作符和Object构造函数 Let person = new Object();
使用 对象字面量 let person ={ name:“wsy”,age = 69 }

创建数组 Array();

构造函数 let colors =new Array(20);
字面量 let names = [];

25.class

类的内部还是一个函数 类面向对象
定义的方法放在原型中的好处 :通过该构造函数生成的实例所拥有的方法都是指向一个函数的索引
,这样可以节省内存。
constructor 为对象做属性初始值的

26. js的防抖和节流

1.什么是节流防抖
防抖 :持续触发事件时,在单位事件只触发最后一次事件,若在单位事件内还触发,则从新计算
节流:持续触发事件时,在单位时间只触发一次
2.什么时候用到节流防抖
防抖(debounce)
1.input的搜索
2.window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件
节流(throttle)
1.鼠标不断点击触发,mousedown(单位时间内只触发一次)
2.监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
*/
3. 防抖

   <input type="text" class="username">const inp = document.querySelector('.username')function debounce(fn, time) {let timeout = null; // 创建一个标记用来存放定时器的返回值return function () {clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数fn.apply(this, arguments);//arguments是传入的参数console.log(this,'this指向');console.log(arguments,'arguments是什么');}, time);};}function sayHi(e) {console.log(e.target.value);}// var inp = document.getElementById('inp');inp.addEventListener('input', debounce(sayHi, 5000)); // 防抖

27. 递归

递归(recursive)函数是“自己调用自己”的函数,主函数调用一个函数,这个函数内部又在此调用这个函数,一直调用自己,调用的条件逐渐逼向边界,最后从边界开始返回,即可以说是“后调用的先返回”。

 function DiGui(n){if(n == 1){return 1}else{return n*DiGui(n-1)}}console.log(DiGui(3));

28. this指向

1.默认绑定规则  独立调用指向window
2.隐式绑定规则 谁调用指向谁

3.显示绑定 call() apply() bind()
5 箭头函数中的this
向外层作用域中,一层层找this,直到找到this的定义,箭头函数中的this是在定义函数的时候绑定的不是在执行函数的时候绑定的
但是在Vue实例中,methods中如果用的是正常函数,那么它的this就指向Vue实例;如果是箭头函数,this就指向window对象。
1.全局环境下的this指向 window

function f1(){console.log(this)
}
f1() //window
例子2 const foo = {bar:10,fn:function(){console.log(this)console.log(this.bar)}
}foo.fn()  // {bar:10,fn:f}  10n

29. JavaScript中什么是基本数据类型什么是引用数据类型?以及各个数据类型是如何存储的?

1 基本数据类型有
Number,String,Boolean,Null,Undefined,Symbol(ES6新增数据类型),bigInt
2 引用数据类型统称为Object类型,细分的话有
Object,Array,Date,Function,RegExp
基本数据类型的数据直接存储在栈中;而引用数据类型的数据存储在堆中,每个对象在堆中有一个引用地址。引用类型在栈中会保存他的引用地址,以便快速查找到堆内存中的对象。
顺便提一句,栈内存是自动分配内存的。而堆内存是动态分配内存的,不会自动释放。所以每次使用完对象的时候都要把它设置为null,从而减少无用内存的消耗

20.在js中为什么 0.2+0.1 > 0.3

因为在js中,浮点数是用64位固定长度来表示的,其中1的位置表示符号位,11位表示指数位,剩下的52位是尾数为,由于只有52位表示尾数位,而0.1转为二进制是一个无限循环数0.0001100110011001100…(1100循环),由于只能存储52位尾数位,所以会出现精度缺失,把它存到内存中再取出来转换成十进制就不是原来的0.1了,就变成了0.100000000000000005551115123126,而为什么02+0.1是因为

21. 那为什么0.2+0.3=0.5呢?

0.2 和0.3分别转换为二进制进行计算:在内存中,它们的尾数位都是等于52位的,而他们相加必定大于52位,而他们相加又恰巧前52位尾数都是0,截取后恰好是0.1000000000000000000000000000000000000000000000000000也就是0.5

22.那既然0.1不是0.1了,为什么在console.log(0.1)的时候还是0.1呢?

在console.log的时候会二进制转换为十进制,十进制再会转为字符串的形式,在转换的过程中发生了取近似值,所以打印出来的是一个近似值的字符串

30.判断数据类型有几种方法

  1. typeof
    缺点:typeof null的值为Object,无法分辨是null还是Object
  2. instanceof
    缺点:只能判断对象是否存在于目标对象的原型链上
    function Foo() { }var f1 = new Foo();var d = new Number(1)console.log(f1 instanceof Foo);// trueconsole.log(d instanceof Number); //trueconsole.log(123 instanceof Number); //false   -->不能判断字面量的基本数据类型
  1. constructor
    constructor是每个实例对象都拥有的属性
    4.Object.prototype.toString.call()
    一种最好的基本类型检测方式 Object.prototype.toString.call() ;它可以区分 null 、 string 、
    boolean 、 number 、 undefined 、 array 、 function 、 object 、 date 、 math 数据类型。
    console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]" console.log(Object.prototype.toString.call(null)); // "[object Null]" console.log(Object.prototype.toString.call(123)); // "[object Number]" console.log(Object.prototype.toString.call("abc")); // "[object String]" console.log(Object.prototype.toString.call(true)); // "[object Boolean]" function fn() {console.log("ming");}var date = new Date();var arr = [1, 2, 3];var reg = /[hbc]at/gi;console.log(Object.prototype.toString.call(fn));// "[object Function]" console.log(Object.prototype.toString.call(date));// "[object Date]" console.log(Object.prototype.toString.call(arr)); // "[object Array]"

31.instanceof原理

instanceof原理实际上就是查找目标对象的原型链
instanceof 主要的实现原理就是只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false。
下面展示一些 内联代码片

    function instanceof(left, right) {const rightVal = right.prototypeconst leftVal = left.__proto__// 若找不到就到一直循环到父类型或祖类型while(true) {if (leftVal === null) {return false}if (leftVal === rightVal) {return true}leftVal = leftVal.__proto__ // 获取祖类型的__proto__}}

25.为什么typeof null是Object

因为在JavaScript中,不同的对象都是使用二进制存储的,如果二进制前三位都是0的话,系统会判断为是Object类型,而null的二进制全是0,自然也就判断为Object
000 对象
1 整型
010 双精度类型
100字符串
110布尔类型

32.和=有什么区别

===是严格意义上的相等,会比较两边的数据类型和值大小
数据类型不同返回false
数据类型相同,但值大小不同,返回false
==是非严格意义上的相等,
两边类型相同,比较大小
两边类型不同,根据下方表格,再进一步进行比较。
Null == Undefined ->true
String == Number ->先将String转为Number,在比较大小
Boolean == Number ->现将Boolean转为Number,在进行比较
Object == String,Number,Symbol -> Object 转化为原始类型

33.call,apply,bind

call和 apply 的功能相同,区别在于传参的方式不一样:
fn.call(obj, arg1, arg2, …),调用一个函数, 具有一个指定的this值和分别地提供的参数(参数的列表)。
fn.apply(obj, [argsArray]),调用一个函数,具有一个指定的this值,以及作为一个数组(或类数组对象)提供的参数。
bind 和call/apply 有一个很重要的区别,一个函数被 call/apply 的时候,会直接调用,但是bind 会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。
call:

Function.prototype.myCall = function (context) {// 先判断调用myCall是不是一个函数// 这里的this就是调用myCall的if (typeof this !== 'function') {throw new TypeError("Not a Function")}// 不传参数默认为windowcontext = context || window// 保存thiscontext.fn = this// 保存参数let args = Array.from(arguments).slice(1)   //Array.from 把伪数组对象转为数组// 调用函数let result = context.fn(...args)delete context.fnreturn result}

34.:字面量创建对象和new创建对象有什么区别,new内部都实现了什么,手写一个new

字面量:
字面量创建对象更简单,方便阅读
不需要作用域解析,速度更快
new内部:
1.创建一个新对象
2.使新对象的__proto__指向原函数的prototype
3.改变this指向(指向新的obj)并执行该函数,执行结果保存起来作为result
4.判断执行函数的结果是不是null或Undefined,如果是则返回之前的新对象,如果不是则返回result
手写new
// 手写一个new
function myNew(fn, …args) {
// 创建一个空对象
let obj = {}
// 使空对象的隐式原型指向原函数的显式原型
obj.proto = fn.prototype
// this指向obj
let result = fn.apply(obj, args)
// 返回
return result instanceof Object ? result : obj
}

35.什么是作用域,什么是作用域链?

规定变量和函数的可使用范围称作作用域
每个函数都有一个作用域链,查找变量或者函数时,需要从局部作用域到全局作用域依次查找,这些作用域的集合称作作用域链。

36.什么是执行栈,什么是执行上下文?

执行栈
1.首先栈特点:先进后出
2.当进入一个执行环境,就会创建出它的执行上下文,然后进行压栈,当程序执行完成时,它的执行3.上下文就会被销毁,进行弹栈。
4.栈底永远是全局环境的执行上下文,栈顶永远是正在执行函数的执行上下文
5.只有浏览器关闭的时候全局执行上下文才会弹出

37、什么是闭包?闭包的作用?闭包的应用?

下面展示一些 内联代码片

function AA (){let num =1return function BB(){console.log(num);}}console.log(AA());let CC = AA()CC()//let CC = AA() //这里是调用了一个AA()函数, 但是AA()函数所返回的是一个函数引用
// CC()  //所以要赋值给CC再加个括号() 调用一次方法.

什么是闭包
闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
function outer() {
var a = ‘变量1’
var inner = function () {
console.info(a)
}
return inner // inner 就是一个闭包函数,因为他能够访问到outer函数的作用域
}
闭包的作用
函数执行,形成私有的执行上下文,使内部私有变量不受外界干扰,起到保护和保存的作用

38、什么是原型?什么是原型链?

##1.什么是原型对象
1.在Javascript中,当系统加载构造函数后,会自动在内存中生成一个对象,这个对象就是原型对象。两者之间在内存中表现为相对独立,不存在谁包含谁的关系。但是两者之间又有一些关联,在构造函数的内部存在一个prototype属性指向原型对象,同时在原型对象的内存也存在一个属性constructor其指向了构造函数。

##2. 构造函数 原型对象 实例对象的关系

##3 prototype和__proto__的区别和联系
prototype是构造函数访问原型对象,__proto__是对象实例访问原型对象。
任意一个函数(包括构造函数)都有一个prototype属性,指向该函数的原型对象
一个构造函数实例化的对象,都有一个__proto__属性 指向构造函数的原型对象
function a() {
//console.log(“I’am a function.”);
}
//b是实例化对象,a是构造函数
var b = new a();

console.log(b.proto == a.prototype);

原型:
原型分为隐式原型和显式原型,每个对象都有一个隐式原型,它指向自己的构造函数的显式原型。
原型链: 多个__proto__组成的集合成为原型链
所有实例的__proto__都指向他们构造函数的prototype
所有的prototype都是对象,自然它的__proto__指向的是Object()的prototype
所有的构造函数的隐式原型指向的都是Function()的显示原型
Object的隐式原型是null

39、说一说 JS 中的常用的继承方式有哪些?以及各个继承方式的优缺点。

原型继承、构造函数继承、组合继承、寄生组合继承、ES6的extend
1.原型链继承
优点:父类方法可以复用
缺点:父类所有的引用类型数据(对象,数组)会被子类共享,
改变一个子类的数据,其他数据会受影响,一起变化
缺点2:子类实例不能给父类构造函数传参

function Person(){this.name = "小明"this.eats = ["苹果"]this.getName = () =>{console.log(this.name);}
}
Person.prototype.get = () =>{console.log("Person.prototype上的方法");
}function Student(){}
Student.prototype = new Person()const stu1 = new Student()
stu1.name = "小花"
stu1.eats.push("香蕉")
console.log(stu1.name);
console.log(stu1.eats);
console.log("+++++++++++++++++++++++++++++++++");
const stu2 = new Student()
console.log(stu2.name);
console.log(stu2.eats);

2.构造函数的继承
优点:父类所有的引用类型数据(对象,数组)会被子类共享,
缺点:子类不能访问父类原型属性上的方法和参数

        function Person() {this.name = "小明"this.eats = ["苹果"]this.getName = () => {console.log(this.name);}}Person.prototype.get = () => {console.log("Person.prototype上的方法");}function Student() { Person.call(this)}const stu1 = new Student()

3.组合继承
优点:1.父类可以服用
2.父类所有的引用类型数据(对象,数组)不会被子类共享,
缺点:调用两次父类的构造函数 会用两份一样的属性和方法 会影响性能

 function Person() {this.name = "小明"this.eats = ["苹果"]this.getName = () => {console.log(this.name);}}Person.prototype.get = () => {console.log("Person.prototype上的方法");}function Student() { Person.call(this)}Student.prototype = new Person()const stu1 = new Student()

4.寄生组合继承
优点:1.父类可以服用
2.父类所有的引用类型数据(对象,数组)不会被子类共享,
缺点:调用两次父类的构造函数 会用两份一样的属性和方法 会影响性能

        function Person() {this.name = "小明"this.eats = ["苹果"]this.getName = () => {console.log(this.name);}}Person.prototype.get = () => {console.log("Person.prototype上的方法");}function Student() { Person.call(this)}const Fn =function(){Fn.prototype = Person.prototype}Student.prototype = new Fn()const stu1 = new Student()

40、什么是内存泄漏

内存泄露是指不再用的内存没有被及时释放出来,导致该段内存无法被使用就是内存泄漏

41、为什么会导致的内存泄漏

内存泄漏指我们无法在通过js访问某个对象,而垃圾回收机制却认为该对象还在被引用,因此垃圾回收机制不会释放该对象,导致该块内存永远无法释放,积少成多,系统会越来越卡以至于崩溃

42、垃圾回收机制都有哪些策略

标记清除法
垃圾回收机制获取根并标记他们,然后访问并标记所有来自它们的引用,然后在访问这些对象并标记它们的引用…如此递进结束后若发现有没有标记的(不可达的)进行删除,进入执行环境的不能进行删除
引用计数法
当声明一个变量并给该变量赋值一个引用类型的值时候,该值的计数+1,当该值赋值给另一个变量的时候,该计数+1,当该值被其他值取代的时候,该计数-1,当计数变为0的时候,说明无法访问该值了,垃圾回收机制清除该对象

43、深拷贝和浅拷贝

 1.JSON转换方案缺点:数据类型为function或者数值为undefined情况下无法复制2.  Object.assign({},obj111) 缺点:只能深拷贝一级属性,二级及以上属性就是浅拷贝3. 扩展运算符 {...obj1}缺点:只能深拷贝一级属性,二级及以上属性就是浅拷贝4. slice() / concat()缺点:只能深拷贝一级属性,二级及以上属性就是浅拷贝5. 递归

深拷贝还是得递归
// ----------------------------------------------浅拷贝

    // 只是把对象的属性和属性值拷贝到另一个对象中var obj1 = {a: {a1: { a2: 1 },a10: { a11: 123, a111: { a1111: 123123 } }},b: 123,c: "123"}// 方式1function shallowClone1(o) {let obj = {}for (let i in o) {obj[i] = o[i]}return obj}// 方式2var shallowObj2 = { ...obj1 }// 方式3var shallowObj3 = Object.assign({}, obj1)let shallowObj = shallowClone1(obj1);shallowObj.a.a1 = 999shallowObj.b = trueconsole.log(obj1);  //第一层的没有被改变,一层以下就被改变了

// ----------------------------------------------深拷贝

    // 简易版  function deepClone(o) {let obj = {}for (var i in o) {// if(o.hasOwnProperty(i)){if (typeof o[i] === "object") {obj[i] = deepClone(o[i])} else {obj[i] = o[i]}// }}return obj}var myObj = {a: {a1: { a2: 1 },a10: { a11: 123, a111: { a1111: 123123 } }},b: 123,c: "123"}var deepObj1 = deepClone(myObj)deepObj1.a.a1 = 999deepObj1.b = false
console.log(myObj);

44、宏任务和微任务

js单线程 微任务(Promise)先执行
执行顺序:先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。
微process.nextTick (node.js中进程相关的对象), Promise, Object.observer, MutationObserver。
宏script(全局任务), setTimeout, setInterval, setImmediate, I/O, UI rendering.

45、Promise

promise是js中异步编程(axios)的新的解决方案(旧的就是单纯使用回调函数)解决回调地狱
Promise 是一个构造函数 用来封装一个异步操作,获取其成功和失败的结果

          let promise = new Promise(function(resolve,reject){const time = Date.now()if(time % 2 === 1){resolve(`成功 基数是:${time}`)}else{reject(`失败 偶数是:${time}`)}}).then(function(value){console.log(value);},function(reson){console.log(reson);})

问题一:Promise如何改变状态
1.resolve 2.reject 3. 在执行器中 抛出异常那个会变成rejected
抛出异常是指在执行器函数中 并不是在异步函数中

问题二:promise.then()返回的新的promise的执行结果状态由什么决定
(1)简单表达:有then()指向的回调函数执行的结果决定
(2)详细表达:
① 如果抛出异常,新的promise变为rejected,reson为抛出的异常
② 如果返回的是非promise的任意值,新的promise变为resolved,value为返回的值
③ 如果返回的是一个新的promise 此promise的结果就会变成新的promise的结果
问题三:怎么中断promise链
在回调函数中返回一个pedding状态的promise对象
return new Promise(()=>{})
问题四:promise常用的api
.then .catch
.all 参数是promise实例 // 零秒之后输出 [1,2,3] p2,p3的输出等待p1结束后输出
// 都是成功状态 输出全部的成功状态,
// 若有失败状态 输出第一个失败状态

    let p1 = new Promise(function(resolve,reject){setTimeout(()=>{resolve(1)},2000)})let p2 = Promise.resolve(2)let p3 = Promise.resolve(3)let p4 = Promise.all([p1,p2,p3])p4.then(function(values){console.log(values);},function(reson){console.log(reson);})

Promise.race
说明:返回一个新的promise,第一个完成懂得promise的结果状态是最终的结果状态
// promise 构造函数上的方法 .reject 获取失败状态的promise
/ promise 构造函数上的方法 .resolve获取失败状态的promise

二、Webpack

1.webpack是什么?

一种前端资源构建工具,一个静态模块打包器(nodule bundle)
前端所有资源文件(js/json/css/img…)都会作为模块处理
它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)

2.Webpack 五个核心概念分别是什么?

Entry
入口(Entry)指示 Webpack 以哪个文件为入口起点开始打包,分析内部构件依赖图
Output
输出(Output)指示 Webpack 打包后的资源 bundles 输出到哪里去,以及如何命名
Loader
Loader 能让 Webpack 处理非 JavaScript/json 文件(Webpack 自身只能处理 JavaScript/json )
Plugins
插件(Plugins)可以用于执行范围更广的任务,包括从打包优化和压缩到重新定义环境中的变量
Mode
模式(Mode)指示 Webpack 使用相应模式的配置,只有development(开发环境)和production(生产环境)两种模式

3.有哪些常见的Loader?它们是解决什么问题的?

1.css-loader:将 css 文件变成 CommonJS 模块加载 js 中,里面内容是样式字符串
2.style-loader:创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效
3.url-loader:在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
4.file-loader:打包其他资源(除了css/js/html 资源)
5.html-loader:处理 html 文件中的 img
6.babel-loader:把 ES6 转换成 ES5
7.eslint-loader:通过 ESLint 检查 JavaScript 代码

4.有哪些常见的Plugin?它们是解决什么问题的?

1.html-webpack-plugin:可以复制一个有结构的html文件,并自动引入打包输出的所有资源(JS/CSS)
2.clean-webpack-plugin:重新打包自动清空 dist 目录
3.mini-css-extract-plugin:提取 js 中的 css 成单独文件
4.optimize-css-assets-webpack-plugin:压缩css
5.uglifyjs-webpack-plugin:压缩js
6.commons-chunk-plugin:提取公共代码

5.webpack的构建流程是什么?

1.初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
2.开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
3.确定入口:根据配置中的 entry 找出所有的入口文件;
4.编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
5.完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
6.输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
7.输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统

6.webpack的热更新是什么?

热更新又称热替换(Hot Module Replacement),缩写为HMR,基于devServer,生产环境不需要devServer,所以生产环境不能用HMR功能
作用:优化打包构建速度,一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度
1.样式文件:可以使用HMR功能,因为style-loader内部实现了
2.JS文件:默认没有HMR功能,需要修改js代码,添加支持HMR功能。入口文件做不了HMR功能,只能处理非入口js文件
3.HTML文件:默认没有HMR功能,同时会导致 html 文件不能热更新(即修改没有任何反应)
解决方案:
修改entry入口,将html文件引入
entry:[‘./src/js/index.js’,‘./src/index.html’]
1
不用做HMR功能,因为只有一个html文件

7.如何利用webpack来优化前端性能?

开发环境下:
开启HMR功能,优化打包构建速度
配置 devtool: ‘source-map’,优化代码运行的性能
生产环境下:
1.oneOf 优化:默认情况下,假设设置了7、8个loader,每一个文件都得通过这7、8个loader处理(过一遍),浪费性能,使用 oneOf 找到了就能直接用,提升性能
2.开启 babel 缓存:当一个 js 文件发生变化时,其它 js 资源不用变
3.code split 分割:将js文件打包分割成多个bundle,避免体积过大
4.懒加载和预加载
5.PWA 网站离线访问
6.多进程打包:开启多进程打包,主要处理js文件(babel-loader干的活久),进程启动大概为600ms,只有工作消耗时间比较长,才需要多进程打包,提升打包速度

8.Webpack的基本功能有哪些?

代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
文件优化:压缩 JavaScript、CSS、html 代码,压缩合并图片等
代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

9.前端为什么要进行打包和构建?

代码层面:
体积更小(Tree-shaking、压缩、合并),加载更快
编译高级语言和语法(TS、ES6、模块化、scss)、兼容性和错误检查(polyfill,postcss,eslint)
研发流程层面:
统一、高效的开发环境、统一的构建流程和产出标准、集成公司构建规范(提测、上线)

三、Vue

1. vue的优点

轻量级框架 双向数据绑定 组件化 视图数据、结构分离, 指令,插件化

2. vue组件之间传值、传数据

3. v-show和 v-if相同点和不同点

v-show 利用css属性display来决定显示还是隐藏
v-if 本质是操作dom元素来进行切换,有一个销毁和重建的过程

4. 如何让css只在当前组件起作用

scoped

5. 如何获取dom 原生和vue中

vue中:使用ref ref=“name”
this.$refs.name.style.backgroundColor=“red”
原生的:document.getElementById(“id”)

6. v-model的使用

Message is: {{ message }}

v-model用于表单的双向绑定,其实他就是一个语法糖,两部分操作 v-bind绑定一个value属性 v-on指令给当前元素绑定input事件 ## 7. computed 计算属性和watch 监听器的区别 computed 1. 支持缓存,只有依赖数据发生改变,才会重新进行计算 2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化 3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值 4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed 5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法 watch 1. 不支持缓存,数据变,直接会触发相应的操作; 2.watch支持异步; 3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值; 4. 当一个属性发生变化时,需要执行对应的操作;一对多; 5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,   immediate:组件加载立即触发回调函数执行,   deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

   监听的对象也可以写成字符串的形式<template><div><input type="text" v-model="user_info.name"></div></template><script>export default{data(){return:{user_info:{name:'blue'}}},watch:{""user_info.name":function(){consoe.log("name变了")}}}</script>

8. $nextTick的使用

Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM,

   methods:{testClick:function(){let that=this;that.testMsg="修改后的值";that.$nextTick(function(){console.log(that.$refs.aa.innerText);  //输出:修改后的值});}

什么时候需要用的Vue.nextTick()??
(1) created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
(2) 改变DOM元素的数据后基于新的dom做点什么,对新DOM一系列的js操作都需要放进Vue.nextTick()的回调函数中;

9. vue组件中的data为什么必须是一个函数

因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象。
相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了。

10. vue中的数据双向绑定是什么,以及如何实现的

vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法。

      var obj = {};Object.defineProperty(obj,'hello',{set:function(newVal){document.getElementById('a').value = newVal;document.getElementById('b').innerHTML = newVal;}});

11.v-if和v-for的优先级

当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中。所以,不推荐v-if和v-for同时使用

12. assets和static的区别

相同点:assets和static两个都是存放静态资源文件。项目中所需要的资源文件图片,字体图标,样式文件等都可以放在这两个文件下,这是相同点
不相同点:assets中存放的静态资源文件在项目打包时,也就是运行npm run build时会将assets中放置的静态资源文件进行打包上传,所谓打包简单点可以理解为压缩体积,代码格式化。而压缩后的静态资源文件最终也都会放置在static文件中跟着index.html一同上传至服务器。static中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上传,在打包时会提高一定的效率,但是static中的资源文件由于没有进行压缩等操作,所以文件的体积也就相对于assets中打包后的文件提交较大点。在服务器中就会占据更大的空间。
建议:将项目中template需要的样式文件js文件等都可以放置在assets中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css等文件可以放置在static中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。

13. vue常用的修饰符

.prevent 阻止默认事件 a链接的跳转
.stop 防止事件冒泡
.self 只会触发自己范围内的事件,不包含子元素;
Div嵌套一个button,两个都有点击事件,谁的事件有.self 就执行谁的
.once 只出发一次

14. vue的两个核心点

数据驱动:ViewModel,保证数据和视图的一致性
当创建 Vue 实例时,vue 会遍历 data 选项的属性,利用 Object.defineProperty 为属性添加 getter 和 setter 对数据的读取进行劫持(getter 用来依赖收集,setter 用来派发更新),并且在内部追踪依赖,在属性被访问和修改时通知变化。
每个组件实例会有相应的 watcher 实例,会在组件渲染的过程中记录依赖的所有数据属性(进行依赖收集,还有 computed watcher,user watcher 实例),之后依赖项被改动时,setter 方法会通知依赖与此 data 的 watcher 实例重新计算(派发更新),
组件系统:应用类UI可以看作全部是由组件树构成

15. 什么是MVVM

MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。

16. vue组件封装的过程

1. 建立组件的模板,先把架子搭起来,写写样式,考虑好组件的基本逻辑。 
  2. 准备好组件的数据输入。即分析好逻辑,定好 props 里面的数据、类型。
  3. 准备好组件的数据输出。即根据组件逻辑,做好要暴露出来的方法。
  4. 封装完毕了,直接调用即可

17. vue初始化页面闪动问题

使用vue开发时,在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{{message}}的字样,虽然一般情况下这个时间很短暂,但是我们还是有必要让解决这个问题的。
首先:在css里加上[v-cloak] {
display: none;
}。
如果没有彻底解决问题,则在根元素加上style=“display: none;” :style=“{display: ‘block’}”
html


{{context}}

css [v-cloak]{
display: none;
}

18. vue修改打包后静态资源路径的修改

将 config/index.js 里的 assetsPublicPath 的值改为 ‘./’ 。
build: {
assetsPublicPath: ‘./’,
}

19. vue生命周期

beforecreate
Created:data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据
beforemounte
Mounted: 如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行
beforeupdate updated
beforedestroy destroyed
##20.vue获取数据在哪个周期函数
答:一般 created/beforeMount/mounted 皆可.
比如如果你要操作 DOM , 那肯定 mounted 时候才能操作.

21. 第一次页面加载会触发哪几个钩子?

beforeCreate, created, beforeMount, mounted
##22.在哪个阶段有el,在哪个阶段有el,在哪个阶段有el,在哪个阶段有data
在$el就是组件的根节点 data就是数据在create中有data,在mounted中有data就是数据 在create中有data,在mounted中有data就是数据在create中有data,在mounted中有el

如果加入了keep-alive会多两个生命周期 (缓存组件的),第一次进入组件会执行哪些生命周期,第二次或者第n次进入组件会执行哪些生命周期

Activated:组件激活时调用,deactivated:组件销毁之前调用,这一步,实例仍完全可用

22. vuex有哪几种属性?

有五种,分别是 State、 Getter、Mutation 、Action、 Module
state => 基本数据(数据源存放地)
getters => 从基本数据派生出来的数据
mutations => 提交更改数据的方法,同步!
actions => 像一个装饰器,包裹mutations,使之可以异步。
modules => 模块化Vuex

23 Vuex是单项数据流还是双向数据流

单项数据流

24 Vuex中的mutations和actions区别

mutations:都是同步事务
actions:提交mutations的 不是直接变更状态 可以包含任意异步

25 Vuex如何做到持久化

   Vuex本身不是持久化存储 使用localStorageexport default{state:{pathList:'这是地址管理',num:localStorage.getItem('num') || 1},getters:{},mutations:{add(state){state.num++localStorage.setItem('num',state.num)}},actions:{}
}

2.使用插件 vuex-parsist

23. 什么是虚拟dom 及其优缺点

虚拟 DOM,其实就是用对象的方式取代真实的 DOM 操作,把真实的 DOM 操作放在内存当中,在内存中的对象里做模拟操作。当页面打开时浏览器会解析 HTML 元素,构建一颗 DOM 树,将状态全部保存起来,在内存当中模拟我们真实的 DOM 操作,操作完后又会生成一颗 dom 树,两颗 DOM 树进行比较,根据 diff 算法比较两颗 DOM 树不同的地方,只渲染一次不同的地方。
##25.什么是插槽
占位符:父组件可以在这个占位符中填充任何模板代码,
匿名插槽,具名插槽,作用域插槽,element-ui中常见, 封装一些公共组件中常用到插槽
Router

动态路由,嵌套路由,命名路由,

编程式导航;this.router.push(‘/’)This.router.push(‘/’) This.router.push(‘/’)This.router.push({path:’/’})
传参 this.KaTeX parse error: Expected '}', got 'EOF' at end of input: …名路由传 用this.route.params接受
name:‘home’,
Params:{userId:123}
})
如果 用path跳转和params传参的话,用this.route接受是接不到的传参this.route接受是接不到的 传参 this.route接受是接不到的传参this.router.push({ //用命名路由传 用this.KaTeX parse error: Expected 'EOF', got '}' at position 56: …s:{userId:123} }̲) 传参 this.router.push({ //用命名路由传 用this.KaTeX parse error: Expected 'EOF', got '}' at position 55: …s:{userId:123} }̲) Query传参参数地址栏拼…router.push({ 用this.$route.query接受
Name:’About’,
Query:{id:1234}
})
通过props解耦
Routers:[
{path:’/user/:id’,computed:User,props:true} //第一种
{path:’/user2’,computed:User,props:{id:1111}} //第二种
{path:’/user/:id’,computed:User,props:function(toute){
Return:{id:123-
}
}}
]
//接收组件

{{id}}

//通过props解耦后的id可以直接使用 export default { Props:[‘id’] methods:{} }

路由重定向,路由模式,路由守卫,路由元信息,
路由组件传参:

<router-link :to=”{name:’user’,params:{userId:123}}”></router-link>
<router-link :to=”{name:’user’,query:{userId:123}}”></router-link>

##26.Vue中query与params两种传参的区别
query语法:

this.$router.push({path:“地址”,query:{id:“123”}}); 这是传递参数
this.$route.query.id; 这是接受参数

params语法:

this.$router.push({name:“地址”,params:{id:“123”}}); 这是传递参数
this.$route.params.id; 这是接受参数

区别:
1.首先就是写法得不同,query 得写法是 用 path 来编写传参地址,而 params 得写法是用 name 来编写传参地址,你可以看一下编写路由时候得相关属性,你也可以输出一下 路由对象信息 看一下
2.接收方法不同, 一个用 query 来接收, 一个用 params 接收 ,总结就是谁发得 谁去接收
3.query 在刷新页面得时候参数不会消失,而 params 刷新页面得时候会参数消失,可以考虑本地存储解决
4.query 传得参数都是显示在url 地址栏当中,而 params 传参不会显示在地址栏

27. $route 和 $router 的区别

router是VueRouter的实例,在script标签中想要导航到不同的URL,使用router是VueRouter的实例,在script标签中想要导航到不同的URL,使用router是VueRouter的实例,在script标签中想要导航到不同的URL,使用router.push方法。返回上一个历史history用$router.to(-1)
$route为当前router跳转对象。里面可以获取当前路由的name,path,query,parmas等。
##28 .router 和routes
router是实例,routes路由配置项 是路由的结合
##29. router-link和router-view
利用router-link的to属性进行页面跳转
Router-view是视图渲染时候的容器,组件就是渲染在router-vview组件的位置
##30.:vue-router 有哪几种导航钩子
全局守卫
全局前置守卫:router.beforeEach eg:比如没有登录
全局解析守卫:router.beforeResolve
全局后置钩子:router.afterEach
路由独享守卫
你可以直接在路由配置上定义 beforeEnter

const routes = [{path: '/users/:id',component: UserDetails,beforeEnter: (to, from) => {// reject the navigationreturn false},},

组件内守卫
beforeRouteEnter:在渲染该组件的对应路由被验证前调用
beforeRouteUpdate: 在当前路由改变,但是该组件被复用时调用
beforeRouteLeave:在导航离开渲染该组件的对应路由时调用
##31.路由懒加载
Component:()=>import(‘…/views/About.vue’)
路由跳转的时候才需要加载,一进入页面不会加载
使用原因:在单页应用中,如果没有应用懒加载,运用 webpack 打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,延时过长,不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时
原理:vue 异步组件技术:异步加载,vue-router 配置路由 , 使用 vue 的异步组件技术 , 实现按需加载。

32.vue-router的两种模式

答:hash模式:即地址栏 URL 中的 # 符号;
history模式:window.history对象打印出来可以看到里边提供的方法和记录长度。利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)。
##33.你都做过哪些 Vue 的性能优化
这里只列举针对 Vue 的性能优化 整个项目的性能优化是一个大工程 可以另写一篇性能优化的文章 哈哈

对象层级不要过深,否则性能就会差
不需要响应式的数据不要放到 data 中(可以用 Object.freeze() 冻结数据)
v-if 和 v-show 区分使用场景
computed 和 watch 区分使用场景
v-for 遍历必须加 key,key 最好是 id 值,且避免同时使用 v-if
大数据列表和表格性能优化-虚拟列表/虚拟表格
防止内部泄漏,组件销毁后把全局变量和事件销毁
图片懒加载
路由懒加载
第三方插件的按需引入
适当采用 keep-alive 缓存组件
防抖、节流运用
##34.vue-loader作用:
解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理,使其js可以写es6、style样式可以scss或less、
##35.为什么使用key?
需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。
作用主要是为了高效的更新虚拟DOM。
##36.单页面应用和多页面应用区别及优缺点
单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。
多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新
单页面的优点:
用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)。
单页面缺点:
不利于seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多。

四、Css

1.css引入方式

(1)内联样式(行内样式)

CSS

(2)内部样式 (3)外部样式(推荐)

2.@import和link的区别?

  1. @import是CSS提供加载样式的一种方式,只能用于加载CSS。link标签除了可以加载CSS外,还可以做很多其它的事情,比如定义rel连接属性等。
  2. 加载顺序的差别。当一个页面被加载的时候,link引用的CSS会同时被加载,@import引用的CSS会等到页面全部被下载完再被加载。所以有时候浏览@import加载CSS的页面时开始会没有样式(就是闪烁),网速慢的时候会比较明显。
  3. 兼容性的差别。@import在IE5以上才能识别,而link标签无此问题。
  4. 使用dom控制样式时的差别。当使用javascript控制dom去改变样式的时候,只能使用link标签,因为dom操作元素的样式时,用@import方式的样式也许还未加载完成。
    5.使用@import方式会增加HTTP请求,会影响加载速度,所以谨慎使用该方法。

3. 选择器

1 全局选择器 *{}
2 元素选择器 p a div
3 类选择器 class .
4 id选择器 id #
选择器优先级
元素选择器的权重为0001,class选择器的权重为0010,id选择器的权重为0100,内联样式的权重为1000
行内样式>ID选择器>类选择器>元素选择器
5 后代选择器 div p
6 子代选择器 div>p
7 相邻兄弟选择器 选择紧跟E元素后的F元素,用加好表示,选择相邻的第一个兄弟元素。

h1元素

第一个元素

第二个元素

h1+p{color:red;} 伪类选择器 (1):link “链接”:超链接点击之前(只适用于a) (2):visited “访问过的”:链接被访问过之后(只适用于a) (3):hover “悬停”:鼠标放到标签上的时候(适用于所有标签) (4):active “激活”: 鼠标点击标签,但是不松手时。(适用于所有标签) :first-child 选择器 :first-child 选择器匹配其父元素中的第一个子元素。 li:first-child{ background:yellow; } :last-child 选择器 :last-child选择器用来匹配父元素中最后一个子元素。 p:last-child{ background:#ff0000; } :nth-child ()选择器 :nth-child(n) 选择器匹配父元素中的第 n 个子元素,元素类型没有限制。 n 可以是一个数字,一个关键字,或者一个公式。 伪对象选择器 ul::before{content:"这是ul的伪元素"; color: blue;} ul::after{content:"这是之后的伪元素";} 属性选择器

4.盒模型

标准和模型和怪异和模型的区别,及相互转化
标准盒的实际宽度 就是width 怪异盒的实际 是width+border+padding
box-sizing: content-box; 转为标准盒模型
box-sizing: border-box; 转为怪异盒模型

5.弹性盒模型

弹性容器通过设置 display 属性的值为 flex 将其定义为弹性容器。
5.1 父元素上有什么属性
(1)flex-direction属性,
flex-direction 属性指定了弹性子元素在父容器中的位置。属性值如下:
row:横向从左到右排列(左对齐),默认的排列方式。
row-reverse:反转横向排列(右对齐,从后往前排,最后一项排在最前面。
column:纵向排列。
column-reverse:反转纵向排列,从后往前排,最后一项排在最上面。
(2)justify-content 属性
内容对齐(justify-content)属性应用在弹性容器上,把弹性项沿着弹性容器的主轴线(main axis)对齐,属性值如下:
①flex-start:
弹性项目向行头紧挨着填充。这个是默认值。第一个弹性项的main-start外边距边线被放置在该行的main-start边线,而后续弹性项依次平齐摆放。
②flex-end:
弹性项目向行尾紧挨着填充。第一个弹性项的main-end外边距边线被放置在该行的main-end边线,而后续弹性项依次平齐摆放。
④space-between:
弹性项目平均分布在该行上。如果剩余空间为负或者只有一个弹性项,则该值等同于flex-start。否则,第1个弹性项的外边距和行的main-start边线对齐,而最后1个弹性项的外边距和行的main-end边线对齐,然后剩余的弹性项分布在该行上,相邻项目的间隔相等。
⑤space-around:
弹性项目平均分布在该行上,两边留有一半的间隔空间。如果剩余空间为负或者只有一个弹性项,则该值等同于center。否则,弹性项目沿该行分布,且彼此间隔相
(3) align-items 属性
align-items 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式。
①flex-start:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
②flex-end:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
③center:弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
5.2 子元素上的属性
flex-grow flex-grow 根据弹性盒子元素所设置的扩展因子作为比率来分配剩余空间。
默认为0,即如果存在剩余空间,也不放大。
如果只有一个子元素设置,那么按扩展因子转化的百分比对其分配剩余空间。0.1即10%,1即100%,超出按100%

6.margin需要注意的问题

(1)外边距合并问题
垂直方向上外边距相撞时,取较大值
注意:浮动元素的外边距不合并
(2)margin-top问题
当给子元素设置margin-top时,父元素会跟着子元素一起下来:解决方法:
①父元素设置overflow:hidden;
②父元素或者子元素设置float
③父元素设置border:1px solid transparent;
④父元素设置padding-top:1px;

7.怎么清除浮动

(1)设置父布局的高度
(2)受影响的元素加clear属性
clear:left | right | both;
(3)overflow清除浮动
这种情况下,父布局不能设置高度。
父级标签的样式里面加: overflow:hidden;
(4)空div法
在最后一个浮动的盒子的后面,新添加一个标签。然后设置clear清除浮动。
这种情况下,父布局不能设置高度。

8.display有什么属性值 及其作用

none 此元素不会被显示。
block 此元素将显示为块级元素,此元素前后会带有换行符。
inline inline 默认。此元素会被显示为内联元素,元素前后没有换行符。
inline-block 行内块元素
Flex 弹性盒模型

9. css3有哪些新特性 举例说明

圆角 border-radius: 15px 50px 30px 5px;
盒阴影 box-shadow: 10px 10px green;
h-shadow 水平阴影的位置 必须 v-shadow 垂直阴影的位置 必须
字阴影 text-shadow: h-shadow v-shadow blur color;
背景颜色渐变 background: linear-gradient(direction, color-stop1, color-stop2, …);

10,响应式设计有哪些

媒体查询media
多列 column-count

11.元素水平垂直居中

1、一个已知高宽的div在不同分辨率屏幕垂直,水平居中 ,css实现

div{
position:absolute;
width:200px;
height:200px;
top:50%;
left:50%;
margin-left:-100px;
margin-top:-100px;
}

12.画一个三角形

.triangle{
width: 0;
height: 0;
border:100px solid transparent;
border-bottom:100px solid blue;
}

13 常见的兼容性问题?

不同浏览器的标签默认的margin和padding不一样。*{margin:0;padding:0;}

五、HTML

1.from表单中post和get提交数据的区别:

1、数据提交方式,get把提交的数据url可以看到,post看不到
2、get一般用于提交少量数据,post用来提交大量数据

2.H5新增语义化标签

...

头部

导航

侧边栏

...

页脚

常见vue、js,webpack面试题相关推荐

  1. vue.js 常见面试题_使用Vue.js时应避免的常见错误

    vue.js 常见面试题 Looking for a front-end framework to try out, I started with React and then tried Vue.j ...

  2. nodejs+vue.js+webpack

    前端: nodejs+vue.js+webpack 后台:ssb(Spring+SpringMVC + mybatis-plus) 开发工具:idea 一.前提 1.安装nodejs 2.安装完nod ...

  3. 基于Vue JS, Webpack 以及Material Design的渐进式web应用 [Part 1]

    基于Vue JS, Webpack 以及Material Design的渐进式web应用 [Part 1] 原文:基于Vue JS, Webpack 以及Material Design的渐进式web应 ...

  4. [译]基于Vue JS, Webpack 以及Material Design的渐进式web应用 [Part 1]

    渐进式web应用是大势所趋.越来越多的大公司开始使用这些技术(比如推特:https://mobile.twitter.com/). 想象你可以在地铁中浏览一个web应用,这个应用能够向用户推送通知并且 ...

  5. vue 高阶面试题_15个 Vue.js 高级面试题,必收藏

    1. 渲染项目列表时,"key" 属性的作用和重要性是什么? 渲染项目列表时,key 属性允许 Vue 跟踪每个 Vnode.key 值必须是唯一的. 如果没有使用 key 属性, ...

  6. 常见的js算法面试题收集,es6实现

    1.js 统计一个字符串出现频率最高的字母/数字 let str = 'asdfghjklaqwertyuiopiaia'; const strChar = str => {let string ...

  7. vue.js+webpack 为 img src 赋值的路径问题解决方法

    首先,如果使用的是img标签那么可以这样 data () {return {img: require('@/assets/SavingOverview/1.png')} }然后在template中&l ...

  8. 总结下用Vue.js和webpack遇到的问题

    这段时间用vue.js+webpack做一个单页应用的demo,第一次尝试模块化,技术水平有限,学习不够深入,总是遇到各种问题,所谓前事不忘后事之师,so记录下. 1.ES6匿名函数里面this值 结 ...

  9. vue实现div多选全选功能_怎样为你的 Vue.js 单页应用提速

    每日前端夜话第323篇 翻译:疯狂的技术宅 作者:Matthias Sommer 来源:dzone 正文共:1956 字 预计阅读时间:10 分钟 我有一个项目用了 Vue.js 来构建单页应用程序. ...

  10. 在ASP.NET Core 3.1 MVC中集成Vue.js V4和使用Dropzone文件上传

    目录 介绍 先决条件 Node.js的介绍 您已经安装了Node.js/NPM吗? Node/ NPM版本相关的常见错误 Vue.js简介 安装Vue.js V4 NET Core介绍 安装Visua ...

最新文章

  1. python中json.dump() 和 json.dumps() 有那些区别?
  2. python八大选择排序_python之八大排序方法
  3. Java基础---代码块和final关键字
  4. beoplay耳机序列号查询_BO Beoplay E8评测:真正无线耳机,可自定义EQ设置和透明模式!...
  5. Java设计模式及类图
  6. qtoolbutton设置图标大小及文字位置
  7. wim工具扫描linux磁盘,图文解说WIMTOOL的安装及利用该工具编辑WIM文件
  8. 算法基础:基本数据结构的特点:队列 vs 栈
  9. 购买一台计算机需要哪些配件,组装一台电脑需要哪些配件【详细列举】
  10. 详解navigator对象
  11. td-agent windows 安装步骤
  12. office是什么意思
  13. 网络入门-IP地址规划
  14. 倒计时2天:百度“文心一言”即将上线!
  15. python代码变量作业_1作业python数据类型 条件循环 列表
  16. Python数据分析案例08——预测泰坦尼克号乘员的生存(机器学习全流程)
  17. 网络营销中的动态定价策略
  18. matlab 延迟算子,时间序列分析-----2---时间序列预处理
  19. 关于数据清洗的常见方式
  20. Spring事务实现的方式及底层原理

热门文章

  1. FFmpe写一个多线程播放器1 基础逻辑和队列定义
  2. 《Android 美颜类相机开发汇总》第五章 Android OpenGLES 美颜定制实现
  3. 怎么修改html超链接方向,如何修改HTML超链接样式?
  4. 分享118个HTML个性简实模板,总有一款适合您
  5. linux php pear 安装,全面解析ubuntu下安装php、pear
  6. GAN之生成对抗网络(Matlab)
  7. 计算机毕业设计Node.js+Vue建筑工程管理系统(程序+源码+LW+部署)
  8. 小学生基本的计算机操作知识试题,中小学电脑考试操作题.doc
  9. python 彩票包_python 彩票
  10. oracle resulttype,MyBatis中关于resultType和resultMap的区别介绍