2020了,初/中级前端面试你应该知道的(下)

26. Vue父子间如何双向绑定

第一种:父——>子通过props传递数据,子——>父通过自定义事件通信

第二种:通过v-model实现父子间双向数据绑定

第三种:使用.sync修饰符实现父子间的双向数据绑定

 

27. 面向对象思想

javascript中的面向对象:ECMA标准定义JS中的对象:无序属性的集合,其属性可以包含基本值、对象或者函数。可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)

面向对象三个基本特征是:封装、继承、多态

封装:将对象运行所需的资源封装在程序对象中——基本上,是方法和数据。对象是公布其接口。其他附加到这些接口上的对象不需要关心对象实现的方法即可使用这个对象。这个概念就是不要告诉我你是怎么做的,只要做就可以了。对象可以看作是一个自我包含的原子。对象接口包括了公共的方法和初始化数据。

继承:说到继承并不太陌生,继承可以使得子类具有父类的各种的公有属性和公有方法。而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。

子类继承父类后,子类具有父类属性和方法,然而也同样具备自己所独有的属性和方法,也就是说,子类的功能要比父类多或相同,不会比父类少。

多态:按字面的意思就是多种状态,允许将子类类型的指针赋值给父类类型的指针。

说白了多态就是相同的事物,一个接口,多种实现,同时在最初的程序设定时,有可能会根据程序需求的不同,而不确定哪个函数实现,通过多态不需要修改源代码,就可以实现一个接口多种解决方案。

多态的表现形式重写与重载。

1、易维护
采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的。
2、质量高
在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求并具有较高的质量。
3、效率高
在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
4、易扩展
由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。

28.  jQuery传统项目的看法

jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作,其实和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。比如需要获取label标签的内容:$("lable").val();,它还是依赖DOM元素的值。

Vue则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的DOM对象,可以说数据和View是分离的,他们通过Vue对象这个vm实现相互的绑定。这就是传说中的MVVM

vue适用的场景:复杂数据操作的后台页面,表单填写页面

jquery适用的场景:比如说一些html5的动画页面,一些需要js来操作页面样式的页面

然而二者也是可以结合起来一起使用的,vue侧重数据绑定,jquery侧重样式操作,动画效果等,则会更加高效率的完成业务需求

 

29. 小程序如何获取位置

获取用户地理位置信息  scope.userLocation自带方法获取经纬度

腾讯位置服务应用

 

30、说说弹性布局,如何分成四份

弹性布局,又称“Flex布局,是由W3C2009年推出的一种布局方式。可以简便、完整、响应式地实现各种页面布局。

使用:

给父容器添加display: flex/inline-flex;属性,即可使容器内容采用弹性布局显示,而不遵循常规文档流的显示方式;

容器添加弹性布局后,仅仅是容器内容采用弹性布局,而容器自身在文档流中的定位方式依然遵循常规文档流;

③  display:flex;容器添加弹性布局后,显示为块级元素;

display:inline-flex;容器添加弹性布局后,显示为行级元素;

设为Flex布局后,子元素的floatclearvertical-align属性将失效。但是position属性,依然生效。

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

分成四份: flex-grow1flex-shrink1

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

31、Vue路由传参

  1. 通过query的方式也就是?的方式路径会显示传递的参数
  2. 通过params的方式,路径不会显示传递的参数
  3. 通过 :/ 的的形式传递传参

32、像素单位

px单位名称为像素,相对长度单位,像素(px)是相对于显示器屏幕分辨率而言的国内推荐;

em单位名称为相对长度单位。相对于当前对象内文本的字体尺寸,国外使用比较多;扩展阅读:html em标签,html em强调标签

pt单位名称为点(Point),绝对长度单位一般老版本的table使用长度大小单位但是现在基本上没有使用。

 

html单位简短介绍:

 

Px 像素Pixel;相对长度单位。

Pt 点(Point);绝对长度单位

Em 相对长度单位,这里emhtml <em>标签的"EM"拼写完全相同,而这里em作为单独文本单位。

 

33. 闭包

闭包是指有权访问另一个函数作用域中的变量的函数 --JavaScript高级程序设计》

函数对象可以通过作用域关联起来,函数体内的变量都可以保存在函数作用域内,这在计算机科学文献中称为闭包”,所有的javascirpt函数都是闭包 --Javascript权威指南》

闭包的用途:

  1. 保护变量的安全实现JS私有属性和私有方法
  2. 将处理结果缓存

闭包的缺点:

闭包将函数的活动对象维持在内存中,过度使用闭包会导致内存占用过多,所以在使用完后需要将保存在内存中的活动对象解除引用;

闭包只能取得外部函数中任何变量的最后一个值,在使用循环且返回的函数中带有循环变量时会得到错误结果;

当返回的函数为匿名函数时,注意匿名函数中的this指的是window对象。

34. iframe标签

iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。

iframe常用属性:

  1. frameborder:是否显示边框,1(yes),0(no)
  2. height:框架作为一个普通元素的高度,建议在使用css设置。
  3. width:框架作为一个普通元素的宽度,建议使用css设置。
  4. name:框架的名称,window.frames[name]时专用的属性。
  5. scrolling:框架的是否滚动。yes,no,auto
  6. src:内框架的地址,可以使页面地址,也可以是图片的地址。
  7. srcdoc , 用来替代原来HTML body里面的内容。但IE不支持, 不过也没什么卵用
  8. sandbox: iframe进行一些列限制,IE10+支持

35. 简述vue生命周期

生命周期钩子详细

beforeCreate 在实例初始化之后,数据观测(data observer) event/watcher 事件配置之前被调用。

created 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用。

mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。

activated keep-alive 组件激活时调用。

deactivated keep-alive 组件停用时调用。

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

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

(除了beforeCreatecreated钩子之外,其他钩子均在服务器端渲染期间不被调用

36. webpack五大核心

  1. 入口(entry)

入口起点 --> 入口文件以来的模块和库 --> 处理依赖

  1. 输出(output)

打包完毕 --> 输出bundles(打完包的部分) --> 输出文件命名(默认为./dist)

  1. 加载器(loader)

用来将其他不同语言的文件(:lesssasstypescript)转为js文件

  1. 插件(plugins)

下载 --> require进配置文件中 --> 应用到配置数组plugins

  1. 模式

选择development production 之中的一个,来设置 mode 参数

37. 熟悉原生js开发

测试如下:

1,写出一套自定义事件机制抄,要求可以实现对指定对象绑定多个自定义事件,拿到这个对象句柄的所有地方都可以触发定义过的事件

2,模拟出浏览器的alert prompt confirm 要求可配置标知题、提示文本、按下确定\取消时的回调方法、处理抢占问题等等

3,解析出一个dom内部具有制定属性的所有节点,例如:

<div id="test"><span attr="a"></span><span attr="b"></span></div>

test一次性解析后,可以拿到test.atest.b 等等

4,想一套页面分模块机制,要求一个模块出道错不影响其它模块,模块间可以通信

38. vue 定时器使用与清除

由于项目中难免会碰到需要实时刷新,无论是获取短信码,还是在支付完成后轮询获取当前最新支付状态,这时就需要用到定时器。

但是,定时器如果不及时合理地清除,会造成业务逻辑混乱甚至应用卡死的情况,这个时就需要清除定时器。

某个页面中启动定时器后,一定要在页面关闭时将定时器清除掉。即在页面卸载(关闭)的生命周期函数里beforeDestroy,清除定时器。

38. echarts载入在哪个生命周期

mounted里使用setEchart方法,初始化图表组件,一定要在这里使用该方法,否则会找不到DOM

updated周期里是响应参数变化的方法,首先检测该实例有没有生成(单页应用因为用户可能存在的误操作,很可能导致实例没有生成,这里检测是很有必要的),接着在vue中的数据发生改变时运行chartChange方法,注意,我的选择框是没有绑定事件的,只是通过v-model改变了参数,然后opt动态响应了参数的变化。当opt的参数变化的时候,updated中的方法就会执行,echarts也会动态响应。这个就是使用基于数据驱动vue最精巧的地方,避免了通过事件调用echartChange方法。也是vue中使用echarts核心的一环

39. vue3.0新增了哪些

Vue 3.0计划并已实现的主要架构改进和新功能:

编译器(Compiler

使用模块化架构

优化 "Block tree"

更激进的 static tree hoisting 功能 (检测静态语法,进行提升)

支持 Source map

内置标识符前缀(又名"stripWith"

内置整齐打印(pretty-printing)功能

移除 Source map 和标识符前缀功能后,使用 Brotli 压缩的浏览器版本精简了大约10KB

运行时(Runtime

速度显著提升

同时支持 Composition API Options API,以及 typings

基于 Proxy 实现的数据变更检测

支持 Fragments (允许组件有从多个根结点)

支持 Portals (允许在DOM的其它位置进行渲染)

支持 Suspense w/ async setup()

40. 前端安全问题

1XSSCross-Site Scripting)脚本攻击漏洞;

 

2CSRFCross-sit request forgery)漏洞;

 

3iframe安全隐患问题;

 

4、本地存储数据问题;

 

5、第三方依赖的安全性问题;

 

6.HTTPS加密传输数据;

42. 性能优化

优化的目的:

优化的目的在于让页面加载的更快,对用户操作响应更及时,为用户带来更好的用户体验,对于开发者来说优化能够减少页面请求数,能够节省资源。

前端优化的方法有很多种,可以将其分为两大类,第一类是页面级别的优化如http请求数,内联脚本的位置优化等,第二类为代码级别的优化,例Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等。

页面级别优化

http请求数:

减少http请求数是最重要也是最有效的方法,可以通过以下方法来减少http请求

1)合理的设置http缓存,恰当的缓存设置可以大大减少http请求。要尽可能地让资源能够在缓存中待得更久

2)从设计实现层面简化页面,保持页面简洁、减少资源的使用时是最直接的。

3)资源合并与压缩,尽可能的将外部的脚本、样式进行合并,多个合为一个。

4CSS Sprites,通过合并 CSS图片,这是减少请求数的一个好办法

内联脚本的位置

浏览器是并发请求的,而外链脚本在加载时却常常阻塞其他资源,例如在脚本加载完成之前,它后面的图片、样式以及其他脚本都处于阻塞状态,直到脚本加载完成后才会开始加载。如果将脚本放在比较靠前的位置,则会影响整个页面的加载速度从而影响用户体验。所以说尽可能的将脚本往后挪,减少对并发下载的影响

代码级别的优化

DOM操作优化

要避免在document上直接进行频繁的DOM操作,可以使用classname代替大量的内联样式修改,对于复杂的UI元素,设置positionabsolutefixed,尽量使用css动画,适当使用canvas尽量减少css表达式的使用,使用事件代理

图片优化

通过对图片的压缩来起到优化前端性能的作用

CSS选择符:

大多数人认为,浏览器对CSS的解析是从左往右的,事实上从右往左解析的效率更高,因为第一个id选择基本上就把查找的范围限定了

43. cookie与session

不要混淆 session session 实现。

本来 session 是一个抽象概念,开发者为了实现中断和继续等操作,将 user agent server 之间一对一的交互,抽象为会话,进而衍生出会话状态,也就是 session 的概念。

cookie 是一个实际存在的东西,http 协议中定义在 header 中的字段。可以认为是 session 的一种后端无状态实现。

而我们今天常说的 “session”,是为了绕开 cookie 的各种限制,通常借助 cookie 本身和后端存储实现的,一种更高级的会话状态实现。

所以 cookie session,你可以认为是同一层次的概念,也可以认为是不同层次的概念。具体到实现,session 因为 session id 的存在,通常要借助 cookie 实现,但这并非必要,只能说是通用性较好的一种实现方案。

44. Vue与传统MVC对比

  1. MVCModel模型+View视图+controller控制器,主要是基于分层的目的,让彼此的职责分开。View通过Controller来和Model联系,ControllerViewModel的协调者,ViewModel不直接联系,基本联系都是单向的。
    用户通User过控制器Controller来操作模板Model从而达到视图View的变化
  2. MVP:是从MVC模式演变而来,都是通过Controller/Presenter负责逻辑的处理+Model提供数据+View负责显示。
    MVP中,PresenterView是没有直接关联的,是通过定义好的借口进行交互,从而使得在变更View的时候可以保持Presenter不变。
    MVP模式的框架:Riot.js
  3. MVVMMVVM是把MVC里的ControllerMVP里的Presenter改成了ViewModelModel+View+ViewModel
    View的变化会自动更新到ViewModelViewModel的变化也会自动同步到View上显示。这种自动同步是因为ViewModel中的属性实现了Observer,当属性变更时都能触发对应的操作。

MVVM模式的框架有:Angular.js + Vue.jsKonckout+Ember.js后两种知名度较低以及是早起的框架模式。

45. await与promise

async-awaitpromisegenerator的语法糖。只是为了让我们书写代码时更加流畅,当然也增强了代码的可读性。简单来说:async-await 是建立在 promise机制之上的,并不能取代其地位。

await 可以理解为是 async wait 的简写。await 必须出现在 async 函数内部,不能单独使用。

await 后面可以跟任何的JS 表达式。虽然说 await 可以等很多类型的东西,但是它最主要的意图是用来等待 Promise 对象的状态被 resolved。如果await的是 promise对象会造成异步函数停止执行并且等待 promise 的解决,如果等的是正常的表达式则立即执行。

46. vue常用组件

核心组件 路由:vue-route

异步数据请求:axios

vuex 状态管理

UI

焦点图 / 轮播图 swiper

图表 vue-echarts

安全性 传输加密:sha256md5base64rsa

性能优化 图片懒加载 vue-lazyload 上传图片压缩 lrz

47. Typescript是否了解

TypeScript具有类型系统,且是JavaScript的超集。它可以编译成普通的JavaScript代码。 TypeScript支持任意浏览器,任意环境,任意系统并且是开源的。Ts主要用于解决那些问题:

js木有编译类型检查,写代码的时候木有错误,在运行的时候就发现错误一大堆,ts具有类型系统,可以解决此类问题

js代码非常灵活,同一团队中,大神和小菜鸟写的代码各不相同,维护起来十分不便,统一采用ts开发js,使用相同的规则进行编码,能够比较好的解决此类问题

js发展十分迅速,存在各种各样的版本和各种环境,在不同的环境中特性存在差异,为了满足各种环境,需要编写各异的代码,js通过制定编译环境可以将同一代码编译成对应环境的js脚本

js在编译大型项目缺乏良好的模块及文件的组织,需要支持有模块及命名空间的概念,遵循CommonJs的规范,ts支持模块及命名空间,同时支持。

48. Lodash框架

1.下载地址

https://www.bootcdn.cn/lodash.js/

 

2.开始使用

1.chunk方法

将数组进行切分

 

var arr = [1,2,3,4]

var newArr = _.chunk(arr,2)

console.log(newArr) //[1,2] [3,4]

1

2

3

2.compact方法

去除假值。(将所有的空值,0NaN过滤掉)

 

_.compact(['1','2',' ',0])

// => ['1','2']

1

2

3.uniq方法

数组去重。(将数组中的对象去重,只能是数组去重,不能是对象去重。)

 

_.uniq([1,1,3])

// => [1,3]

1

2

4.reject方法

根据条件去除某个元素

 

var foo = [

    {id: 0, name: "aaa", age: 33},

    {id: 1, name: "bbb", age: 25}

]

var bar = _.reject(foo, ['id', 0])

 

//bar = [{id: 1, name: "bbb", age: 25}]

1

2

3

4

5

6

7

5.shuffle方法

无序化

 

_.shuffle([1,2,3,4]);// 无序化

1

6.pick方法

根据key来筛选数组

 

var foo = {id: 0, name: "aaa", age: 33}

var bar = _.pick(foo, ['name', 'age'])

//bar = {name: "aaa", age: 33}

1

2

3

7.keys方法

返回object中的所有key

 

var foo = {id: 0, name: "aaa", age: 33}

var bar = _.keys(foo)

//bar = ['id', 'name', 'age']

1

2

3

8.cloneDeep方法

深度拷贝

 

9.forEach方法

_.forEach(agent,function(n,key) {

 

    agent[key].agent_id= agent[key].agent_name

 

})

1

2

3

4

5

这是一个常见的forEach的数组遍历,使用了lodash过后,_.forEach()这是一个值,而不是一个函数。就可以直接

 

const arr = _.forEach();

1

这时候arr就是新的数组agent

 

10.merge方法

merge 参数合并

递归的将源对象和继承的可枚举字符串监控属性合并到目标对象中。源对象从左到右引用,后续来源将覆盖以前来源的属性分配。

 

var object = {

  'a': [{ 'b': 2 }, { 'd': 4 }]

};

 

var other = {

  'a': [{ 'c': 3 }, { 'e': 5 }]

};

 

_.merge(object, other);

// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }]

1

2

3

4

5

6

7

8

9

10

在实际开发中,前端在接口的请求可以merge一下之前的query和现在改变的查询的值,再去请求后端接口的数据

 

11.random方法

console.log(_.random(10, 20)); // 获取随机数

_.random(15, 20, true); // 随机浮点

_.sample(["lisong", "heyan"], 1);// 随机获取数组中的某一项,attr2:随机获取的个数

1

2

注意一下如果没找到的话,会返回undefined,要处理一下

 

13.keyBy方法

以某个属性为键,将数组转为对象

 

var foo = var foo = [

    {id: 0, name: "aaa", age: 33},

    {id: 1, name: "bbb", age: 25

3

12.find方法

find查找数组

 

var foo = [

    {id: 0, name: "aaa", age: 33},

    {id: 1, name: "bbb", age: 25}

]

var bar = _.find(foo, ['id', 0])

//bar = {id: 0, name: "aaa", age: 33}

1

2

3

4

5

6}

]

var bar = _.keyBy(foo, 'name')

//bar = {

//    aaa: {id: 0, name: "aaa", age: 33},

//    bbb: {id: 1, name: "bbb", age: 25}

//}

1

2

3

4

5

6

7

8

9

14.filter方法

根据条件过滤出符合条件的元素,返回新数组

 

var foo = var foo = [

    {id: 0, name: "aaa", age: 33},

    {id: 1, name: "bbb", age: 25}

]

var bar = _.filter(foo, ['name', "aaa"])

//bar = {

//    aaa: {id: 0, name: "aaa", age: 33}

//}

1

2

3

4

5

6

7

8

15.map方法

从集合中挑出一个key,将其值作为数组返回

 

var foo = var foo = [

    {id: 0, name: "aaa", age: 33},

    {id: 1, name: "bbb", age: 25}

]

var bar = _.map(foo, 'name')

//bar = ["aaa", "bbb"]

1

2

3

4

5

6

16.max/.min/_.sum方法

数组中最大值、最小值、数组求和

 

var foo = [1, 2, 3, 4]

var bar = _.max(foo)

//bar = 4

bar = _.min(foo)

//bar = 1

bar = _.sum(foo)

//bar = 10

1

2

3

4

5

6

7

17.pad/.padStart/_.padEnd方法

在两端、开头、末尾补齐字符

 

var foo = "helloworld"

var bar = _.pad(foo, 14, '-')

//bar = --helloworld--

bar = _.padStart(foo, 14, '-')

//bar = ----helloworld

bar = _.padEnd(foo, 14, '-')

//bar = helloworld----

1

2

3

4

5

6

7

选出json数组中id最大的一项

var foo = [

    {id: 0, name: "aaa", age: 33},

    {id: 1, name: "bbb", age: 25}

]

var bar = _.find(foo, ['id', _.max(_.map(foo, 'id'))])

// bar = {id: 1, name: "bbb", age: 25}

// ps:也可以用maxBy某个key来代替

1

2

3

4

5

6

7

更新json数组中某一项的值

var foo = [

    {id: 0, name: "aaa", age: 33},

    {id: 1, name: "bbb", age: 25}

]

let list = _.keyBy(foo, 'id')

list[0].name = "ccc"

var bar = _.map(list)

// bar = [

//    {id: 0, name: "ccc", age: 33},

//    {id: 1, name: "bbb", age: 25}

//]

1

2

3

4

5

6

7

8

9

10

11

flatten方法

var arr = [1,2,[3,4,[5],6]]

var a8 = _.flatten(arr)  //[ 1, 2, 3, 4, [ 5 ], 6 ]

var a9 = _.flattenDeep(arr)  //[ 1, 2, 3, 4, 5, 6 ]

var a10 = _.flattenDepth(arr,2)  //[ 1, 2, 3, 4, 5, 6 ]

1

2

3

4

数组去重

var arr2 = [12,14,11,12,12,1,14,16,17,22,2,11,12]

var a11 = Array.from(new Set(arr2))

var a12 = [...new Set(arr2)]

var a13 = _.uniq(arr2)  //[ 12, 14, 11, 1, 16, 17, 22, 2 ]

var arrObj = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];

var a14 = _.uniqWith(arrObj, _.isEqual)  //[ { x: 1, y: 2 }, { x: 2, y: 1 } ]

49. canvas画布

HTML5 canvas 元素使用 JavaScript 在网页上绘制图像。

画布是一个矩形区域,您可以控制其每一像素。

canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。

50. websocekt

WebSocket是一种在单个TCP连接上进行全双工通信的协议。

WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket 的优点:  开销少、时时性高、二进制支持完善、支持扩展、压缩更优。

 因为 HTTP 协议有一个缺陷:通信只能由客户端发起。

51. vue的优势,与传统MVC的优势

精力集中, 代码结构, 操作性, 模块化, 单页面实现, 组件复用, 性能

52. 冒泡排序的原理

     算法原理:每次对相邻的两个元素进行比较,若前者大于后者则进行交换,如此一趟下来最后一趟的就是最大元素,重复以上的步骤,除了已经确定的元素。

53. hash和history的区别

    hash:  即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。

比如这个 URLhttp://www.aaa.com/#/hellohash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

      history:  利用了 HTML5 History Interface 中新增的 pushState() replaceState() 方法。(需要特定浏览器支持)

这两个方法应用于浏览器的历史记录栈,在当前已有的 backforwardgo 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。

因此可以说,hash 模式和 history 模式都属于浏览器自身的特性,Vue-Router 只是利用了这两个特性(通过调用浏览器提供的接口)来实现前端路由。

54. 箭头函数this指向

     箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象)

55. 多接口传入如何处理

把多个接口揉成一个接口

var http = require('http');

var mysql      = require('mysql');

var connection = mysql.createConnection({

    host     : 'rm-bp1w72suk8pc5h6mk.mysql.rds.aliyuncs.com',

    user     : 'r85u40z94p',

    password : 'Mafeng11',

    database: 'r85u40z94p'

});

//开始你的mysql连接

connection.connect();

 

 

var server = http.createServer(function (req, res) {

    //如果你发一个GEThttp://127.0.0.1:9000/test

    var url_info = require('url').parse(req.url, true);

    //检查是不是给/testrequest

    if(url_info.pathname === '/test'){

        res.writeHead(200, {'Content-Type': 'text/plain'});

         

 

 

                connection.query('SELECT * FROM `r85u40z94p`.`user`  order by rand()  LIMIT 5',function(err,rows,fields){

                    //处理你的结果e68a84e8a2ade79fa5e9819331333365633838

                   // res.end(rows.constructor);

                    // 输出结果

                    res.end(JSON.stringify(rows));

 

 

                    console.log(rows.constructor);

                    console.log(typeof(rows));

                    res.end(rows.join);

                    console.log(err);

                    console.log(fields);

                });

    }

    //这个是用来回复上面那个post的,显示post的数据以表示成功了。你要是有别的目标,自然不需要这一段。

    else{

        req.pipe(res);

    }

});

server.listen(9000, '127.0.0.1');

//server关闭的时候也关闭mysql连接

server.on('close',function(){

    connection.end();

});

console.log('listening on port  9000');

56. 后端实时推送数据处理方式

     webSocketAjax轮询,iframe

  1. 原型与原型链

原型:  

所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象

所有函数都有一个prototype(原型)属性,属性值是一个普通的对象

所有引用类型的__proto__属性指向它构造函数的prototype

原型链: 当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

58. Vuex五大核心

     state => 基本数据

     getters => 从基本数据派生的数据

     mutations => 提交更改数据的方法,同步!

     actions => 像一个装饰器,包裹mutations,使之可以异步。

     modules => 模块化Vuex

59. 项目开发中常用插件

     bootstrap,swiper,vue,webpack

60. null与undifined区别 1+null 1+undifined

    (1)Null类型,代表空值,代表一个空对象指针,使用typeof运算得到object,所以你可以认为它是一个特殊的对象值;

  (2)Undefined类型,当一个声明了一个变量未初始化时,得到的就是undefined

  (3)undefined是访问一个未初始化的变量时返回的值,而null是访问一个尚未存在的对象时所返回的值。因此,可以把undefined看作是空的变量,而null看作是空的对象。

     1+null=null     1+undefined=NaN

  1. object.defineproperty缺点

    (1). 无法检测到对象属性的新增或删除

    (2). 不能监听数组的变化

63. js的执行机制

    (1). "任务队列"是一个事件的队列,只要事件指定过回调函数,这些事件完成任务时,就会向"任务队列"添加一个事件,等待主线程读取。

    (2). 当主线程执行完执行栈中的同步任务之后,去开始执行已经完成任务等待中的异步任务,执行的就是任务对应的回调函数

    (3). 主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动进入主线程(定时器到了规定的时间,才能返回主线程)

    (4). 异步任务,意味着只有当前脚本的所有代码执行完,系统才会去读取"任务队列

    (5). 先执行主线程(同步任务放置在主线程),主线程执行完,系统去读取任务队列(异步任务放置在任务队列)

64. 深拷贝与浅拷贝

    深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。

    (1).  JSON方法实现

    (2). for…in…实现便历和复制

    (3). 利用数组的Array.prototype.foreach进行copy

posted @ 2020-05-14 20:05  王小道  阅读(617)  评论(1编辑  收藏  举报