ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

前端面试题1

2021-07-07 21:02:15  阅读:249  来源: 互联网

标签:面试题 浏览器 函数 DOM 对象 前端 元素 组件


css

css3新特性

1.过渡 transition2.动画 animation3.形状转换 transform4.阴影 box-shadow5.滤镜 Filter6.颜色 rgba7.栅格布局 gird8.弹性布局 flex

css中link与@import的区别

1、@import是 CSS 提供的语法规则,只有导入样式表的作用;link是HTML提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性等。2、加载页面时,link引入的CSS被同时加载,@import引入的CSS将在页面加载完毕后加载。3、link标签作为HTML元素,不存在兼容性问题,而@import是CSS2.1才有的语法,故老版本浏览器(IE5之前)不能识别。4、可以通过JS操作DOM,来插入link标签改变样式;由于DOM方法是基于文档的,无法使用@import方式插入样式。

伪类与伪元素区别

1)伪类(pseudo-classes)

  • 其核⼼就是⽤来选择DOM树之外的信息,不能够被普通选择器选择的⽂档之外的元素,⽤来添加⼀些选择器的特殊效果。

  • ⽐如:hover :active :visited :link :visited :first-child :focus :lang等

  • 由于状态的变化是⾮静态的,所以元素达到⼀个特定状态时,它可能得到⼀个伪类的样式;当状态改变时,它⼜会失去这个样式。

  • 由此可以看出,它的功能和class有些类似,但它是基于⽂档之外的抽象,所以叫 伪类。

2)伪元素(Pseudo-elements)

  • DOM树没有定义的虚拟元素

  • 核⼼就是需要创建通常不存在于⽂档中的元素,

  • ⽐如::before ::after 它选择的是元素指定内容,表示选择元素内容的之前内容或之后内容。

  • 伪元素控制的内容和元素是没有差别的,但是它本身只是基于元素的抽象,并不存在于⽂档中,所以称为伪元素。⽤于将特殊的效果添加到某些选择器

2)伪类与伪元素的区别

  • 表示⽅法

    • CSS2 中伪类、伪元素都是以单冒号:表示,

    • CSS2.1 后规定伪类⽤单冒号表示,伪元素⽤双冒号::表示,

    • 浏览器同样接受 CSS2 时代已经存在的伪元素(:before, :after, :first�line, :first-letter 等)的单冒号写法。

    • CSS2 之后所有新增的伪元素(如::selection),应该采⽤双冒号的写法。

    • CSS3中,伪类与伪元素在语法上也有所区别,伪元素修改为以::开头。浏览器对以:开头的伪元素也继续⽀持,但建议规范书写为::开头

  • 定义不同

    • 伪类即假的类,可以添加类来达到效果

    • 伪元素即假元素,需要通过添加元素才能达到效果

  • 总结:

    • 伪类和伪元素都是⽤来表示⽂档树以外的"元素"。

    • 伪类和伪元素分别⽤单冒号:和双冒号::来表示。

    • 伪类和伪元素的区别,关键点在于如果没有伪元素(或伪类),

    • 是否需要添加元素才能达到效果,如果是则是伪元素,反之则是伪类。

4)相同之处:

  • 伪类和伪元素都不出现在源⽂件和DOM树中。也就是说在html源⽂件中是看不到伪类和伪元素的。不同之处:

  • 伪类其实就是基于普通DOM元素⽽产⽣的不同状态,他是DOM元素的某⼀特征。

  • 伪元素能够创建在DOM树中不存在的抽象对象,⽽且这些抽象对象是能够访问到的。

让一个div水平垂直居中

  • 使用position + transform

  • 使用flex

  • 使用position

  • 使用伪类

    .parent{
        font-size: 0;
        text-align: center;
    }
    .parent::before {
        content: "";
        display: inline-block;
        width: 0;
        height: 100%;
        vertical-align: middle;
    }
    .child{
        display: inline-block;
        vertical-align: middle;
    }

link和@import有什么区别

(1)link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;

(2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;

(3)import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;

js

数组和对象的原生方法

  • Array

    Array.concat( ) 连接数组Array.join( ) 将数组元素连接起来以构建一个字符串Array.length 数组的大小Array.pop( ) 删除并返回数组的最后一个元素Array.push( ) 给数组添加元素Array.reverse( ) 颠倒数组中元素的顺序Array.shift( ) 将元素移出数组Array.slice( ) 返回数组的一部分Array.sort( ) 对数组元素进行排序Array.splice( ) 插入、删除或替换数组的元素Array.toLocaleString( ) 把数组转换成局部字符串Array.toString( ) 将数组转换成一个字符串Array.unshift( ) 在数组头部插入一个元素

  • Object

    Object.hasOwnProperty( ) 检查属性是否被继承Object.isPrototypeOf( ) 一个对象是否是另一个对象的原型Object.propertyIsEnumerable( ) 是否可以通过for/in循环看到属性Object.toLocaleString( ) 返回对象的本地字符串表示Object.toString( ) 定义一个对象的字符串表示Object.valueOf( ) 指定对象的原始值

内存泄漏

内存泄露

  • 指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内情人q存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费

  • 排查

    • 一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public static String str;

      二)是否App中使用了大量的递归或无限递归(递归中用到了大量的建新的对象)

      三)是否App中使用了大量循环或死循环(循环中用到了大量的新建的对象)

      四)检查App中是否使用了向数据库查询所有记录的方法。即一次性全部查询的方法,如果数据量超过10万多条了,就可能会造成内存溢出。所以在查询时应采用“分页查询”。

      五)检查是否有数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放。会大量存储在内存中。

      六)检查是否使用了“非字面量字符串进行+”的操作。因为String类的内容是不可变的,每次运行"+"就会产生新的对象,如果过多会造成新String对象过多,从而导致JVM没有及时回收而出现内存溢出。

内存溢出

  • 内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出

  • 引起内存溢出的原因

    1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

    2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

    3.代码中存在死循环或循环产生过多重复的对象实体;

    4.使用的第三方软件中的BUG;

    5.启动参数内存值设定的过小

写JavaScript的基本规范

1.不要在同一行声明多个变量。2.请使用 ===/!==来比较true/false或者数值3.使用对象字面量替代new Array这种形式4.不要使用全局函数。5.Switch语句必须带有default分支6.函数不应该有时候有返回值,有时候没有返回值。7.For循环必须使用大括号8.If语句必须使用大括号9.for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。

JS的数据类型

基本类型:Number、Boolean、String、null、undefined、symbol(ES6 新增的),BigInt(ES2020) 引用类型:Object,对象子类型(Array,Function)

浅拷贝和深拷贝的区别

  • 浅拷贝:一般指的是把对象的第一层拷贝到一个新对象上去

  • 深拷贝:一般需要借助递归实现,如果对象的值还是个对象,要进一步的深入拷贝,完全替换掉每一个复杂类型的引用。

浅拷贝:浅拷贝通过ES6新特性Object.assign()或者通过扩展运算法...来达到浅拷贝的目的,浅拷贝修改副本,不会影响原数据,但缺点是浅拷贝只能拷贝第一层的数据,且都是值类型数据,如果有引用型数据,修改副本会影响原数据。

深拷贝:通过利用JSON.parse(JSON.stringify())来实现深拷贝的目的,但利用JSON拷贝也是有缺点的,当要拷贝的数据中含有undefined/function/symbol类型是无法进行拷贝的,当然我们想项目开发中需要深拷贝的数据一般不会含有以上三种类型,如有需要可以自己在封装一个函数来实现。

事件冒泡和事件捕获

事件捕获(event capturing): 当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点到事件源(由外到内)进行事件传播。

事件冒泡(dubbed bubbling):事件冒泡刚好相反,事件源到根节点(由内到外)进行事件传播。

无论是事件捕获还是事件冒泡,它们都有一个共同的行为,就是事件传播。dom标准事件流的触发的先后顺序为:先捕获再冒泡。即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。

在我们平常用的addEventListener方法中,一般只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数,然而,addEventListener还可以传入第三个参数,第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。

判断数组的方法

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

面向对象

面向对象的三大特性:继承/多态/封装

  • 封装

    封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

  • 继承

    继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。

    要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。

  • 多态性

    多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

    实现多态,有两种方式,覆盖和重载。覆盖和重载的区别在于,覆盖在运行时决定,重载是在编译时决定。并且覆盖和重载的机制不同,例如在 Java 中,重载方法的签名必须不同于原先方法的,但对于覆盖签名必须相同。

作用链域

全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找,直至全局函数,这种组织形式就是作用域链。

原型,原型链,原型链继承

  • 原型

    每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

  • 什么是原型链?

    当对象查找一个属性的时候,如果没有在自身找到,那么就会查找自身的原型,如果原型还没有找到,那么会继续查找原型的原型,直到找到 Object.prototype 的原型时,此时原型为 null,查找停止。这种通过 通过原型链接的逐级向上的查找链被称为原型链

    原型链实际上在上面原型的问题中就有涉及到,在原型的继承中,我们继承来多个原型,这里再提一下实现完美继承的方案,通过借助寄生组合继承,PersonB.prototype = Object.create(PersonA.prototype)这是当我们实例化PersonB得到实例化对象,访问实例化对象的属性时会触发get方法,它会先在自身属性上查找,如果没有这个属性,就会去proto中查找,一层层向上直到查找到顶层对象Object,这个查找的过程就是原型链来。

  • 什么是原型继承

    一个对象可以使用另外一个对象的属性或者方法,就称之为继承。具体是通过将这个对象的原型设置为另外一个对象,这样根据原型链的规则,如果查找一个对象属性且在自身不存在时,就会查找另外一个对象,相当于一个对象可以使用另外一个对象的属性和方法了。

    每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。关系:instance.constructor.prototype = instance.proto

    特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。

    当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话, 就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。 function Func(){} Func.prototype.name = "Sean"; Func.prototype.getInfo = function() { return this.name; } var person = new Func();//现在可以参考var person = Object.create(oldObject); console.log(person.getInfo());//它拥有了Func的属性和方法 //"Sean" console.log(Func.prototype); // Func { name="Sean", getInfo=function()}

防抖节流

- 防抖
  - 原理:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
  - 适用场景:
    - 按钮提交场景:防止多次提交按钮,只执行最后提交的一次
    - 搜索框联想场景:防止联想发送请求,只发送最后一次输入
- 节流
  - 原理:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
  - 适用场景
    - 拖拽场景:固定时间内只执行一次,防止超高频次触发位置变动
    - 缩放场景:监控浏览器resize

重绘回流

  • Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流

    会导致回流的操作:

    • 页面首次渲染

    • 浏览器窗口大小发生改变

    • 元素尺寸或位置发生改变

    • 元素内容变化(文字数量或图片大小等等)

    • 元素字体大小变化

    • 添加或者删除可见的DOM元素

    • 激活CSS伪类(例如::hover

    • 查询某些属性或调用某些方法

  • 当页面中元素样式的改变并不影响它在文档流中的位置时(例如:colorbackground-colorvisibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。

  • 性能影响

    回流比重绘的代价要更高

  • 如何避免

    CSS

    • 避免使用table布局。

    • 尽可能在DOM树的最末端改变class

    • 避免设置多层内联样式。

    • 将动画效果应用到position属性为absolutefixed的元素上。

    • 避免使用CSS表达式(例如:calc())。

    JavaScript

    • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。

    • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。

    • 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。

    • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。

    • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

js事件循环机制

事件循环机制从整体上告诉了我们 JavaScript 代码的执行顺序Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。

先执行 Script 脚本,然后清空微任务队列,然后开始下一轮事件循环,继续先执行宏任务,再清空微任务队列,如此往复。

  • 宏任务:Script/setTimeout/setInterval/setImmediate/ I/O / UI Rendering

  • 微任务:process.nextTick()/Promise

上诉的 setTimeout 和 setInterval 等都是任务源,真正进入任务队列的是他们分发的任务。

js

JavaScript的任务分为两种同步异步,它们的处理方式也各自不同,同步任务是直接放在主线程上排队依次执行,异步任务会放在任务队列中,若有多个异步任务则需要在任务队列中排队等待,任务队列类似于缓冲区,任务下一步会被移到调用栈然后主线程执行调用栈的任务。

调用栈:调用栈是一个栈结构,函数调用会形成一个栈帧,帧中包含了当前执行函数的参数和局部变量等上下文信息,函数执行完后,它的执行上下文会从栈中弹出。

JavaScript是单线程的,单线程是指 js引擎中解析和执行js代码的线程只有一个(主线程),每次只能做一件事情,然而ajax请求中,主线程在等待响应的过程中回去做其他事情,浏览器先在事件表注册ajax的回调函数,响应回来后回调函数被添加到任务队列中等待执行,不会造成线程阻塞,所以说js处理ajax请求的方式是异步的。

宏任务微任务

  • 宏任务指执行栈中待执行的任务,setTimeout、setInterval、script,http回调都是宏任务。

  • 微任务指执行栈清空后立即执行的任务,Promise和 MutationObserver,nextTick都是微任务。

作用域,作用域链

  • ES5 中只存在两种作用域:全局作用域和函数作用域。在 JavaScript 中,我们将作用域定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套子作用域中根据标识符名称进行变量(变量名或者函数名)查找

  • 作用域链,当访问一个变量时,编译器在执行这段代码时,会首先从当前的作用域中查找是否有这个标识符,如果没有找到,就会去父作用域查找,如果父作用域还没找到继续向上查找,直到全局作用域为止,,而作用域链,就是有当前作用域与上层作用域的一系列变量对象组成,它保证了当前执行的作用域对符合访问权限的变量和函数的有序访问

闭包

  • 什么是闭包

    函数执行后返回结果是一个内部函数,并被外部变量所引用,如果内部函数持有被执行函数作用域的变量,即形成了闭包。

    可以在内部函数访问到外部函数作用域。使用闭包,一可以读取函数中的变量,二可以将函数中的变量存储在内存中,保护变量不被污染。而正因闭包会把函数中的变量值存储在内存中,会对内存有消耗,所以不能滥用闭包,否则会影响网页性能,造成内存泄漏。当不需要使用闭包时,要及时释放内存,可将内层函数对象的变量赋值为null。

  • 优点

    1. 可以从内部函数访问外部函数的作用域中的变量,且访问到的变量长期驻扎在内存中,可供之后使用

    2. 避免变量污染全局

    3. 把变量存到独立的作用域,作为私有成员存在

  • 缺点

    1. 对内存消耗有负面影响。因内部函数保存了对外部变量的引用,导致无法被垃圾回收,增大内存使用量,所以使用不当会导致内存泄漏

    2. 对处理速度具有负面影响。闭包的层级决定了引用的外部变量在查找时经过的作用域链长度

    3. 可能获取到意外的值(captured value)

  • 应用场景

    应用场景一: 典型应用是模块封装,在各模块规范出现之前,都是用这样的方式防止变量污染全局。

    应用场景二: 在循环中创建闭包,防止取到意外的值。

  • 如何产生闭包

    返回函数

    函数当做参数传递

Javascript如何实现继承

1、构造继承2、原型继承3、实例继承4、拷贝继承

原型prototype机制或apply和call方法去实现较简单,建议使用构造函数与原型混合方式。

function Parent(){ this.name = 'wang'; }

function Child(){
    this.age = 28;
}
Child.prototype = new Parent();//继承了Parent,通过原型
​
var demo = new Child();
alert(demo.age);
alert(demo.name);//得到被继承的属性

}

javascript创建对象的几种方式

javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON;但写法有很多种,也能混合使用。

1、对象字面量的方式

person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};

2、用function来模拟无参的构造函数

function Person(){}
var person=new Person();//定义一个function,如果使用new"实例化",该function可以看作是一个Class
person.name="Mark";
person.age="25";
person.work=function(){
alert(person.name+" hello...");
}
person.work();

3、用function来模拟参构造函数来实现(用this关键字定义构造的上下文属性)

function Pet(name,age,hobby){
   this.name=name;//this作用域:当前对象
   this.age=age;
   this.hobby=hobby;
   this.eat=function(){
      alert("我叫"+this.name+",我喜欢"+this.hobby+",是个程序员");
   }
}
var maidou =new Pet("麦兜",25,"coding");//实例化、创建对象
maidou.eat();//调用eat方法

4、用工厂方式来创建(内置对象)

 var wcDog =new Object();
 wcDog.name="旺财";
 wcDog.age=3;
 wcDog.work=function(){
   alert("我是"+wcDog.name+",汪汪汪......");
 }
 wcDog.work();

5、用原型方式来创建

function Dog(){
​
 }
 Dog.prototype.name="旺财";
 Dog.prototype.eat=function(){
 alert(this.name+"是个吃货");
 }
 var wangcai =new Dog();
 wangcai.eat();

6、用混合方式来创建

function Car(name,price){
  this.name=name;
  this.price=price; 
}
 Car.prototype.sell=function(){
   alert("我是"+this.name+",我现在卖"+this.price+"万元");
  }
var camry =new Car("凯美瑞",27);
camry.sell(); 

什么是虚拟dom,优势是什么,存储在哪

  • Virtual DOM 可以理解为一个简单的JS对象,并且最少包含标签名( tag)、属性(attrs)和子元素对象( children)三个属性。

  • 优势:

    1、具备跨平台的优势-由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等。
    ​
    2、提升渲染性能-Virtual DOM的优势不在于单次的操作,而是在大量、频繁的数据更新下,能够对视图进行合理、高效的更新。
    为了实现高效的DOM操作,一套高效的虚拟DOM diff算法显得很有必要。通过找出本次DOM需要更新的节点来更新,其他的不更新。
    3、是一个js对象,存储在内存中。

js脚本加载问题,async、defer问题

  • 如果依赖其他脚本和 DOM 结果,使用 defer

  • 如果与 DOM 和其他脚本依赖不强时,使用 async

浏览器内核的理解?

  • 主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。

渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。

JS引擎则:解析和执行javascript来实现网页的动态效果。

最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。

  • 常见的浏览器内核有哪些?

    Trident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML]Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等Presto内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;]Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]

ES6

this

this指向

bind,call,apply

call: Array.prototype.call(this, args1, args2])

apply: Array.prototype.apply(this, [args1, args2])

ES6 之前用来展开数组调用, foo.appy(null, []),ES6 之后使用 ... 操作符

  • New 绑定 > 显示绑定 > 隐式绑定 > 默认绑定

  • 如果需要使用 bind 的柯里化和 apply 的数组解构,绑定到 null,尽可能使用 Object.create(null) 创建一个 DMZ 对象

  • 四条规则:

    • 默认绑定,没有其他修饰(bind、apply、call),在非严格模式下定义指向全局对象,在严格模式下定义指向 undefined

    • 隐式绑定:调用位置是否有上下文对象,或者是否被某个对象拥有或者包含,那么隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象。而且,对象属性链只有上一层或者说最后一层在调用位置中起作用

    • 显示绑定:通过在函数上运行 call 和 apply ,来显示的绑定 this

    • New 绑定时,如果是 new 一个硬绑定函数,那么会用 new 新建的对象替换这个硬绑定 this,

  • 注意事项

    1. call和apply功能几乎一致,唯一的区别就是传参的方式!!2.call和apply的第一个参数如果为null或者undefined,那么this指向window3.call和apply的第一个参数如果为值类型的数据,那么会将这个值类型的数据,转换成其对应的引用类型的数据,然后再将this指向这个引用类型的数据4.call和apply立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用。5.当参数的个数确定的情况下可以使用call;当参数的个数不确定的情况下可以使用apply

Map和Set

WeakMap和Map之间的区别?

WeakMap只能以复杂数据类型作为key,并且key值是弱引用,对于垃圾回收更加友好

Set:

  • 成员唯一、无序且不重复。

  • [value, value],键值与键名是一致的(或者说只有键值,没有键名)。

  • 可以遍历,方法有:add、delete、has。

WeakSet:

  • 成员都是对象。

  • 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄漏。

  • 不能遍历,方法有add、delete、has。

Map:

  • 本质上是键值对的集合,类似集合。

  • 可以遍历,方法很多可以跟各种数据格式转换。

WeakMap:

  • 只接受对象作为键名(null除外),不接受其他类型的值作为键名。

  • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的。

  • 不能遍历,方法有get、set、has、delete。

symbol

SymbolES6 新推出的一种基本类型,它表示独一无二的值

Symbol有两个方法:

  • Symbol.for()

    • Symbol.for()定义的值会先检查给定的描述是否已经存在,如果不存在才会新建一个值,否则描述相同则他们就是同一个值

  • Symbol.keyFor()

    • Symbol.keyFor()是用来检测该字符串参数作为名称的 Symbol值是否已被登记,返回一个已登记的 Symbol 类型值的key

promise

  • 概念

    抽象表达
    Promise是 js 进行异步编辑的新的解决方案(旧的方式:纯回调的形式)
    具体表达
    1 从语法上来说Promise 是一个构造函数
    2 从功能上来说promise 对象用来封装一个异步操作并可以获取其结果
  • Promise优点

    • 统一异步 API

      • Promise 的一个重要优点是它将逐渐被用作浏览器的异步 API ,统一现在各种各样的 API ,以及不兼容的模式和手法。

    • Promise 与事件对比

      • 和事件相比较, Promise 更适合处理一次性的结果。在结果计算出来之前或之后注册回调函数都是可以的,都可以拿到正确的值。 Promise 的这个优点很自然。但是,不能使用 Promise 处理多次触发的事件。链式处理是 Promise 的又一优点,但是事件却不能这样链式处理。

    • Promise 与回调对比

      • 解决了回调地狱的问题,将异步操作以同步操作的流程表达出来。

    • Promise 带来的额外好处是包含了更好的错误处理方式(包含了异常处理),并且写起来很轻松(因为可以重用一些同步的工具,比如 Array.prototype.map() )。

    Promise缺点

    • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。

    • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

    • 当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

    • Promise 真正执行回调的时候,定义 Promise 那部分实际上已经走完了,所以 Promise 的报错堆栈上下文不太友好。

  • 状态改变

    pending 变为 resolved
     * pending rejected
     * 一个promise 对象只能改变一次
     * 无论变为成功还是失败,都会有一个结果数据
     * 成功的结果数据一般称为value 失败的结果数据一般称为reason
     * 为什么要使用promise
     *
     * 1 指定的回调函数的方式更加灵活
     * 旧:必须要启动异步任务前指定
     * promise 启动异步任务=>返回 promise对象=>给promise对象
     * 绑定回调函数(甚至可以在异步结束后指定/多个)
     *
     * 2 promise 支持链式调用。可以解决回调地狱问题
     * 什么是回调地狱 回调函数嵌套调用,外部回调函异步执行的结果是嵌套的
     * 回调函数执行条件
     * 回调地狱的缺点?不便于阅读/不便于异常处理
     * 解决方案 promise 链式调用
     * 错误回调:异常传透
     * then 是原型对象方法
     * new Promise 是实例对象方法
     * Promise.all promise函数对象方法

箭头函数与普通函数的区别

  • 箭头函数是匿名函数,不能作为构造函数,不能使用new

  • 箭头函数不绑定arguments,取而代之用rest参数...解决

  • 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值

  • 箭头函数通过call()或apply()方法调用一个函数时,只传入了一个参数,对 this 并没有影响

  • 箭头函数没有原型属性

普通函数通过 function 关键字定义, this 无法结合词法作用域使用,在运行时绑定,只取决于函数的调用方式,在哪里被调用,调用位置。(取决于调用者,和是否独立运行)

箭头函数使用被称为 “胖箭头” 的操作 => 定义,箭头函数不应用普通函数 this 绑定的四种规则,而是根据外层(函数或全局)的作用域来决定 this,且箭头函数的绑定无法被修改(new 也不行)。

  • 箭头函数常用于回调函数中,包括事件处理器或定时器

  • 箭头函数和 var self = this,都试图取代传统的 this 运行机制,将 this 的绑定拉回到词法作用域

  • 没有原型、没有 this、没有 super,没有 arguments,没有 new.target

  • 不能通过 new 关键字调用

    • 一个函数内部有两个方法:[[Call]] 和 [[Construct]],在通过 new 进行函数调用时,会执行 [[construct]] 方法,创建一个实例对象,然后再执行这个函数体,将函数的 this 绑定在这个实例对象上

    • 当直接调用时,执行 [[Call]] 方法,直接执行函数体

    • 箭头函数没有 [[Construct]] 方法,不能被用作构造函数调用,当使用 new 进行函数调用时会报错。

http

同步和异步的区别

同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,j进行下一步操作。

异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。

跨域

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

解决跨域

  • jsonp:只支持 GET,不支持 POST 请求,不安全 XSS

  • cors:需要后台配合进行相关的设置

  • postMessage:配合使用 iframe,需要兼容 IE6、7、8、9

  • document.domain:仅限于同一域名下的子域

  • websocket:需要后台配合修改协议,不兼容,需要使用 http://socket.io

  • proxy:使用代理去避开跨域请求,需要修改 nginx、apache 等的配置

同源策略

同源策略指的是:协议+域名+端口三者皆相同,可以视为在同一个域,否则为不同域。同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。

作用是一个用于隔离潜在恶意文件的重要安全机制。

所限制的跨域交互包括:

  • Cookie、LocalStorage、IndexdDB 等存储内容;

  • DOM 节点;

  • Ajax 请求。

Ajax 为什么不能跨域

Ajax 其实就是向服务器发送一个 GET 或 POST 请求,然后取得服务器响应结果,返回客户端。Ajax 跨域请求,在服务器端不会有任何问题,只是服务端响应数据返回给浏览器的时候,浏览器根据响应头的Access-Control-Allow-Origin字段的值来判断是否有权限获取数据。

因此,服务端如果没有设置跨域字段设置,跨域是没有权限访问,数据被浏览器给拦截了。

所以,要解决的问题是:如何从客户端拿到返回的数据

其实,在同源策略的基础上,选择性地为同源策略开放了一些后门。例如 img、script、style 等标签,都允许跨域引用资源。

JSONP 实现

只支持GET请求,不支持POST等其它请求,也不支持复杂请求,只支持简单请求。

JSONP 缺点

  • 只支持 GET 请求

  • 只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面之间如何进行 JavaScript 调用的问题

  • 调用失败的时候不会返回各种 HTTP 状态码。

  • 安全性,万一假如提供 JSONP 的服务存在页面注入漏洞,即它返回的 javascript 的内容被人控制的。

跨域资源共享 CORS

支持所有的请求,包含GET、POST、OPTOIN、PUT、DELETE等。既支持复杂请求,也支持简单请求。

JSONP和CORS跨域理解

JSONP与CORS的使用目的相同,并且都需要服务端和客户端同时支持,但CORS的功能更加强大。

SONP和CORS的优缺点

  1. JSONP的主要优势在于对浏览器的支持较好;虽然目前主流浏览器都支持CORS,但IE9及以下不支持CORS。

  2. JSONP只能用于获取资源(即只读,类似于GET请求);CORS支持所有类型的HTTP请求,功能完善。(这点JSONP被玩虐,但大部分情况下GET已经能满足需求了)

JSONP的错误处理机制并不完善,我们没办法进行错误处理;而CORS可以通过onerror事件监听错误,并且浏览器控制台会看到报错信息,利于排查。

  1. JSONP只会发一次请求;而对于复杂请求,CORS会发两次请求。

  2. 始终觉得安全性这个东西是相对的,没有绝对的安全,也做不到绝对的安全。毕竟JSONP并不是跨域规范,它存在很明显的安全问题:callback参数注入和资源访问授权设置。CORS好歹也算是个跨域规范,在资源访问授权方面进行了限制(Access-Control-Allow-Origin),而且标准浏览器都做了安全限制,比如拒绝手动设置origin字段,相对来说是安全了一点。但是回过头来看一下,就算是不安全的JSONP,我们依然可以在服务端端进行一些权限的限制,服务端和客户端也都依然可以做一些注入的安全处理,哪怕被攻克,它也只能读一些东西。就算是比较安全的CORS,同样可以在服务端设置出现漏洞或者不在浏览器的跨域限制环境下进行攻击,而且它不仅可以读,还可以写。

应用场景

如果需要兼容IE低版本浏览器,无疑,JSONP。如果需要对服务端资源进行操作,无疑,CORS。

Http 缓存策略

浏览器缓存(Brower Caching)是浏览器对之前请求过的文件进行缓存,以便下一次访问时重复使用,节省带宽,提高访问速度,降低服务器压力

http缓存机制主要在http响应头中设定,响应头中相关字段为Expires、Cache-Control、Last-Modified、Etag。

ajax实现原理及方法使用

原生ajax的请求步骤

//创建 XMLHttpRequest 对象
var ajax = new XMLHttpRequest();
//规定请求的类型、URL 以及是否异步处理请求。
ajax.open('GET',url,true);
//发送信息至服务器时内容编码类型
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
//发送请求
ajax.send(null);  
//接受服务器响应数据
ajax.onreadystatechange = function () {
    if (obj.readyState == 4 && (obj.status == 200 || obj.status == 304)) { 
    }
};

如何防范CSRF攻击,XSS攻击

XSS攻击的防范

1、HttpOnly 防止劫取 Cookie
2、输入检查-不要相信用户的所有输入
3、输出检查-存的时候转义或者编码
复制代码

CSRF攻击的防范

1、验证码
2、Referer Check
3、添加token验证

一个页面从输入 URL 到页面加载显示完成的全部过程

1、浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;2、调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;3、通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;4、进行HTTP协议会话,客户端发送报头(请求报头);5、进入到web服务器上的 Web Server,如 Apache、Tomcat、Node.JS 等服务器;6、进入部署好的后端应用,如 PHP、Java、JavaScript、Python 等,找到对应的请求处理;7、处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回304;8、浏览器开始下载html文档(响应报头,状态码200),同时使用缓存;9、文档树建立,根据标记请求所需指定MIME类型的文件(比如css、js),同时设置了cookie;10、页面开始渲染DOM,JS根据DOM API操作DOM,执行事件绑定等,页面显示完成。

常用的http状态码

基本概念:

HTTP,全称为 HyperText Transfer Protocol,即为超文本传输协议。是互联网应用最为广泛的一种网络协议所有的 www 文件都必须遵守这个标准。

http特性:

HTTP 是无连接无状态的HTTP 一般构建于 TCP/IP 协议之上,默认端口号是 80HTTP 可以分为两个部分,即请求和响应。

http请求:

HTTP 定义了在与服务器交互的不同方式,最常用的方法有 4 种分别是 GET,POST,PUT, DELETE。URL 全称为资源描述符,可以这么认为:一个 URL 地址对应着一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE 就对应着对这个资源的查询,修改,增添,删除4个操作。

HTTP 请求由 3 个部分构成,分别是:状态行,请求头(Request Header),请求正文。

HTTP 响应由 3 个部分构成,分别是:状态行,响应头(Response Header),响应正文。

HTTP 响应中包含一个状态码,用来表示服务器对客户端响应的结果。状态码一般由3位构成:

1xx : 表示请求已经接受了,继续处理。2xx : 表示请求已经处理掉了。3xx : 重定向。4xx : 一般表示客户端有错误,请求无法实现。5xx : 一般为服务器端的错误。

比如常见的状态码:

200 OK 客户端请求成功。301 Moved Permanently 请求永久重定向。302 Moved Temporarily 请求临时重定向。304 Not Modified 文件未修改,可以直接使用缓存的文件。400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。401 Unauthorized 请求未经授权,无法访问。403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因。404 Not Found 请求的资源不存在,比如输入了错误的URL。500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。

大概还有一些关于http请求和响应头信息的介绍。

http的基本结构

应用层:向用户提供服务,处理特定的细节,比如:文件传输,DNS服务,HTTP等

传输层:为两台主机上的应用程序提供端到端的通信,主要分为TCP和UDP两种通讯方式

  • tcp是一种可靠的传输协议,需要经过三次握手确保双方可以正常通讯,此外还有切包,超时重传、发送和接收端到端的确认分组等机制。

  • udp是不可靠的传输协议,所以需要应用层来保证可靠性

网络层:在众多的选项内选择一条传输路线。依赖mac地址

链路层:处理连接网络的硬件部分

http方法

  • get:获取

  • post:传给服务器

  • put:传输文件,http1.1不带验证机制

  • head:和get类似,只是不返回主体部分,用于确认uri的有效性

  • delete:用于删除文件,http1.1不带验证机制

  • options:询问支持的方法

cookies,sessionStorage 和 localStorage 的区别

cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

存储大小: cookie数据大小不能超过4k。 sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

有期时间: localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; sessionStorage 数据在当前浏览器窗口关闭后自动删除。 cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

https

HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

HTTPS主要作用是:

(1)对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全;

(2)对网站服务器进行真实身份认证。

HTTP 与 HTTPS 的区别

HTTPS比HTTP更加安全,对搜索引擎更友好,利于SEO,谷歌、百度优先索引HTTPS网页;

HTTPS需要用到SSL证书,而HTTP不用;

HTTPS标准端口443,HTTP标准端口80;

HTTPS基于传输层,HTTP基于应用层;

HTTPS在浏览器显示绿色安全锁,HTTP没有显示;

vue

基础

SPA 单页面的理解,优缺点

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。

优点:

  • 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;

  • 基于上面一点,SPA 相对对服务器压力小;

  • 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;

缺点:

  • 初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;

  • 前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;

  • SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

vue 的单向数据流

父级 prop 的更新会向下流动到子组件中,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值

computed 和 watch 的区别和运用的场景

computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;

watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;

运用场景:

  • 当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;

  • 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

vue 生命周期

(1)生命周期是什么?

Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

(2)各个生命周期的作用

生命周期描述
beforeCreate组件实例被创建之初,组件的属性生效之前
created组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el 还不可用
beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用
mountedel 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子
beforeUpdate组件数据更新之前调用,发生在虚拟 DOM 打补丁之前
update组件数据更新之后
activitedkeep-alive 专属,组件被激活时调用
deactivatedkeep-alive 专属,组件被销毁时调用
beforeDestory组件销毁前调用
destoryed组件销毁后调用

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

vue中组件是用来复用的,为了防止data复用,将其定义为函数。

我们将组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,拥有自己的作用域,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。

当我们组件的date单纯的写成对象形式,这些实例用的是同一个构造函数,由于JavaScript的特性所导致,所有的组件实例共用了一个data,就会造成一个变了全都会变的结果

vue中key

使用 key 来给每个节点做一个唯一标识, Diff 算法就可以正确的识别此节点。作用主要是为了高效的更新虚拟 DOM。

v-model 的原理

v-model 本质上是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素使用 value 属性和 input 事件;

  • checkbox 和 radio 使用 checked 属性和 change 事件;

  • select 字段将 value 作为 prop 并将 change 作为事件。

vue双向绑定的原理

双向数据绑定是基于Object.defineProperty()重新定义get和set方法实现的。修改触发set方法赋值,获取触发get方法取值,并通过数据劫持发布信息。

v-show 与 v-if 有什么区别

v-if真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。

所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。

vue常用的修饰符

  • .stop:等同于 JavaScript 中的 event.stopPropagation() ,防止事件冒泡;

  • .prevent :等同于 JavaScript 中的 event.preventDefault() ,防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播);

  • .capture :与事件冒泡的方向相反,事件捕获由外到内;

  • .self :只会触发自己范围内的事件,不包含子元素;

  • .once :只会触发一次。

高级

params和query的区别

用法:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是 this.$route.query.namethis.$route.params.name 。url地址显示:query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示

注意点:query刷新不会丢失query里面的数据 params刷新 会 丢失 params里面的数据。

组件router

$route$router 的区别

$router 是VueRouter的实例,在script标签中想要导航到不同的URL,使用 $router.push 方法。返回上一个历史history用 $router.to(-1)

$route 为当前router跳转对象。里面可以获取当前路由的name,path,query,parmas等。

Vue通信

1.props和$emit2.中央事件总线 EventBus(基本不用)3.vuex(官方推荐状态管理器)4.和​children

Vue路由守卫有哪些,怎么设置,使用场景

常用的两个路由守卫:router.beforeEach 和 router.afterEach

每个守卫方法接收三个参数:

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。

在项目中,一般在beforeEach这个钩子函数中进行路由跳转的一些信息判断。判断是否登录,是否拿到对应的路由权限等等。

组件中的name

  1. 项目使用 keep-alive 时,可搭配组件 name 进行缓存过滤

  2. DOM 做递归组件时需要调用自身 name

  3. vue-devtools 调试工具里显示的组见名称是由vue中组件name决定的

vue-router 路由模式

abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式.

hash模式: 即地址栏 URL 中的 # 符号;

history模式: window.history对象打印出来可以看到里边提供的方法和记录长度。利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)。

完整的导航守卫流程

导航被触发。

在失活的组件里调用离开守卫beforeRouteLeave(to,from,next)

调用全局的beforeEach( (to,from,next) =>{} )守卫。

在重用的组件里调用 beforeRouteUpdate(to,from,next) 守卫。

在路由配置里调用beforeEnter(to,from,next)路由独享的守卫。

解析异步路由组件。

在被激活的组件里调用beforeRouteEnter(to,from,next)

在所有组件内守卫和异步路由组件被解析之后调用全局的beforeResolve( (to,from,next) =>{} )解析守卫。

导航被确认。

调用全局的afterEach( (to,from) =>{} )钩子。

触发 DOM 更新。

用创建好的实例调用beforeRouteEnter守卫中传给 next 的回调函数

导航守卫的三个参数的含义

to:即将要进入的目标 路由对象。

from:当前导航正要离开的路由对象。

  • next():进入下一个路由。

  • next(false):中断当前的导航。

  • next('/')next({ path: '/' }) : 跳转到其他路由,当前导航被中断,进行新的一个导航。

vuex

vuex是一个专为vue.js应用程序开发的状态管理器,它采用集中式存储管理应用的所有组件的状态,并且以相应的规则保证状态以一种可以预测的方式发生变化。

(1)Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

(2)改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

state: vuex使用单一状态树,用一个对象就包含来全部的应用层级状态

mutation: 更改vuex中state的状态的唯一方法就是提交mutation

action: action提交的是mutation,而不是直接变更状态,action可以包含任意异步操作

getter: 相当于vue中的computed计算属性

keep-alive

  1. keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染

  2. 一般结合路由和动态组件一起使用,用于缓存组件;

  3. 提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高;

  4. 对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。

vue中$nextTick作用

处理数据动态变化后,dom还未及时更新的问题。$nextTick就可以获取到数据更新后最新的dom变化

vue项目优化的手段有哪些

前端方面:1、路由懒加载2、图片,资源放cdn3、页面图片较多进行懒加载4、骨架屏方案5、采用服务端渲染---nuxt.js服务器端:开启gzip

Vue SSR

Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。

即:SSR大致的意思就是vue在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。

其他

前端工程化、模块化、组件化

前端工程化

1、将前端项目当成一项系统工程进行分析、组织和构建从而达到项目结构清晰、分工明确、团队配合默契、开发效率提高的目的
2、工程化思维就是“结构、样式和动作分离”。如目录分为assets,components,router,util

前端模块化

1、可以简单的认为模块化和组件化是工程化的表现形式
2、JS模块化方案很多有AMD/CommonJS/UMD/ES6 Module等,CSS模块化开发大多是在less、sass、stylus

前端组件化

1、组件化将页面视为一个容器,页面上各个独立部分例如:头部、导航、焦点图、侧边栏、底部等视为独立组件,不同的页面根据内容的需要,去盛放相关组件即可组成完整的页面。
2、模块化和组件化一个最直接的好处就是复用

vue,jq,react,angular区别,各自优势

jq

1、需要频繁操作dom
2、容易引起重绘和回流,影响页面性能
复制代码

vue

1、mvvm模式,采用虚拟dom不需要频繁操作dom,通过双向绑定,用数据驱动页面变化,页面变化对应数据也发生变化,只需要关注数据层的业务逻辑,而无需关注视图层的更新。可以尽量减少无用的更新操作,提高dom渲染效率。
2、组件化开发,页面由若干个组建组成,可复用性高。
3、社区环境好,各类资源文档十分齐全。
4、通过Object.defineProperty() 方法,监控对数据的操作,从而可以自动触发数据同步。
复制代码

react

1、虚拟dom。
2、一切都是组件,组件实例之间可以嵌套。
3、使用独特的jsx语法。
复制代码

angular

1、AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观。
2、在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢。

webpack

1、Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。2、Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。3、Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。4、Loader:模块转换器,用于把模块原内容按照需求转换成新内容。5、Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。6、Output:打包后文件输出的位置

vue和jQuery的区别

jQuery是使用选择器( $ )选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:$("lable").val(); ,它还是依赖DOM元素的值。Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM。

项目

原来公司工作流程是怎么样的,如何与其他人协作的?如何夸部门合作的?

你遇到过比较难的技术问题是?你是如何解决的?

设计模式 知道什么是singleton, factory, strategy, decrator么?

常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?

页面重构怎么操作?

网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。

对于传统的网站来说重构通常是:

表格(table)布局改为DIV+CSS使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的)对于移动平台的优化针对于SEO进行优化深层次的网站重构应该考虑的方面

减少代码间的耦合让代码保持弹性严格按规范编写代码设计可扩展的API代替旧有的框架、语言(如VB)增强用户体验通常来说对于速度的优化也包含在重构中

压缩JS、CSS、image等前端资源(通常是由服务器来解决)程序的性能优化(如数据读写)采用CDN来加速资源加载对于JS DOM的优化HTTP服务器的文件缓存

你有什么想问我的

公司常用的技术栈是什么?

你们如何测试代码?

你们如何解决线上故障?

你们如何准备故障恢复?是否有完善的发布机制?

公司是否有技术分享交流活动?有的话,多久一次呢?

一次迭代的流程是怎么样的?从 PRD 评审开始到发布这一整个流程。

公司技术团队的架构和人员组成?

有公司级别的学习资源吗?比如电子书订阅或者在线课程?

你们认为和竞品相比有什么优势?

标签:面试题,浏览器,函数,DOM,对象,前端,元素,组件
来源: https://blog.csdn.net/weixin_53170812/article/details/118557237

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有