基础面试

5、rem 和flex布局原理javascript

1.rem是根据html的font-size大小来变化,正是基于这个出发,咱们能够在每个设备下根据设备的宽度设置对应的html字号,从而实现了自适应布局php

2.采用flex布局的元素,称为flex容器,它的全部子元素自动成为容器成员,称为flex项目。以下图:
css

容器默认存在2根轴,水平的主轴和垂直的侧轴,主轴的开始位置(与边框的交叉点)叫作main start, 结束位置叫作 main end.
交叉轴的开始位置叫作 cross start,结束位置叫作cross end。项目默认沿主轴排列。单个项目占据的主轴空间叫作main size,
占据的交叉轴空间叫作cross size。html

二:容器有以下6个属性
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content前端

1. flex-direction该属性决定主轴的方向(即项目的排列方向)。
它可能有四个值:
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。vue

 

6、什么是原型链 闭包js的内存分配机制java

原型链:若访问对象属性时,先在基本属性中找,若是自身没有该属性,便会沿着_proto_这条链往上找这个找的路径叫原型链。node

闭包:就是可以读取其余函数内部变量的函数。jquery

因为在javascript中,只有函数内部的子函数才能读取局部变量,因此说,闭包能够简单理解成“定义在一个函数内部的函数“。因此,在本质上,闭包是将函数内部和函数外部链接起来的桥梁。webpack

原型链用于实现JS中的实现继承。(许多语言都支持两种方式的继承:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。因为函数没有签名,在ECMAScript中只能实现实现继承。
原型链做为实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另外一个引用继承的属性和方法。了解一下构造函数、原型和实例的关系:每一个构造函数都是一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。假如咱们让原型对象等于另外一个类型的实例,那么此时的原型对象将包含一个指向另外一个原型的指针,相应的另外一个原型中包含着一个指向另外一个构造函数的指针。如此层层递进,就构成了实例与原型的链条。这就是原型链的概念。
当函数调用时,需查找和获取的变量和元素都会经过原型链机制一层层的往上搜索在原型对象或继承来的对象中得到。

当函数被建立,就有了做用域,当被调用时,就有了做用域链,当被继承时就有了原型链,当须要获取做用域链或原型链上的变量或值时,就有了闭包

JS的内存分配:

javascript中的变量分为两种,原始值和引用值。

原始值:指的是原始数据类型的值,好比undefined,null,number,string,boolean类型所表示的值。

引用值:指的是复合数据类型的值,即Object,Function,Array等。

 

原始值和引用值存储在内存中的位置分别为栈和堆。

原始值是存储在栈中的简单数据段,他们的值直接存储在变量访问的位置。

引用值是存储在堆中的对象。

存储在栈中的值是一个指针,指向存储在堆中的实际对象。     

8、前端性能优化思路经验    

网页内容

减小http请求次数

减小DNS查询次数

避免页面跳转

缓存Ajax

延迟加载

提早加载

减小DOM元素数量

根据域名划份内容

减小iframe数量

避免404

 

服务器

使用CDN

添加Expires 或Cache-Control报文头

Gzip压缩传输文件

配置ETags

尽早flush输出

使用GET Ajax请求

避免空的图片src

 

Cookie

减小Cookie大小

页面内容使用无cookie域名

CSS

将样式表置顶

避免CSS表达式

用<link>代替@import

避免使用Filters

Javascript

将脚本置底

使用外部Javascirpt和CSS文件

精简Javascript和CSS

去除重复脚本

减小DOM访问

使用智能事件处理

 

图片

优化图像

优化CSS Sprite

不要在HTML中缩放图片

使用小且可缓存的favicon.ico

 

9、给一个已知数组去重

第一种是比较常规的方法

思路:

1.构建一个新的数组存放结果

2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比

3.若结果数组中没有该元素,则存到结果数组中


Array.prototype.unique1 = function(){
 var res = [this[0]];
 for(var i = 1; i < this.length; i++){
  var repeat = false;
  for(var j = 0; j < res.length; j++){
   if(this[i] == res[j]){
    repeat = true;
       break;
   }
  }
  if(!repeat){
   res.push(this[i]);
  }
 }
 return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique1());


第二种方法比上面的方法效率要高

思路:

1.先将原数组进行排序

2.检查原数组中的第i个元素 与 结果数组中的最后一个元素是否相同,由于已经排序,因此重复元素会在相邻位置

3.若是不相同,则将该元素存入结果数组中

复制代码代码以下:


Array.prototype.unique2 = function(){
 this.sort(); //先排序
 var res = [this[0]];
 for(var i = 1; i < this.length; i++){
  if(this[i] !== res[res.length - 1]){
   res.push(this[i]);
  }
 }
 return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique2());


第二种方法也会有必定的局限性,由于在去重前进行了排序,因此最后返回的去重结果也是排序后的。若是要求不改变数组的顺序去重,那这种方法便不可取了。

第三种方法(推荐使用)

思路:

1.建立一个新的数组存放结果

2.建立一个空对象

3.for循环时,每次取出一个元素与对象进行对比,若是这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容做为对象的一个属性,并赋值为1,存入到第2步创建的对象中。

说明:至于如何对比,就是每次从原数组中取出一个元素,而后到对象中去访问这个属性,若是能访问到值,则说明重复。

复制代码代码以下:


Array.prototype.unique3 = function(){
 var res = [];
 var json = {};
 for(var i = 0; i < this.length; i++){
  if(!json[this[i]]){
   res.push(this[i]);
   json[this[i]] = 1;
  }
 }
 return res;
}

var arr = [112,112,34,'你好',112,112,34,'你好','str','str1'];
alert(arr.unique3());

 

let、var、const区别:

  1. const定义的变量能够修改,不可重复定义,并且必须初始化

2. var定义的变量能够修改,若是不初始化会输出undefined,不会报错。

3. let是块级做用域,函数内部使用let定义后,对函数外部无影响。

Promise:

Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理更强大。

所谓Promise,简单说就是一个容器,里面保存着某个将来才会结束的事件 (一般是一个异步操做)的结果。从语法上说,Promise是一个对象,从它能够获取异步操做的消息。

Promise对象有如下2个特色: 
    1.对象的状态不受外界影响。Promise对象表明一个异步操做,有三种状态:Pending(进行中)Resolved(已完成)Rejected(已失败)。只有异步操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其余手段没法改变。 
    2.一旦状态改变,就不会再变,任什么时候候均可以获得这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved;从Pending变为Rejected。只要这两种状况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象田静回调函数,也会当即获得这个结果。这与事件(Event)彻底不一样,事件的特色是,若是你错过了它,再去监听,是得不到结果的。

有了Promise对象,就能够把异步操做以同步操做的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供了统一的接口,使得控制异步操做更加容易。

 

跨域:

什么是跨域?

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

所谓同源是指,域名,协议,端口均相同,

浏览器执行javascript脚本时,会检查这个脚本属于哪一个页面,若是不是同源页面,就不会被执行。

解决办法:

1、JSONP:

使用方式就不赘述了,可是要注意JSONP只支持GET请求,不支持POST请求。

2、代理:

例如www.123.com/index.html须要调用www.456.com/server.php,能够写一个接口www.123.com/server.php,由这个接口在后端去调用www.456.com/server.php并拿到返回值,而后再返回给index.html,这就是一个代理的模式。至关于绕过了浏览器端,天然就不存在跨域问题。

 

jquery插件无缝滚动实现原理:

1.不少时候使用方法Ul列表去展现。固然这也有一些好处,好比float对齐之类的。固然直接用p或者div也行。

2.了解overflow属性。在溢出状况下的处理。其实轮播就是在不断的处理li溢出的状况。

3 jQuery animate的动画效果。固然若是不用这个也行。一个setInterval就能搞定它。不过jQuery仍是作了一些封装。

4 可能还须要一些基础的理解就是对定位的熟悉。margin和postion的了解。

5 以后就是循环轮播了,循环轮播须要对节点进行从新的修改。

   具体而言就是在轮播到最后一张图片的时候,修改节点,将第一个节点,添加到列表的最后一个位置。以下:

  1. $(this).css({'margin-left':0}).children('li').last().after($(this).children('li').first());  



看一下核心代码:

html:

  1. <div class="list" id = "sidle">  
  2.     <ul>  
  3.         <li><img src="1.jpg" width="538" height="198" /></li>  
  4.         <li><img src="2.jpg" width="538" height="198" /></li>  
  5.         <li><img src="3.jpg" width="538" height="198" /></li>  
  6.         <li><img src="4.jpg" width="538" height="198" /></li>  
  7.     </ul>  
  8. </div>  


css:

  1. .list{  
  2.     width:538px;  
  3.     height:198px;  
  4.     overflow:hidden;  
  5.     margin:50px auto;  
  6. }  
  7. .list ul{  
  8.     width:2152px;  
  9.     height:198px;  
  10. 10.     margin:0;  
  11. 11.     padding:0;  

12. }  

13. .list ul li{  

  1. 14.     float:left;  
  2. 15.     width:538px;  

16. }  



  1.  (function($){  
  2.     var silde = {  
  3.         init:function(){  
  4.             this.auto();  
  5.         },  
  6.         auto:function(){  
  7.             var _root = this,  
  8.                 $ul = $("#sidle").find("ul"),  
  9.                 $lis = $ul.children("li"),  
  10. 10.                 width = $lis.eq(0).width();  
  11. 11.             setInterval(function(){  
  12. 12.                 $ul.animate({  
  13. 13.                         'margin-left':'-'+ width +'px'  
  14. 14.                     },  
  15. 15.                     'slow',  
  16. 16.                     function(){  
  17. 17.                         //此处保证能循环轮播  
  18. 18.                         //将已经轮播过的节点的第一张图片添加到末尾的位置  
  19. 19.                         //再将margin-left重置为0px;  
  20. 20.                         //这样就能一直的循环下去.  
  21. 21.                         $ul.css({'margin-left':0}).  
  22. 22.                             children('li').  
  23. 23.                             last().  
  24. 24.                             after(  
  25. 25.                                 $ul.children('li').first()  
  26. 26.                             );  
  27. 27.                     });  
  28. 28.                 },2000  
  29. 29.             );  
  30. 30.         }  
  31. 31.     };  
  32. 32.     $(function(){silde.init();})  

33. })(jQuery);  

 

Vuex:

Vuex 是什么?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

什么是“状态管理模式”?

让咱们从一个简单的 Vue 计数应用开始:

 

这个状态自管理应用包含如下几个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入致使的状态变化。

如下是一个表示“单向数据流”理念的极简示意:

 

可是,当咱们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。
  • 来自不一样视图的行为须要变动同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会很是繁琐,而且对于兄弟组件间的状态传递无能为力。对于问题二,咱们常常会采用父子组件直接引用或者经过事件来变动和同步状态的多份拷贝。以上的这些模式很是脆弱,一般会致使没法维护的代码。

所以,咱们为何不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,咱们的组件树构成了一个巨大的“视图”,无论在树的哪一个位置,任何组件都能获取状态或者触发行为!

另外,经过定义和隔离状态管理中的各类概念并强制遵照必定的规则,咱们的代码将会变得更结构化且易维护。

这就是 Vuex 背后的基本思想,借鉴了 FluxRedux、和 The Elm Architecture。与其余模式不一样的是,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。

 

什么状况下我应该使用 Vuex?

在组件外部管理状态, 能够帮助咱们管理共享状态

中小型单页应用,一个简单的 global event bus 就足够您所需了。

Axios:

axios 是一个基于 Promise 的,为浏览器和 Node.js 设计的 HTTP 客户端。它尽量简化封装了 HTTP 相关的各类操做,在 Web App 中使用很是方便,官方建议使用 axios 进行 HTTP 操做

v-modle实现原理:

 

咱们看上图中的代码,有行 $emit的代码,这行代码实际上会触发一个 input事件, 'input'后的参数就是传递给v-model绑定的属性的值,

也就是自定义的组件内部通常包含原生的表单组件(固然非表单的组件也能够)

而后,给原生控件绑定事件,捕捉到原生组件的值,利用 $emit方法,触发input方法,组件监听到 input事件而后把值传入到myattr中.

这里有个疑问,为何是 'input'呢??? 三个字,看文档!

这个就是 vue对 v-model实现的一个规则: 使用了v-model的组件会

自动监听 input 事件,并把这个input事件所携带的值 传递给v-model所绑定的属性!这样组件内部的值就给到了父组件了

经过以上讲解,咱们总结一下如何利用v-model实现自定义的表单组件:

监听原生组件的事件,当获取到原生组件的值后把值经过调用 $emit('input' ,data) 方法去触发 input事件

 

组件之间怎么通讯:

1.父组件传递数据给子组件

父组件数据如何传递给子组件呢?能够经过props属性来实现

这样呢,就实现了父组件向子组件传递数据.

2.子组件与父组件通讯

那么,若是子组件想要改变数据呢?这在vue中是不容许的,由于vue只容许单向数据传递,这时候咱们能够经过触发事件来通知父组件改变数据,从而达到改变子组件数据的目的.

3.非父子组件通讯

若是2个组件不是父子组件那么如何通讯呢?这时能够经过eventHub来实现通讯. 
所谓eventHub就是建立一个事件中心,至关于中转站,能够用它来传递事件和接收事件.

 

这样就实现了非父子组件之间的通讯了.原理就是把Hub看成一个中转站!

 

你是如何搭建脚手架的:

1、环境搭建
  1. 安装node.js,从node.js官网下载并安装node,安装过程很简单,一路“下一步”就能够了(傻瓜式安装)。安装完成以后,打开命令行工具(win+r,而后输入cmd),输入 node -v,以下图,若是出现相应的版本号,则说明安装成功。
    1. 在硬盘上找一个文件夹放工程用的。这里有两种方式指定到相关目录:①cd 目录路径 ②若是以安装git的,在相关目录右键选择Git Bash Here
    2. 安装vue脚手架输入:vue init webpack exprice ,注意这里的“exprice” 是项目的名称能够说是随便的起名,可是须要主要的是“不能用中文”
2.  安装淘宝镜像,打开命令行工具,把这个(npm install -g cnpm --registry= https://registry.npm.taobao.org)安装完成以后输入 cnpm -v,以下图,若是出现相应的版本号,则说明安装成功。
3.  安装webpack,打开命令行工具输入:npm install webpack -g,安装完成以后输入 webpack -v,以下图,若是出现相应的版本号,则说明安装成功。

4.  安装vue-cli脚手架构建工具,打开命令行工具输入:npm install vue-cli -g,安装完成以后输入 vue -V(注意这里是大写的“V”),以下图,若是出现相应的版本号,则说明安装成功。

一.    用vue-cli来构建项目
  1. cd 命令进入建立的工程目录,首先cd exprice(这里是本身建工程的名字);
  2. 安装项目依赖:npm install,由于自动构建过程当中已存在package.json文件,因此这里直接安装依赖就行。不要从国内镜像cnpm安装(会致使后面缺了不少依赖库),可是可是若是真的安装“个把”小时也没成功那就用:cnpm install 吧
  3. 安装 vue 路由模块 vue-router 和网络请求模块 vue-resource,输入:cnpm install vue-router vue-resource –save

建立完成的“exprice”目录以下:

数面试

 

css部分

  1. position有哪些属性?
  1. 盒模型中的content如何固定100px?

设置 box-sizing: content-box;

  1. transition/translate/transform 如何实现2s使一个with100px的盒子变成200px?

transition过渡属性

transition-property  

transition-duration

transition-timing-function: linear/ease

transition-delay

  1. 容器中的不定长宽div如何上下左右居中对齐?

js部分

  1. 原生js如何获取时间戳?

Date.parse(new Date())

(new Date()).valueOf()

new Date().getTime()

  1. JSON两个转换方法记得吗?

JSON.parse()

JSON.stringify()

  1. 如何用jquery实现列表奇偶行设置自定义颜色?

//偶数行:even

$(“ul li:even”).css(‘backgroundColor’: ‘blue’)

//偶数行:odd

$(“ul li:odd”).css(‘backgroundColor’: ‘green’)

  1. 普通数组与对象数组如何快速排序?数组遍历方法有哪些?map方法参数有哪些,有什么做用?

普通数组:经常使用方法sort()为数组排序,默认会调用toString()方法比较ASCII值升序排序。

对象数组:编写一个函数参数为(arr, prop, desc)

  1. 要利用数组sort方法就先初始化一个空数组
  2. 数组长度作全局缓存
  3. 比较属性prop的键值数据类型都须要作判断
  4. 最后调用数组的sort方法
  5. 最后是数组拷贝到目标数组
  6. 返回该目标数组
  1. 对象排序怎么作?
    1. 获取对象属性集合Object.keys()
    2. Object.keys = Object.keys || function(obj){

var a = [];

//简洁巧妙,遍历同时赋值

for(a[a.length] in obj){

       return a;

}

}

注意旧版本的IE,不支持for in遍历名为valueOf和toString的属性名

  1. 遍历数组和对象分别有哪些方法?效率高的是什么方法?
    1. 原生for循环、for-in及forEach

1.1   for-in遍历数组或者对象,i值表明数组每一项的下标值,或者表明对象的每一项的key值。(特别为遍历对象设计)

1.2   forEach遍历数组,三个参数依次是数组元素、索引、数组自己(只能遍历数组) arr.forEach(value, index, arr)

1.3   能遍历对象和数组—通用的forEach方法

function forEach(obj){

             var key;

             If( obj instantceof Array ){

                       obj.forEach(function(item){

                                console.log(item);

})

}else{

         for(var key in obj){

         console.log(key, obj[key]);

}

}

}

  1. ES6 for-of方法遍历类数组集合

//for-of遍历Map对象, 遍历字符串”china中国”

let iterable = new Map([[“a”: 1],[“b”: 2],[“c”: 3]]);

for(let [key, value] in iterable){

            console.log(value);

}

  1. Object.key()返回键名的集合
  1. jQuery的$.each()

$.each(function(index, value){})遍历对象和数组

  1. underscore的_.each()

_.each(arrTmp,function(value,index,array){}遍历对象和数组

  1. javascript原生遍历方法的建议用法:

用for循环遍历数组

用for-in遍历对象

用for-of遍历类数组对象(ES6)

用Object.keys()获取对象属性名的集合

  1. 数组对象嵌套的状况怎么排序?
  1. 如何复制一个数组或者一个对象?有更快速便捷的方式吗?

复制有浅拷贝与深拷贝之分:

1.1 浅拷贝是赋值操做,只是建立了一份原内容的引用

1.2 深拷贝有三种方法

1.2.1 遍历复制

1.2.2 (最快的复制方法1是concat一个空数组)

arrayObject.concat(arrayX, arrayX…)

(最快的复制方法2是slice(start, end)从头截到尾)

arr.slice(0)

都不改变原数组且返回被链接数组的一份拷贝

1.3   实例:

var objDeepCopy  = function(source){

        var sourceCopy = source instanceof Array ? [] : {};

        for(var item in source){

sourceCopy[item] = typeof source[item] === 'object' ? objDeepCopy(source[item]) : source[item];

        }

        return sourceCopy;

        }

  1. (5,10)之间的随机数怎么获取?

Math.random() * (max - min) + min

Math.floor(Math.random()*(max-min)+min)

Math.round((Math.random()*(max-min)+min)*10)/10

  1. typeof [] 输出值是什么?

typeof 有哪些返回值类型:

10.1 boolean (true false)

10.1  number (NaN Infinity)

10.2  string ("123")

10.3  function (Date eval)

10.4  object (window document null [] {})

10.5  undefined (undefined sass)

  1. Js如何判断值是否为数字?

1.1    使用isNaN()函数处理,会把””/[]/null看成0处理,视为数字

···   11.2 function isNaN(val){

If(val === “” || val == null || val == []){
       return false;

} else if(!isNaN(val)){

       return true;

}else{

       return false;

}

}   

  1. 两个数组如何链接在一块儿?数组与字符串直接转换方法是什么?

concat()方法和slice(start,end)截取返回都不改变原数组:快速深拷贝一个数组

数组转字符串: join(“”)

字符串转数组:split(“,”)

项目部分

  1. 你在项目中用过哪些技术?
  2. 负责哪些模块的实现?
  3. 项目中碰到过什么问题?
  4. 你是怎么解决的?

电话面试:

flex 应用

栅格布局

前端缓存技术有用过哪些

什么是原型链?有哪几种方法实现继承,多态,封装?

闭包是什么?用闭包实现过什么功能?

Js事件都有哪些?

vue的mvvm实现原理

vue路由实现原理

vue的钩子函数有哪些?

vue的:和 @分别表明什么含义?

vue项目的开发目录还记得吗?有公司公用的组件怎么放置的?

先后端分离 打包发布怎么作的

 

面试笔试题:

解析url:http://www.qq.com?tag=12 p 5ih&g=&u=50为json对象

(Window.foo||(window.foo=”bar”)) window.foo的值是什么?

描述下position的relative和absolute的原理和关系?

Css如何清除浮动?

编写一个高效的数组去重方法

请简述Onload和DomContentLoad的区别?

一个类的方法写在构造函数里边与写在原型中的区别?

简述下建立Ajax|请求的过程,描述下什么是跨域?

Vue中v-bind 和 v-on的分别是什么?

Js的基本数据类型有哪些?

Get和Post有什么区别?

描述Expires和 Cache-control的功能细节?

简述xss的原理,如何预防?

Repaint和reflow是什么?

相关文章
相关标签/搜索