面试整理

750 阅读19分钟

display:node 和 visibilty:hidden 区别:

  1. display:none是彻底消失,不在文档流中占位,浏览器也不会解析该元素;visibility:hidden是视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;

  2. 使用visibility:hidden比display:none性能上要好,display:none切换显示时visibility,页面产生回流(当页面中的一部分元素需要改变规模尺寸、布局、显示隐藏等,页面重新构建,此时就是回流。所有页面第一次加载时需要产生一次回流),而visibility切换是否显示时则不会引起回流。

1.字符串反转

// 第一种方法
function strReverse(str = '') {
    this.strString = '';
    this.strArr = [];
    str.split(' ').forEach(item => {
        this.strArr.unshift(strString);
    })
    this.newStr = this.strArr.join(' ');
    console.log(this.newStr);
}

// 第二种方法
String.prototype.myReverse = function () {
    var newStr = '';
    for (var i = this.length; i > 0; i--) {
        newStr += this[i-1];
    }

    return newStr;
}

2.去除首尾空格

String.prototype.myTrim = function () {
    return this.replace(/^(\s|\u00A0)+/, '').replace(/(\s|\u00A0)+$/, '');
}

2.js实现1~10000之间的对称数,例如:(121,1331)

function getSymmetryNum(start, end) {
    this.ary = [];
    for(let i = start; i < end; i++) {
        if(i.toString() === i.toString().split('').reverse().join('') && i.toString().length > 1) {
            this.ary.push(i.toString());
        }
    }
    return this.ary.join('\n');
}

console.log(getSymmetryNum(1, 10000));

js算法排序

冒泡排序

  • 1.思想:当前项和后一项进行比较 如果当前项大于后一项则 交换位置
function bubbleSort(arr) {
    for(var i = 0; i<arr.length-1; i++) {
        for(var j = 0; j < arr.length-1-i; j++) {
            var num = arr[j];
            if (arr[j] > arr[j + 1]) {
                arr[j] = arr[j + 1];
                arr[j + 1] = num;
            }

        }
    }
    return arr;
}

let arr = [12,25,14,32,1,5];
console.log(bubbleSort(arr));
  • 请写一个函数,能够自动按照顺序执行数组中的每一个函数,必须一次打印1,2,3
// 现有数组
    var arr = [function (callback) {
        setTimeout(function () {
            alert(1);
            callback();
        }, 1000)
    }, function (callback) {
        setTimeout(function () {
            alert(2);
            callback();
        }, 500)
    }, function (callback) {
        setTimeout(function () {
            alert(3);
            callback();
        }, 1)
    }];
    // 请写一个函数,能够自动按照顺序执行数组中的每一个函数,必须一次打印1,2,3
    //创建一个迭代器,按顺序执行多个异步函数 
    function MyIteration(arr) {
        var that = this;
        var num = 0;
        var len = arr.length;
        var fn = arr[num];
        fn.call(that, next); 
        //上一步执行的结果
        function next() {
            num++;
            if (num < len) {
                var fn = arr[num]; 
                fn.call(that, next);
            }
        }
    }
    MyIteration(arr);

跨域

1. 同源策略

  • 什么是同源策略
  • 同源策略(Same-origin Policy):为了保护浏览器的信息安全,浏览器采用同源策略,保证当前源中的资源只能在当前源中使用;其他源如果需要使用当前资源,需要特殊技术,这种A源访问B源的资源的通信称为跨域。
  • 示例:
let xhr = new XMLHttpRequset();
xhr.open('GET','https//www.baidu.com', true);
xhr.onreadystatechange = function() {
    if(this.readystate === 4 && /^2\d{2}$/).test(this.status) {
        console.log('xxx');
    }
    
}

xhr.send();
  • 以上请求会报错:
Access to XMLHttpRequest at 'https://www.baidu.com/' from origin 'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
  • 当出现以上错误时说明你正在进行一个跨域的操作

同源策略的要求

  • 同源策略要求通信的两个源的协议、域名、端口号都要相同,如果三者中任意一个不同就是不满足同源策略;不满足同源策略的通信就是跨域。

常用的跨域解决方案

  • 1.jsonp
  • 2.服务器转发,因为同源策略只在客户端存在,在服务端是不存在的;所以可以用服务端转发请求
    1. nginx转发,nginx是服务器应用程序,他可以接受客户端的请求,然后根据规则可以配置自动转发
  • 4.CORS(Cross-Origin-Resource-Sharing):需要目标域设置Acess-Control-Allow-Origin头信息

JSONP原理:

  • jsonp是一种常用的解决跨域的方式;
  • 利用了script标签的src属性是不受同源策略约束的,可以访问不同域服务器或者端口号下的数据

用法

    1. 提前声明一个叫做fn的函数,给fn设置一个形参
    1. 在页面给script的src的指向的路径拼接一个callback属性,callback='fn';当浏览器解析这个script标签时h会向src指向的路径发送http请求
    1. 服务器收到这个请求后,会返回一个fn(这里面是服务器返回的数据)
    1. fn(xxx) 这个是让fn执行,小括号里面就是服务器发送给我们的数据

实例:

  • js代码
function fn(data) {
    console.log(data);
}
  • html代码
<script src='http://matchweb.sports.qq.com/kbs/calendar?columnId=100000&callback=fn"'></script>

css 与css3的区别

  • 什么是CSS?
  • CSS 是层叠样式表 ( Cascading Style Sheets ) 的简称。
  • CSS 是一种标记语言,属于浏览器解释型语言,可以直接由浏览器执行,不需要编译。
  • CSS 是用来表现HTML或XML的标记语言。
  • CSS 是由W3C的CSS工作组发布推荐和维护的.
  • CSS 是编程入门人员的必修课,运用CSS样式可以让页面变得美观。
  • CSS语法由三部分构成:选择器、属性和值: selector {property: value}
  • CSS3 是最新的 CSS 标准。
  • css3比css多了一些样式设置而已。 css3是向前兼容的,也就是说,css中有效的code在css3也有效。
  • 一个css与css3都有效的code,如果浏览器不支持css3,那么只会以css的样式显示。最常见的就是圆弧角。
  • 一个只在css3中有效的code,如果浏览器不支持css3,那么其显示效果就不会出现。
  • css3和css,在编写code的时候,除了对一些css3中新出现的属性设置,其它完全一样。
  • CSS3新增属性
  • box-shadow(阴影效果)
  • border-colors(为边框设置多种颜色)
  • boder-image(图片边框)
  • text-shadow(文本阴影)
  • text-overflow(文本截断)
  • border-radius(圆角边框)
  • opacity(不透明度)
  • box-sizing(控制盒模型的组成模式):指定两个boxes接壤
  • resize(元素缩放):指定一个div元素,允许用户调整大小
  • outline(外边框)
  • background-origin(指定背景图片从哪里开始显示)
  • background-clip(指定背景图片从什么位置开始裁切)
  • background(为一个元素指定多个背景)

vue实例 的生命周期

你是怎么理解生命周期钩子函数的?

  • vue的生命周期钩子函数 是在vue实例过程中执行的一些函数,分别有 beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed。这八个函数是vue规定的函数名 beforeCreate 是在vue初始化 内部事件和生命周期之后执行的,里边只有一些vue的内部属性和方法 我们一般不用,在 vue把 data、methods、computed中的属性挂载到当前实例之后,会触发 created这个钩子函数,我们一般在这个钩子函数中发送一些ajax请求;因为ajax请求发出越早越好;而在这个钩子函数中 我们可以调用到对应的属性和方法;在该函数之后,会查看是否有el、template这个两个属性;然后执行beforeMount钩子函数;在这个函数中我们可以调到原始的DOM元素;再之后,vue根据数据渲染虚拟DOM;并把渲染好的虚拟DOM展示到页面上,再执行mounted钩子函数;在这个钩子函数中我们可以获取已经渲染好的DOM元素;当在页面上用到的数据更新时会触发update对应的两个钩子函数;注意不能在这两个函数中书写可以触发视图更新的操作。当当前实例被销毁时会触发destroy对应的两个钩子函数;我们在这里可以做一些清除定时器的操作。

  • 什么是生命周期

  • vue的实例具有生命周期,vue的实例在生成的时候,会经历一系列的初始化的过程;数据的监听,编译模板,实例挂载DOM元素,或者数据更新导致DOM更新,在执行的过程中,会运行一些叫做生命周期的钩子函数,在Vue实例生命周期中特定的时间点执行的函数称为生命周期的钩子函数;

  • 如果我们需要在某个生命周期处理一些事情,我们可以把这些事情写在钩子函数中;等到vue的实例生命周期到这个阶段就会执行这个钩子,而我们要做的事情也就得以处理了;

  • 注意:生命周期的钩子函数不能人为的控制其执行的顺序;

1.2 常用的生命周期

  • beforeCreate 在实例初始化之后,数据观测 (data observer) 和watch配置之前被调用。
  • created 在实例创建完成后被立即调用。在这一步,实例已完成数据观测、属性和方法的运算、watch/event 事件回调;但是在现阶段还没有开始挂载,即还没挂载到根DOM元素上,所以 this.$el 属性不可见
  • beforeMount 在挂载开始之前被调用,创建虚拟DOM(Virtual-DOM);虚拟DOM不是真实的DOM元素,而是js对象,其中包含了渲染成DOM元素信息;
  • mounted 把Vue的虚拟DOM挂载到真实的DOM上;如果要在Vue中获取DOM元素对象,一般在这个钩子中获取;项目中的ajax请求一般会在这里或者created里发送;
  • beforeUpdate 只有当数据发生变化时,才会触发这个函数;
  • updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用updated。
  • beforeDestroy 在vue的实例被销毁之前调用,如果页面中有定时器,我们会在这个钩子中清除定时器;
  • destroyed Vue 实例销毁后调用,实例中的属性也不再是响应式的,watch被移除
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <div @click="fn">{{msg}}</div>
</div>

<script src="vue.js"></script>
<script>
  // 生命周期:
  // vue的实例具有生命周期,vue的实例在生成的时候,会经历一系列的初始化的过程;数据的监听,编译模板,实例挂载DOM元素,或者数据更新导致DOM更新,在执行的过程中,会运行一些叫做生命周期的钩子函数,在Vue实例生命周期中特定的时间点执行的函数称为生命周期的钩子函数;

  // 如果我们需要在某个生命周期处理一些事情,我们可以把这些事情写在钩子函数中;等到vue的实例生命周期到这个阶段就会执行这个钩子,而我们要做的事情也就得以处理了
  // 生命周期的钩子函数不能人为的控制其执行的顺序;

  let vm = new Vue({
    data: {
      msg: 'hello'
    },
    methods: {
      fn() {console.log(11111)}
    },
    beforeCreate() {
      // 在实例初始化之后,数据观测 (data observer) 和watch配置之前被调用。
      console.log(1);
      console.log(this.msg);
      console.log(this.$el); // this.$el 是根DOM元素
    },
    created() {
      // 在实例创建完成后被立即调用。在这一步,实例已完成数据观测、属性和方法的运算、watch/event 事件回调
      // 但是在现阶段还没有开始挂载,即还没挂载到根DOM元素上,所以 this.$el 属性不可见
      console.log(2);
      console.log(this.msg);
      console.log(this.$el);
    },
    beforeMount() {
      // 在挂载开始之前被调用,创建虚拟DOM(Virtual-DOM);虚拟DOM不是真实的DOM元素,而是js对象,其中包含了渲染成DOM元素信息;
      console.log(3);
      console.log(this.msg);
      console.log(this.$el);
    },
    mounted() {
      // 把Vue的虚拟DOM挂载到真实的DOM上;
      // 如果要在Vue中获取DOM元素对象,一般在这个钩子中获取
      // 项目中的ajax请求一般会在这里或者created里发送;
      console.log(4);
      console.log(this.msg);
      console.log(this.$el);
    },
    // 只有当数据发生变化时,才会触发这个函数;
    beforeUpdate() {
      console.log(5)
    },
    updated() {
      // 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
      console.log(6);
    },
    beforeDestroy() {
      // 在vue的实例被销毁之前调用,如果页面中有定时器,我们会在这个钩子中清除定时器;
      console.log(7);
    },
    destroyed() {
      // Vue 实例销毁后调用,实例中的属性也不再是响应式的,watch被移除
      console.log(8);
    }
  });

  vm.$set(vm, 'msg', 'hello world'); // 因为vue的数据都是响应式的,只有修改数据才会触发beforeUpdate和updated钩子


  vm.$mount('#app'); // 当创建实例时不传递el属性,可以手动挂载到DOM节点;

  vm.$destroy(); // 手动销毁实例;

</script>
</body>
</html>

说一下性能优化方面?

  1. 减少http请求次数
  2. 雪碧图
  3. 延迟加载
  4. ajax分页
  5. 文件压缩
  6. 减少css图片请求
  7. 将外部脚本置底(将脚本内容在页面信息内容加载后再加载)
  8. 预先解析DNS
  9. css利用继承
  10. 可以用三目运算符替换条件分支,可以提高效率

get和post的区别?

get

  1. get请求如果需要传递参数,那么会默认将参数拼接到url的后面;然后发送给服务器
  2. get请求传递参数大小是有限制的;是浏览器的地址栏有大小限制;IE不超过2K;谷歌不超过8K;超过会自动截掉
  3. get安全性较低
  4. get 一般会走缓存,为了防止走缓存,给url后面每次拼的参数不同
  5. 放在?后面,一般用个时间戳或随机数

post

  1. post传递参数,需要把参数放进请求体中,发送给服务器
  2. post请求参数放进了请求体中,对大小没有要求
  3. 安全性比较高
  4. post请求不会走缓存

同步和异步的区别?

  1. 同步:js本身是一个阻塞的语言,需要逐行读取代码,如果某一个程序出错,即不再执行后面所有代码
  2. 异步:不管程序相应结果都会执行所有代码

ajax的优缺点?

  • ajax优点:
  1. 页面无刷新,实现按需加载,用户体验非常好
  2. 不打断用户的操作,实现异步请求,具备更加迅速的响应能力
  3. 可以将服务端的一些行为转嫁到客户端,减轻服务器压力和宽带
  4. 不需要借助插件和小程序
  • ajax缺点:
  1. 破环了后退前进功能
  2. 安全问题
  3. 对搜索引擎支持较弱
  4. 破坏程序异常机制

new操作干了什么?

  1. 创建空的对象
  2. 改变当前作用域下的this
  3. 返回对象

typeof返回那些数据类型?

  1. number
  2. string 3.boolean
  3. undefined
  4. object
  5. function

Array相关的属性和方法

  1. length:length是Array的实例属性

  2. prototype:前面说到Array在代码中是一个函数,也就是数组对象的构造函数,所以它有自己的原型,也就是prototype

  3. Array.from(),从一个类似数组或可迭代对象中创建一个新的数组实例

  4. Array.isArray(),用于确定传递的值是否是一个Array

  5. Array.of(),创建一个具有可变数量参数的新数组实例,而不考虑参数的数量和类型

  6. push(),将一个或多个元素添加到数组的末尾,并返回该数组的新长度

  7. unshift(),将一个或多个元素添加到数组的开头,并返回该数组的新长度

  8. shift(),从数组中删除第一个元素,并返回该元素的值

  9. pop(),删除数组中的最后一个元素,并返回该元素的值

  10. slice(),返回一个新的数组对象,这个对象是一个由begin和end(不包含end)决定的的原数组的浅拷贝。原始数组不会被改变

  11. splice(),方法通过删除现有元素和/或添加新元素来修改数组,并以数组返回原数组中被修改的内容

  12. concat(),方法用于合并两个或多个数组。此方法不会改变现有数组,而是返回一个新数组

  13. copyWithin(),方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小

  14. fill(),方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引

  15. reverse(),将数组中的元素位置颠倒。第一个数组元素成为最后一个数组元素,最后一个数组元素成为第一个

  16. sort

  17. map

  18. foreach

  19. indexOf

  20. lastindexOf

  21. join

  22. 数组的那些方法使原有数组发生改变

5、pop()? 删除数组最后一个元素,如果数组为空,则不改变数组,返回undefined,改变原数组,返回被删除的元素

6、push()? ?向数组末尾添加一个或多个元素,改变原数组,返回新数组的长度

7、reverse()? ?颠倒数组中元素的顺序,改变原数组,返回该数组

8、shift()? ?把数组的第一个元素删除,若空数组,不进行任何操作,返回undefined,改变原数组,返回第一个元素的值

9、sort()? ?对数组元素进行排序,改变原数组,返回该数组

10、splice()? ?从数组中添加/删除项目,改变原数组,返回被删除的元素

11、unshift()? ?向数组的开头添加一个或多个元素,改变原数组,返回新数组的长度

  1. jquery中的ajax方法常见参数

  2. url:

2.type:

3.timeout:

4.async:

5.data:

6.success

  1. cache:

10.学习方法

看文档/掘金/博客园/Pdf电子书

调试问题方法

先大概理解一下,快速梳理一次

分而治之来调试问题

每次记录修改的地方

重现失败

主观臆断的人,总是为了套用理论而扭曲事实,而不是用理论来解释事实

  1. vue双向数据绑定原理

    • vue利用的Object.defineProperty这个方法遍历data中所有的属性,给每个属性增加了setter和getter方法,当数据发生改变时会触发setter方法;当获取数据时会触发getter方法。Object.defineProperty 在 IE8 及以下不兼容,所以 vue 只能在 IE9 以上使用;
  2. v-if和v-show的区别

    v-if操作的是Dom,根据条件判断显示,如果条件不通过,直接删除了这个元素 v-show操作的是元素中的display:block,不删除元素,原有元素还在

  3. vue中computed和watch的区别

    computed里的函数中不支持异步, computed会走缓存 实现多对一 computed(计算属性)是多个属性改变影响一个属性改变 watch里的函数中支持异步 watch不会走缓存 实现了一对多 watch是监听一个属性,它改变了,影响多个属性改变

  4. webpack中常用的loader有哪些?

    1.style-loader 2.css-loader 3.less-loader 4.file-loader 5.url-loader 6.vue-loader

  5. vue和react区别

    1. vue轻量,构建页面方便
    2. react更适合大型项目
    3. vue双向数据流
    4. react单向数据流 4.react利用虚拟Dom,减少与Dom的交互

16.vuex中getter和setter的区别

17.setTimeout(function() {

console.log(1)

}, 0);

new Promise(function executor(resolve)

{

console.log(2);

for( var i=0 ; i<10000 ; i++ ) {

i == 9999 && resolve();

}

console.log(3);

}).then(function() {

console.log(4); });

console.log(5);

18.vue路由传参三种方式

  1. :id

  2. query

  3. params

  4. 说一下闭包

闭包就是能够读取其他函数内部变量的函数

定义在一个函数内部的函数

有什么不好的地方?

闭包会使得函数中的变量都保存在内存中,消耗大,降低性能,

在IE下还会造成内存泄漏 :解决方法 在退出函数之前,将不使用的局部变量全部删除

闭包会在父函数外部,改变父函数内部变量的值

20.new运算符的缺点

用构造函数生成实例对象,无法共享属性和方法

  1. vue脚手架3.0 创建脚手架是vue create 项目名 vue脚手架2.0创建脚手架是vue init webpack 项目名

  2. js的设计模式

  3. 单例模式

  4. 工厂模式

  5. 原型模式 (设置函数的原型属性 应用:实现继承)

  6. 观察者模式(发布订阅模式)

  7. 访问模式(通过继承封装一些该数据类型不具备的属性 让对象具备数组的操作方法)

  8. Vue父组件=>子组件传递数据

1、子组件在props中创建一个属性,用以接收父组件传过来的值

2、父组件中注册子组件

3、在子组件标签中添加子组件props中创建的属性

4、把需要传给子组件的值赋给该属性

  1. Vue 子组件=> 父组件传递数据

当子组件需要向父组件传递数据时,就要用到自定义事件。

1、子组件中需要以某种方式例如点击事件的方法来触发一个自定义事件

2、将需要传的值作为$emit的第二个参数,该值将作为实参传给响应自定义事件的方法

3、在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听

  1. Vue兄弟组件传递数据

1、新建一个eventBus.js实例,这个第三方实例就承担起了组件之间通信的桥梁了,也就是中央事件总线

2、然后给每个子组件绑定一个方法(触发时候发布eventBus),在每个子组件做一个订阅的监控,触发绑在created里的方法执行

但是一般不用,复杂项目一般用Vuex

在通信中,组件之间传值,他们都有一个共同点就是有中间介质,

*子向父的介质是自定义事件

*父向子的介质是props中的属性

*非父子组件的介质是中央事件总线

  1. 模板渲染

1.前后端渲染对比:两种方式各有自己的优缺点,需要根据自己的业务场景来选择技术方案。

前端渲染的优点在于:

① 业务分离,后端只需要提供数据接口,前端在开发时也不需要部署对应的后端环境,通过一些代理服务器工具就能远程获取后端数据进行开发,能够提升开发效率。

② 计算量转移,原本需要后端渲染的任务转移给了前端,减轻了服务器的压力。

后端渲染的优点在于:

① 对搜索引擎友好。

② 首页加载时间短,后端渲染加载完成后就直接显示HTML,但前端渲染在加载完成后还需要有段js渲染的时间。

Vue.js 2.0开始支持服务端渲染,从而让开发者在使用上有了更多的选择。

  1. v-if vs v-show

当v-if和v-show的条件发生变化时,v-if引起了dom操作级别的变化,而v-show仅发生了样式的变化,从切换的角度考虑v-show消耗的性能要比v-if小。

除此之外,v-if切换时,Vue.js会有一个局部编译/卸载的过程,因为v-if中的模板也可能包括数据绑定或子组件。

v-if会确保条件块在切换当中适当地销毁与中间内部的事件监听器和子组件。而且v-if是惰性的,如果在初始化条件为假时,v-if本身什么都不会做

而v-show则仍会进行正常的操作,然后吧css样式设置为display:none。

总的来说,v-if有更高的切换消耗,而v-show有更高的初始渲染消耗,我们需要根据实际的使用场景来选择合适的指令。

  1. 问题重现

先大概理解一下,快速梳理一次

  1. 分而治之来调试问题

  2. 每次记录修改的地方

  3. 重现失败

  4. 像各类库插件出问题,去gitHub上去找

  5. 主观臆断的人,总是为了套用理论而扭曲事实,而不是用理论来解释事实

29.前后端分离

后端只负责提供接口供前端使用,跳转前端来完成

  1. react中有几种数据传递方式

  2. props

  3. redux

  4. context

31.说一下es6的新特性,箭头函数的特点?

es6的新特性,箭头函数的特征

声明变量可用const和let,相比var不存在变量提升

便利使用 展开运算符... 剩余运算符

解构赋值 数组和对象中提取值,对变量进行赋值 解构不成功,变量的值就等于undefined

class继承,利用extends关键字实现继承 继承一个类的属性和方法

async 函数,使异步操作变得更加方便

箭头函数中的this继承外围作用域的this

箭头函数没有anguments

箭头函数不能被new

箭头函数没有prototype属性

yield 关键字通常不能在箭头函数中使用

箭头函数可使用闭包

箭头函数可使用三元运算符

32.移动端兼容问题:

html5调用安卓或者ios的拨号功能

html5提供了自动调用拨号的标签,只要在a标签的href中添加tel:就可以

设置new Date日期格式的时候 ios没显示 解决方法

new Date("year-month-day");只识别new Date("year/month/day")

移动端300ms延迟

一个js脚本fastclick.js

input框中鼠标的光标不能居中

去掉line-height就行

33.你以前用过跨域吗,JSONP的原理 www.zhihu.com/question/19…

带callback的json就是jsonp.

利用没有跨域限制 sessionStorage - 针对一个 session 的数据存储,当用户关闭浏览器窗口后,数据会被删除 创建并访问一个 sessionStorage sessionStorage 、localStorage 和 cookie 之间的区别 共同点:都是保存在浏览器端,且同源的 区别: 1. cookie数据始终在同源的http请求中携带 2. sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存 3. sessionStorage仅在页面关闭前有效 4. localStorage用来保存持久数据 5. 作用域的不同sessionStorage不在不同的浏览器窗口中共享, localStorage、cookie 在所有同源窗口中都是共享的

38.你怎么理解http;http怎么工作的; www.cnblogs.com/wxisme/p/62…

主要是用来规定客户端和服务端的数据传输格式、

是用于从服务器传输超文本到本地浏览器的传送协议

1)、地址解析 2)、封装HTTP请求数据包 3)封装成TCP包,建立TCP连接(TCP的三次握手) 4)客户机发送请求命令 5)服务器响应 6)服务器关闭TCP连接

39.说一下promise底层实现机制;

40.AMD cmd require规范的区别;

1、AMD推崇依赖前置,CMD推崇就近依赖

2、执行时机不同:AMD是加载完立即执行,CMD是延迟执行(二者的最大区别)

3、实现按需加载的方法不同

41.webpack 工作配置问题

42.git在工作中如何使用

提交,推送,克隆,回拉

合理利用分支,独立开发不冲突

集中解决冲突

合理使用tag,为提交点打上补丁,方便回滚,不需要revert

43.跨域的几种方式 :juejin.cn/post/684490…

44.DOM-diff原理;juejin.cn/post/684490…

实现domDiff分为以下四步:

  1. 用JS模拟真实DOM节点

  2. 把虚拟DOM转换成真实DOM插入页面中

  3. 发生变化时,比较两棵树的差异,生成差异对象

  4. 根据差异对象更新真实DOM

45.MVC和MVVM什么区别?

M - Model :数据保存

V - View : 用户界面

C - Controller : 业务逻辑

MVC ,用户操作> View (负责接受用户的输入操作)>Controller(业务逻辑处理)>Model(数据持久化)>View(将结果通过View反馈给用户)

MVVM是将“数据模型数据双向绑定”的思想作为核心, 因此在View和Model之间没有联系,通过ViewModel进行交互, 而且Model和ViewModel之间的交互是双喜那个的,因此试图的数据的变化会同事修改数据源, 而数据源数据的变化也会立即反应到View上

46.同步异步,以及JS的事件流;juejin.cn/post/684490…

同步 > 异步 > 回调

setTimeout(function(){ for(var i = 0; i < 100000000; i++){} console.log('timer a'); }, 0) for(var j = 0; j < 5; j++){ console.log(j); } setTimeout(function(){ console.log('timer b'); }, 0) function waitFiveSeconds(){ var now = (new Date()).getTime(); while(((new Date()).getTime() - now) < 5000){} console.log('finished waiting'); } document.addEventListener('click', function(){ console.log('click'); }) console.log('click begin'); waitFiveSeconds();

47.ajax中get和post有什么区别

==get== 1.get请求如果需要传递参数,那么会默认将参数拼接到url的后面;然后发送给服务器 2.get请求传递参数大小是有限制的;是浏览器的地址栏有大小限制;IE不超过2K;谷歌不超过8K;超过会自动截掉 3.get安全性较低 4.get 一般会走缓存,为了防止走缓存,给url后面每次拼的参数不同 5.放在?后面,一般用个时间戳或随机数 ==post== 1.post传递参数,需要把参数放进请求体中,发送给服务器 2.post请求参数放进了请求体中,对大小没有要求 3.安全性比较高 4.post请求不会走缓存 GET产生一个TCP数据包;POST产生两个TCP数据包 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data 服务器响应200 ok(返回数据)

48.前端的性能优化有哪些:juejin.cn/post/684490…

49.前端的安全性;

50.说一下深拷贝和浅拷贝:juejin.cn/post/1

1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用 2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

为什么要使用深拷贝?

我们希望在改变新的数组(对象)的时候,不改变原数组(对象)

怎么检验深拷贝成功

改变任意一个新对象/数组中的属性/元素, 都不改变原对象/数组

51.常见的算法有哪些 :juejin.cn/post/684490…

冒泡排序、选择排序、计数排序、快速排序

52.你知道的前端加密是什么,怎么做的? juejin.cn/post/684490…

摘要哈希生成的正确姿势是什么样呢?分三步:

1.收集相关业务参数,在这里是金额和目标账户。当然,实际应用中的参数肯定比这多得多,这里只是做了简化。

2.按照规则,把参数名和参数值拼接成一个字符串,同时把给定的密钥也拼接起来。之所以需要密钥,是因为攻击者也可能获知拼接规则。

3.利用MD5算法,从原文生成哈希值。MD5生成的哈希值是128位的二进制数,也就是32位的十六进制数。

第三方支付平台如何验证请求的签名?同样分三步:

1.发送方和请求方约定相同的字符串拼接规则,约定相同的密钥。

2.第三方平台接到支付请求,按规则拼接业务参数和密钥,利用MD5算法生成Sign。

3.用第三方平台自己生成的Sign和请求发送过来的Sign做对比,如果两个Sign值一模一样,则签名无误,如果两个Sign值不同,则信息做了篡改。这个过程叫做验签。

53.网络安全

  1. 首先,所有的http/https请求,必须通过身份的验证,没有登录的用户拒绝响应。这是必须做的,身份验证会增加攻击的难度。

  2. 控制数据包的大小,根据自己的业务,设置数据包的最大值,当大于这个值的情况下可以拒绝服务。(业务最大只需要3M, 那么100M的请求就被拒绝了)

  3. 对调用的参数进行校验,比如传输一个很大的数组给后台服务器,在多个请求同时遍历大数组的情况下,会导致CPU资源耗尽。

    1. 除登录用户的校验,还必须增加随机数校验,解决跨站请求伪造的同时,大大增加了Dos攻击的难度。

5.在服务器响应中,不能无限启动新的线程。如果需要多线程处理,需要使用线程池的机制,并控制线程的数量。同时保证线程池不能过多,不能再请求中生成线程池。

  1. 请求要有超时机制,防止请求线程被长时间占用,从而导致线程中的资源无法释放。

54.从url输入到渲染的整个过程

  1. 解析HTML生成DOM树。

  2. 解析CSS生成CSSOM规则树。

  3. 将DOM树与CSSOM规则树合并在一起生成渲染树。

  4. 遍历渲染树开始布局,计算每个节点的位置大小信息。

  5. 将渲染树每个节点绘制到屏幕。

55.TCP三次握手;

第一次握手

client发送一个SYN(J)包给server,然后等待server的ACK回复,进入SYN-SENT状态。p.s: SYN为synchronize的缩写,ACK为acknowledgment的缩写。

第二次握手

server接收到SYN(seq=J)包后就返回一个ACK(J+1)包以及一个自己的**SYN(K)**包,然后等待client的ACK回复,server进入SYN-RECIVED状态。

第三次握手

client接收到server发回的ACK(J+1)包后,进入ESTABLISHED状态。然后根据server发来的SYN(K)包,返回给等待中的server一个ACK(K+1)包。等待中的server收到ACK回复,也把自己的状态设置为ESTABLISHED。到此TCP三次握手完成,client与server可以正常进行通信了

第一次挥手

client发送一个FIN(M)包,此时client进入FIN-WAIT-1状态,这表明client已经没有数据要发送了。

第二次挥手

server收到了client发来的FIN(M)包后,向client发回一个ACK(M+1)包,此时server进入CLOSE-WAIT状态,client进入FIN-WAIT-2状态。

第三次挥手

server向client发送FIN(N)包,请求关闭连接,同时server进入LAST-ACK状态。

第四次挥手

client收到server发送的FIN(N)包,进入TIME-WAIT状态。向server发送**ACK(N+1)**包,server收到client的ACK(N+1)包以后,进入CLOSE状态;client等待一段时间还没有得到回复后判断server已正式关闭,进入CLOSE状态。

56.vue双向数据绑定原理

vue实现数据双向绑定的原理就是用Object.defineproperty()重新定义(set方法)对象设置属性值和(get方法)获取属性值的操纵来实现的

这个方法接收三个参数,第一个要操作的对象,第二个要定义或修改的对象属性名,第三个参数为对象,里面设置了get和set方法

let box = document.getElementById("box"); let obj = {}; let temp ={}; Object.defineProperty(obj,"name",{ get(){ // 在get方法中,不能调用自己的属性名对应的属性值; return temp.name; }, set(val){ // val : 代表的是将要设置的最新的值;是等号右边的值; //console.log(obj); //console.log(box.value); //debugger temp.name=val; box.value = temp.name; } }); // 修改input的内容;改变数据中的name属性值; box.addEventListener("input",function () { // 监听box的input事件;当修改box的输入框内容时,同时修改数据中name属性; obj.name = this.value; }); // 1. 改变input的值;触发oninput事件;会调用set方法;改obj中的值; // 2. 改变obj中的值,改input的框的值;

57.vue的生命周期以及在各个钩子函数执行发生的事情

生成一个vue的实例;需要执行一系列过程;需要设置数据监听,编译模板、并将实例挂载到DOM元素上,并在数据更新时,更新DOM;同时给这个过程中会运行一些生命周期钩子函数

八个钩子函数,分别在不同的时期执行

  1. 在初始化实例时,会默认调用beforeCreate created beforeMount mounted 这四个钩子函数

  2. 当更新数据时,更新之前会触发beforeUpdate这个钩子函数,更新完成之后,会触发updated这个钩子函数

  3. 当vue的实例销毁时,会调用beforeDestroy和destroyed这个钩子函数

1.在beforeCreate和created钩子函数之间的生命周期

在这个生命周期之间,进行初始化事件,进行数据的观测 created的时候数据已经和data属性进行绑定

2、created钩子函数和beforeMount间的生命周期

会判断对象是否有el选项:如果有的话就继续向下编译,如果没有el选项,则停止编译

3、beforeMount和mounted 钩子函数间的生命周期

给vue实例对象添加了$el,替换之前的dom元素、beforeMount之前el上还是undefined

4、mounted

真实dom替换之前占位的虚拟dom,渲染了页面,

5、beforeUpdate钩子函数和updated钩子函数间的生命周期

当vue实例中的data发生变化,对应组件重新渲染、在beforeUpdate可以监听到data的变化,但是view层没有被重新渲染,view层的数据没有变化。等到updated的时候,view层才被重新渲染,数据更新

6、beforeDestroy和destroyed钩子函数间的生命周期

beforeDestroy钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。

Vue 实例销毁后调用destroyed钩子函数,之后Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁

58.vue中组件之间的通信如何完成

父组件 -- > 子组件,使用的props属性传递机制

要实现子组件到父组件之间的通信 ----- 事件机制

兄弟组件之间的通信----使用eventbus

父传子,如果子组件想要拿到父组件data中的数据,利用属性传递,子组件注册标签

中自定义属性取父组件data中属性名,子组件用props[”自定义属性名“] ,子组件中的props用对象的形式可以进行校验 , 其中props:{

type: //检测类型

default:0 //给自定义属性名赋默认值,如果不传,默认值代替

required:true 必须给自定义属性名传值,不能和default同用

validator(val){ //自定义校验器

return>500

} 第一个参数是当前传递的值

} ,并且props 中的属性名和data中的名字不能相同

子传父,利用发布订阅模式,父组件绑定一些事件,子组件触发这个事件,将参数传递过去,单向数据流,父组件刷新,子组件刷新

59.说一说vueX的组成

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

vuex五大核心属性:state,getter,mutation,action,module

 state:存储数据,存储状态;在根实例中注册了store 后,用 this.$store.state 来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。

 getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

 mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。

 action:包含任意异步操作,通过提交 mutation 间接更变状态。

 module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块

由于传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力

我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致代码无法维护

所以我们需要把组件的共享状态抽取出来,以一个全局单例模式管理

60.vue的性能优化

提取组件的 CSS 到单独到文件

当使用单文件组件时,组件内的 CSS 会以 style标签的方式通过 JavaScript 动态注入。这有一些小小的运行时开销,将所有组件的 CSS 提取到同一个文件可以避免这个问题,也会让 CSS 更好地进行压缩和缓存

少的使用watch,使用computed

当组件某个数据变更后需要对应的state进行变更,就需要对另外的组件进行state进行变更。可以使用watch监听相应的数据变更并绑定事件。当watch的数据比较小,性能消耗不明显。当数据变大,系统会出现卡顿,所以减少watch的数据。其它不同的组件的state双向绑定,可以采用事件中央总线或者vuex进行数据的变更操作

computed和watch的区别

  1. computed不支持异步,watch支持异步

  2. 能用computed,就不要用watch

  3. computed走缓存

  4. watch不走缓存

  5. watch一对多 / watch是监听一个属性,它改变了,影响多个属性改变

  6. computed多对一 / computed(计算属性)是多个属性改变影响一个属性改变

v-if 和 v-show选择调用

v-if是懒加载,当状态为true时才会加载,并且为false时不会占用布局空间;v-show是无论状态是true或者是false,都会进行渲染,并对布局占据空间对于在项目中,需要频繁调用,不需要权限的显示隐藏,可以选择使用v-show,可以减少系统的切换开销

细分vuejs组件

拆分组件,不能功能拆分成小模块,让渲染更快

图片按需加载,设置条件请求,达到条件请求数据,渲染页面,完成按需加载图片

61.vue中DOM-diff原理 :blog.csdn.net/m6i37jk/art…

Vue的核心是双向绑定和虚拟DOM


62.react的生命周期

63.react中redux是实现原理

64.react中render实现的原理

65.JSX元素实现原理

66react中组件之间通信如何完成

67.说一说react生命周期函数以及生命周期函数执行时做的事情;

68.如果在页面中只有一处文本改动,用jqery和react,,哪个框架实现的性能高?

69.VUE和REACT有什么区别?juejin.cn/post/684490…

70.react-redux 的实现原理;

71.react中的性能优化 :www.jianshu.com/p/333f390f2…

为什么 react 中循环 建议不使用索引

如果为了展示,可以使用索引,但如果数据太多,会导致页面重新渲染,消耗性能

  1. 20.请详细描述,在浏览器输入一个网址,到最后看到一个完整的网页,都经过了什么步骤? wenku.baidu.com/link?url=4u…

73.前后端联调

在后端没有提供接口时,自己本地mock中的数据与后端提供真实业务数据之间来回切换,在不同开发速度下达到数据交换的一种调试方式

也就是调试自己的代码逻辑和后台接口的问题

74.前后端分离

项目:

简单描述一下这个项目是做什么的?

你在这个项目中负责哪部分?

你在这个项目中遇到哪些问题,是怎么解决的;

这个项目中你应用了什么技术

学习文档