零散的JavaScript知识

1.谈谈优雅降级和渐进增强的区别

  渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能然后再针对高级浏览器进行的效果、交互等改进和追加功能达到更好的用户体验

  优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

2.描述cookies,sessionStorage和localStorage的区别?

  相同点:都是保存在浏览器端,且同源

区别:
1、cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存

2、存储大小限制也不同,cookie数据不能超过4k,sessionStorage和localStorage 但比cookie大得多,可以达到5M

3、数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

4、作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面(即数据不共享);localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的( 即数据共享 )。

3.简要解释盒模型、行内元素与块级元素的概念。

  盒模型:w3C的标准盒模型是指外边距+边框+内边距+内容。

  行元素:占据行内的一部分,宽度和高度随内容变化,不主动换行;

  块元素:占据一行,个元素会换行显示,可设置宽高。

4.如何进行前度优化?简述几种常用的方法。

  1. js代码通过外联样式的方式写在body标签的最后
  2. 制成精灵图,不仅可以减少代码,还可以减少对服务器的请求次数,提高性能
  3. 利用本地变量存储请求成功数据,减少请求。
  4. 不要使用css表达式,尽量使用具体的数值。
  5. 动态改变DOM结构时,利用DOM片段,先将要创建的DOM节点放在一个DOM片段上,最后一次性插入。用innerHTML代替DOM操作,减少DOM操作次数。缓存DOM节点查找的结果
  6. 防止页面的重绘与重写。

5.jsonp的原理?如何实现?为什么ajax不能跨域请求?

    jsonp本质是利用了标签具有可跨域的特性,由服务器返回预先定义好的JavaScript函数的调用,并且将服务器以该数据参数的形式传递过去。

  jsonp的工作原理:使用script标签实现跨域访问,可在url中指定回调函数,获取json数据并在指定的回调函数中执行jquery实现jsonp

  缺点:只支持get方式的jsonp实现,是一种脚本注入行为存在一定的安全隐患。如果返回的数据格式有问题或者返回失败了,并不会报错。

    <script>
       function fuc(data){
         console.log(data.name);
        }
     </script>
     <script src="http://www.baidu.com/api.php?callback=fuc"></script> 

  ajax在进行网站开发的过程中经常会用到第三方的数据,但是由于同源策略的限制导致ajax不能发送请求,因此也无法获得数据。

  解决ajax的跨域问题有两种方法:

  1. jsonp
  2. XMLHttpRequest2总可以配合服务端来解决,在响应头中加入Access-Control-Allow-Origin:*

6.分别讲下小括号,中括号,大括号,冒号在js中的作用

  1.   小括号:()用来定义或调用一个函数
  2. 中括号运算符:[]用来创建一个数组、获取数据元素
  3. 大括号运算符:{}用来创建对象
  4. 冒号运算符:冒号用来分隔对象的属性名和属性值

7.变量的作用域?

  在函数内部声明变量,则局部变量;在函数外部声明变量,则全局变量

8.几种基本数据类型?复杂数据类型?值类型和引用数据类型?堆栈数据结构?

  基本数据类型:undefined、null、Boolean、number、string

  值类型:number、Boolean、null、undefined

  引用类型:对象、数组、函数

  堆栈数据结构:是一种支持后进先出(LIFO)的集合,即后被插入的数据,先被取出

  js数组中提供一下几个方法可以让我们很方便实现堆栈:

  shift:从数组中把第一个元素删除,并返回这个元素的值。

  UNshift:在数组的开头添加一个或更多元素,并返回新的长度,

  push:在数组中末尾添加元素,并返回新的长度。

  pop:从数组中把最后一个元素删除,并返回这个元素的值。

9.判读数据类型?

  typeof返回的类型都是字符串形式,可以判断function的类型;在判断出Object类型的对象时比较方便。

  判断已知对象类型的方法:instanceof,后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支

10.简述ajax流程?

  1. 客户端产生js的时间
  2. 创建XMLHTTPRequest对象
  3. 对XMLHTTPRequest进行配置
  4. 通过ajax引擎发送异步请求
  5. 服务器端接收请求并且处理请求,返回html或者xml内容
  6. XML调用一个callback()处理响应回来的内容
  7. 页面局部刷新

基本步骤:
var xhr =null;//创建对象 
if(window.XMLHttpRequest){
       xhr = new XMLHttpRequest();
}else{
       xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open(“方式”,”地址”,”标志位”);//初始化请求 
   xhr.setRequestHeader(“”,””);//设置http头信息 
xhr.onreadystatechange =function(){}//指定回调函数 
xhr.send();//发送请求 

11.回调函数?

  回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是该函数的实现方式直接调用,而是在特定的时间或条件发生时由另外一个调用的,用于对该事件或条件进行相应。

12.什么是闭包?堆栈溢出有什么区别?内存泄漏?哪些操作会赵成内存泄漏?怎么样防止内存泄漏?

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

  堆栈溢出:就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了别的数据,经常会发生在递归中。

  内存泄漏:用动态存储分配数据内存空间,在使用完毕后未释放,导致一直占据该内存单元。直到程序结束。指任何对象在您不能再拥有或需要它之后仍然存在

  造成内存泄漏:

  setTimeout的第一个参数使用字符串而非函数的话,会引发内存泄漏

闭包、控制日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个玄幻)

防止内存泄漏

  1. 不要动态绑定事件;
  2. 不要在动态添加,或者会被动态溢出的dom上邦事件,用事件冒泡在父容器监听事件
  3. 如果要违反上面的原则,必须提供destory方法,保证移除don后事件也被移除,这点可以参考backbone的源代码,做的比较好
  4. 单列化,少创建dom,少邦事件

13.平时工作中怎么样进行数据交互?如果后天没有提供数据怎么样进行开发?mock数据与后台返回的格式不同怎么办?

  由后台编写接口文档、提供数据接口时、前台通过ajax访问实现数据交互;

  在没有数据的情况下寻找后台提供静态数据或者自定义mock数据;

  返回数据不统一时编写映射文件,对数据进行映射。

14.自执行函数?用于什么场景?好处?

  自执行函数:

  • 声明一个匿名函数;
  • 马上调用这个匿名函数

  作用:创建一个独立的作用域

  好处:防止变量弥散到全局,以免各种js库冲突。隔离作用域避免污染,或者截断作用域链,避免闭包造成引用变量无法释放。利用立即执行特性,返回需要的业务函数或对象,避免每次通过条件判断来处理

场景:一般用于框架、插件等场景

15.什么是构造函数?与普通函数有什么区别?

构造函数:是一种特殊的方法,主要用来创建对象时初始化对象,总与new运算符一起使用,创建对象的语句中构造函数名必须与类名完全相同。

与普通函数相比只能由new关键字调用,构造函数是类的表示

16.移动端上什么是点击穿透?

点击穿透现象:

  • 点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件跨页面点击穿透问题;
  • 如果按钮下面恰好有一个带有href属性a标签,那么页面就会发生跳转另一种跨页面点击穿透问题;
  • 没有mask,直接点击页内按钮跳转至新页,然后发现新页面中对应位置元素的click事件被触发了

解决方案:

  • 只用touch,把页面中所有click全部换成touch事件(touchstart,touchend,tap)
  • 只用click,下下策,因为会带来300ms延迟,页面内任何一个自定义交互都将增加300毫秒延迟
  • tap后延迟350毫秒再隐藏mask,改动最小,确定隐藏mask变慢了,350毫秒还是能感觉到慢
  • pointer-events,比较麻烦且有缺陷,不建议使用mask隐藏后,给按钮下面元素添上pointer-events:none;样式,让click穿过去,350ms后去掉这个样式,恢复响应缺陷是mask消失后的350ms内,用户可以看到按钮下面的元素点着没反应,如果用户手速很快的话一定会发现。

300ms延迟解决方案

  1. 禁用缩放,在html文档头部加meta标签如下:<meta name="viewport" content="user-scalable = no"/>
  2. 更改默认的视口宽度(响应式布局,消除了站点上可能存在的双击绽放的请求)<meta name="viewport" content="width=device-width"/>
  3. Css touch-action:none;在该元素上的操作不会触发用户代理的任何行为,无需进行3000ms延迟判断
  4. FastClick为解决移动端浏览器300毫秒延迟开发的一个轻量级的库

17.编写一个getElementByClassName封装函数?

<body>   
<input type="submit" id = "sub" class="ss confirm btn" value="提交"/>   
<script> window.onload = function(){ 
//方法一         
    var Opt = document.getElementById('sub');
    var getClass = function(className,tagName){
        if(document.getElementsByTagName){
            var Inp = document.getElementsByTagName(tagName);
            for(var i=0; i<Inp.length; i++){
                if((new RegExp('(\\s|^)' +className +'(\\s|$)')).test(Inp[i].className)){
                      return Inp[i];
                    }
                }
            }else if(document.getElementsByClassName){
                return document.getElementsByClassName(className);
        }
    }                 
//方法二
    var aa = getClass("confirm", "input");
        function getClass(className, targetName){
            var ele = [];
            var all = document.getElementsByTagName(targetName || "*");
            for(var i=0; i<all.length; i++){
                if(all[i].className.match(new RegExp('(\\s|^)'+confirm+'(\\s|$)'))){    
                    ele[ele.length] = all[i];
                }
            }
            return ele;
        }
//方法三
    function getObjsByClass(tagName, className){
           if(document.getElementsByClassName){
               alert("document.getElementsByClassName");
               return document.getElementsByClassName(className);
           }else{
               var el = [];
               var _el = document.getElementsByTagName(tagName);
               for(var i=0; i<_el.length; i++){
                   if(_el[i].className.indexOf(className) > -1){
                       alert(_el[i]);
                       el[_el.length] = _el[i];
                   }
               }
               alert(el);
               return el;
           }
       }
   }
 </script>
</body>

18.简述下工作流程

我在之前的公司工作流程大概是这样的:公司定稿会结束以后,会进行简单的技术研讨,然后我们前端会进行先期的技术准备。前端切图人员会进行psd设计稿切图,并且将css文件进行整合。我们主要编写JS部分,其中包括搭建前端框架(大项目),编写js业务和数据持久化操作,我们也会编写js插件并且进行封装方便使用,还有就是编写JS前端组建和JS测试单元,最后将完成的JS部分与切图人员提供的HTML页面进行整合。最后对完成的页面进行功能测试、页面兼容、产品还原。然后对产品进行封存,提交测试。如果出现BUG会返回给我们开发人员进行修改,再提交测试,最后测试成功,进行版本封存。等到程序全部上线的时候进行线上测试。

19.git和SVN的区别?

SVN是集中版本控制系统,版本库是几种放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽大,速度够快,如果在互联网下,如果网速慢的话,上传或下载速度就慢。

git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那么多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自修改推送给对方,就可以相互看到对方的修改了。

20.一般使用什么版本控制工具?SVN如何对文件加锁?

svn加锁目的:为了避免多个人同一时间对同一个文件改动的相互覆盖,版本控制系统就必须有一套冲突处理机制。

svn加锁两种策略:乐观加锁:所有签出的文件都是可读写的,对文件的修改不必获得文件的锁,当你修改完文件签入时,会首先要求你更新本地文件,版本控制系统不会覆盖你的本地修改,而是会让你自己合并冲突后签入。

严格加锁:所有签出的文件都是只读的,任何对文件的修改必须要获得文件的锁,如果其他人没有拥有该文件的锁,那么版本控制系统就会授权给你文件的锁,并将文件设置为可编辑的。

svn两种加锁步骤:乐观加锁:选择你想要获取锁定的文件,然后右键菜单点击TortoiseSVN 选取获取锁定。

严格加锁:在想要采取严格加锁的文件或目录上点击右键,使用TortoiseSVN 属性菜单,点击新建属性,选择
需要锁定。


21.jquery和zepto有什么区别?

1.针对移动端程序,Zepto有一些基本的触摸事件可以用来做触摸屏交互(tap事件、swipe事件),Zepto是不支持IE浏览器的,这不是Zepto的开发者Thomas Fucks在跨浏览器问题上犯了迷糊,而是经过了认真考虑后为了降低文件尺寸而做出的决定,就像jQuery的团队在2.0版中不再支持旧版的IE(6 7 8)一样。因为Zepto使用jQuery句法,所以它在文档中建议把jQuery作为IE上的后备库。那样程序仍能在IE中,而其他浏览器则能享受到Zepto在文件大小上的优势,然而它们两个的API不是完全兼容的,所以使用这种方法时一定要小心,并要做充分的测试。

2.Dom操作的区别:添加id时jQuery不会生效而Zepto会生效。

3.zepto主要用在移动设备上,只支持较新的浏览器,好处是代码量比较小,性能也较好。
jquery主要是兼容性好,可以跑在各种pc,移动上,好处是兼容各种浏览器,缺点是代码量大,同时考虑兼容,性能也不够好。

22. $(function(){})和window.onload 和 $(document).ready(function(){})?

window.onload:用于当页面的所有元素,包括外部引用文件,图片等都加载完毕时运行函数内的函数。load方法只能执行一次,如果在js文件里写了多个,只能执行最后一个。

$(document).ready(function(){})和$(function(){})都是用于当页面的标准DOM元素被解析成DOM树后就执行内部函数。这个函数是可以在js文件里多次编写的,对于多人共同编写的js就有很大的优势,因为所有行为函数都会执行到。而且$(document).ready()函数在HMTL结构加载完后就可以执行,不需要等大型文件加载或者不存在的连接等耗时工作完成才执行,效率高。

22.简述下this和定义属性和方法的时候有什么区别?prototype?

 this表示当前对象,如果在全局作用范围内使用this,则指当前页面对象window;若果函数中使用this,则this指根据此运行函数在什么对象上被调用。我们还可以使用apply和call两个全局方法来改变函数中this的具体指向。

prototype本质上还是一个JavaScript对象,并且每个函数都有一个默认的prototype属性。在prototype上定义的属性方法为所有实例共享,所有实例皆引用到同一个对象,单一实例对原型上的属性进行修改,也会影响到所有其他实例。

23.ajax和jsonp

相同点:都是请求一个url

不同点:ajax的核心是通过XMLHTTPRequest获取内容

jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本

24.readystate0-4

0:未初始化状态:此时,已经创建了一个XMLHttpRequest对象
1: 准备发送状态:此时,已经调用了XMLHttpRequest对象的open方法,并且XMLHttpRequest对象已经准备好将一个请求发送到服务器端
2:已经发送状态:此时,已经通过send方法把一个请求发送到服务器端,但是还没有收到一个响应
3:正在接收状态:此时,已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收到
4:完成响应状态:此时,已经完成了HTTP响应的接收

25.说出http协议状态码?

  200:请求成功

  201:请求成功并且服务器创建了新的资源

  204:请求处理成功,但没有资源可以返回;

  206:对资源某一部分进行请求(比如对于只加载了一半的图片剩余部分的请求)

  301:永久性重定向;

  302:临时性重定向。

  304:服务器判断本地缓存未更新,可以直接使用本地缓存

  307:临时重定向

  400:请求报文存在语法错误

  401:请求需要通过HTTP认证;

  403:请求资源被服务器拒绝,访问权限的问题;

  404:请求的资源不存在

  500:内部服务器错误;

  502:网络超时;

  503:服务器超载或正在维护,无法处理请求

  504:网关超时;

26.ajax中get和post的区别?

  都是数据提交方式。

  get的数据是通过网站问号后边拼接的字符串进行传递的。post是通过一个HTTP包体进行传递数据。

  get传输量是有限制的,post没有限制

  get的安全性没有post高,所以我们一般用get来获取数据,post一般用来修改数据。

27.简述下你理解的面向对象?

  万物皆对象,把一个对象抽象成类,具体上就是把一个对象的静态特性和动态特性抽象成属性和方法,也就是把一类事物的算法和数据结构封装在一个类之中,程序就是多个对象和互相之间通信组成的。

  面向对象具有封装性、继承性、多态性

  封装:隐蔽了对象内部不需要暴露的细节,使得内部细节的变动跟外界脱离,只依靠接口进行通信。封装性降低了编程的复杂性,通过继承,使得新建一个类变得容易,一个类从派生类那里获得其非私有的方法和公用属性的繁琐工作交给了编译器,而继承和实现接口和运行时的类型绑定机制所产生的多态,使得不同的类所产生的对象能够对相同的消息作出不同的反应,极大地提高了代码的通用性。

  总之,面向对象的特性提高了大型程序的重用性和可维护性。

28.this是什么?在不同场景中分别代表什么?

  1.   function a(){this ?}   this -> window;
  2. function b(){ return function(){ this? }} b()()   this->window
  3. function c(){ return {s:function(){this}}} c().s();  this -> object 就是s:f()

  由于其运行期绑定的特性,JavaScript中的this含义要丰富得多,它可以是全局对象、当前对象或者任意对象、这完全取决于函数的调用方式。

29.如何对登录的账号密码进行加密?

  MD5

30.除了jsonp还有什么跨域方式?如何解决跨域问题?

  JavaScript跨域有两种情况:

  1. 基于同一父域的子域之间,如a.c.com和b.c.com
  2. 基于不同的父域之间,如a.com和b.com
  3. 端口的不同,如a.com:80和a.com:81
  4. 协议不同,如http://a.com和https://a.com

  对于情况3和4,需要通过后台proxy来解决,具体方式如下:

  • 在发起方的域下创建proxy程序
  • 发起方的js调用本域下的proxy程序
  • proxy将请求发送给接受方并获取相应的数据
  • proxy将获得的数据返回给发起方的js

  代码和ajax调用一致,其实这种方式就是通过ajax进行调用的,而情况1和2除了通过后台proxy这种方式外,还可以有多种办法来解决:

  1. document.domain+iframe(只能解决情况1)
  2. 在发起方页面和接受页面设置document.domain,并将值设为父域的主域名(window.location.hostname)
  3. 在发起方页面创建一个隐藏的iframe,iframe的源是接受方页面
  4. 根据浏览器的不用,通过iframe.contentDocument || iframe.contentWindow.docuemnt来获得接受页面的内容
  5. 通过获得的接收页面的内容与接收方进行交互。

  这种方法有个缺点,就是当一个域被攻击时,另一个域会有安全漏洞出现。

  jsonp,iframe, window.name, window.postMessage, 服务器上设置代理页面

31.如何使用storage对js文件进行缓存?

  由于sessionStorage针对一个session的数据存储,所以我们一般利用localStorage存储js文件,只有在第一次访问该页面的时候加载js文件,以后在访问的时候加载本地localStorage执行

32.split,join,slice,splice?

  split:切割成数组的形式

  join:将数组转换成字符串

  slice:从已有的数组中返回选定的元素

  splice:从数组中添加、删除项目,然后返回被删除的项目

33.disable readonly?

  readonly只针对input(text/password)和textarea有效,而disabled对于所有的表单元素都有效,当表单元素在使用了disabled后,当我们将表单以post和get的方式提交的话,这个元素的值不会被传递出去,而readonly会被该值传递出去。

34.同步?异步?

  1.进程同步sync:就是在发出一个功能调用时,在没有得到结果之前,该电泳就不反悔,也就是必须一件一件事做,等签意见做完了才能做下一件事。代码依次执行
  2.异步的概念和同步相对的async。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的不见在完成后,通过状态、通知和回调来通知调用者。代码执行不按顺序,‘跳过’执行。

35.promise?

  promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve、reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。

36.函数fn1 函数fn2 函数fn3,如果想在三个函数都执行完成后执行某一个事件应该如何实现?

37.JavaScript提供了哪几种“异步模式”?

  1. 回调函数(callback)
  2. 事件监听
  3. promise对象

38.call&apply两者之间的区别?有什么好处?

  call和apply都是改变this指向的方法,区别在于call可以写多个参数,而apply只能写两个参数,第二个参数是一个数组,用于存放要传的参数。用call和apply:实现更好的继承和扩展,更安全。

39.谁是c的构造函数?

function ab(){
  this.say = '';
}
ab.constructor = {} a.name= '';
var c = new ab();

  构造函数默认指向函数本身,ab是一个类,它的构造函数是它本身。

  然后ab.constructor = {};ab的构造函数就指向{},c是ab的实例化对象,c的构造函数就是{}

  通过使用new的时候,创建对象发生了哪些改变?当使用new操作时,会马上开辟一个块内存

  创建一个空对象,并将this指向这个对象。接着,执行构造函数ab(),对这个空对象进行构造。(构造函数里面有什么属性和方法都一一给这个空白对象装配上去,这就是为何叫构造函数了)

40.sass 和less有什么区别?

  1. 编译环境不一样,sass的安装需要ruby环境,是在服务端处理的,而less是需要引入less.js来处理less代码输出css到浏览器,也可以在开发环节使用less,然后编译成css文件,直接放到项目中。
  2. 变量符不同,less使用@ 而sass使用$,他们的作用域不同,less是块级作用域
  3. 输出设置,Less没有输出设置,sass提供4种输出选项,nested,compact,compressed和expanded nested:嵌套缩进的css代码(默认) expanded:展开的多行css代码 compact:简洁格式的css代码 compressed:压缩后的css代码
  4. sass支持条件语句,可以使用if{}else{},for{}循环等等,而less不行
  5. 引用外部css文件,sass引用外部文件必须以_开头,文件名如果以下划线_形状,sass会认为该文件是一个引用文件,不会将其编译为css文件。less引用外部文件和css中的@import没什么差异
  6. sass和less的工具库不同。sass有工具库Compass, 简单说,sass和Compass的关系有点像Javascript和jQuery的关系,Compass是sass的工具库。在它的基础上,封装了一系列有用的模块和模板,补充强化了sass的功能。less有UI组件库Bootstrap,Bootstrap是web前端开发中一个比较有名的前端UI组件库,Bootstrap的样式文件部分源码就是采用less语法编写。

    总结:不管是sass,还是less,都可以视为一种基于CSS之上的高级语言,其目的是使得CSS开发更灵活和更强大,sass的功能比less强大,基本可以说是一种真正的编程语言了,less则相对清晰明了,易于上手,对编译环境要求比较宽松。考虑到编译sass要安装Ruby,而Ruby官网在国内访问不了,个人在实际开发中更倾向于选择less。

41.开发时如何对项目进行管理?gulp?

  本人开发时,利用gulp等前端工作流管理工具管理项目。gulp是新一代的前端项目构建工具,你可以使用gulp及其插件对你的项目代码(less/sass)进行编译,还可以压缩你的js和css代码,甚至压缩你的图片,能够合并文件,压缩文件,语法检查,监听文件变化,测试,转换二进制,转化图片等一系列功能。gulp仅有少量的API

42.压缩合并目的?http请求的优化方式?

  web性能优化最佳实践中最重要的一条是减少http请求,而减少http请求的最主要的方式就是,合并并压缩JavaScript和css文件。

  css sprite(css精灵图):把全站的图标都放在一个图像文件中,然后用css的background-image和background-position属性定位来显示其中的一小部分。

  合并js和css

  图片、js、css等静态资源放在静态服务器或CDN托管,尽量采用不用的域名,这样能防止cookie不会互相污染,减少每次请求的往返数据

  css替代图片,缓存一些数据

  少用location.reload();使用location.reload()会刷新页面,刷新页面所有资源(css、js、img等)会重新请求服务器。建议使用location.href = '当前页url‘替代location.reload(),使用location.href浏览器会读取本地缓存资源

43.ajax请求凡是有几种(8种)?

  1. $.get(url,[data],[callback])
  2. $.getJSON(url,[data],[callback])
  3. $.post(url,[data],[callback],[type])
  4. $.ajax(option)
  5. $.getScript(url,[callback])
  6. jquery对象.load(url,[data],[callback])
  7. serialize()与serializeArray()

44.如何copy一个dom元素?

  原生js方法:var div = document.getElementsByTagName('div')[0]; var clone = dive.cloneNode();

  jquery方法:$('div').clone();

  在默认情况下,.clone()方法不会复制匹配的元素或其后代元素中绑定的事件。不过,可以诶这个方法传递一个布尔值参数,将这个参数设置为true,就可以连同事件一起复制,即.clone(true)

45.如何创建一个对象?

  1.  工厂模式
  2. 构造函数模式
  3. 原型模式
  4. 混合构造函数和原型模式
  5. 动态原型模式
  6. 寄生构造函数模式
  7. 稳妥构造函数模式

 46.commonjs?requirejs?AMD|CMD|UMD?

  1. commonjs就是js的表现来指定规范,nodejs是这种规范的实现,webpack也是以commonjs的形式来书写。因为js没有模块的功能,所以commonjs应运而生。但它不能在浏览器中运行。commonjs定义的模块分为reqiure(模块定义)、exports(模块定义)module(模块标识)
  2. RequireJS 是一个JavaScript模块加载器。 RequireJS有两个主要方法(method): define()和require()。这两个方法基本上拥有相同的定义(declaration) 并且它们都知道如何加载的依赖关系,然后执行一个回调函数(callback function)。与require()不同的是, define()用来存储代码作为一个已命名的模块。 因此define()的回调函数需要有一个返回值作为这个模块定义。这些类似被定义的模块叫作AMD (Asynchronous Module Definition,异步模块定义)。
  3. AMD是require.js在推广过程中对模块定义的规范化产出AMD异步加载模块
  4. CMD是Seajs在推广过程中对模块定义的规范化,AMD与CDM的区别:
    (1)对于于依赖的模块,AMD 是提前执行(好像现在也可以延迟执行了),CMD 是延迟执行。
    (2)AMD 推崇依赖前置,CMD 推崇依赖就近。
    (3)AMD 推崇复用接口,CMD 推崇单用接口。
    (4)书写规范的差异。
  5. umd是AMD和CommonJS的糅合。
    AMD 浏览器第一的原则发展 异步加载模块。
    CommonJS模块以服务器第一原则发展,选择同步加载,它的模块无需包装(unwrapped modules)。这迫使人们又想出另一个更通用的模式UMD ( Universal Module Definition ), 希望解决跨平台的解决方案。UMD先判断是否支持Node.js的模块( exports )是否存在,存在则使用Node.js模块模式。

47.js的几种继承方式?

  1. 使用对象冒充实现继承
  2. 采用call, apply方法改变函数上下文实现继承
  3. 原型链方式继承

48.JavaScript原型,原型链?有什么特点?

  在JavaScript中,一共有两种类型的值,原始值和对象值,每个对象都有一个内部属性【prototype】,我们通常称之为原型,原型的值可以是一个对象,也可以是null。如果它的值是一个对象,则这个对象也一定有自己的原型,这样就形成一条线性的链,我们称之为原型链

  访问一个对象的原型可以使用ES5中的Object.getPrototype方法,或者es6中的_proto_属性,原型链的作用是用来实现继承,比如我们新建一个数组,数组的方法就是从数组的原型上继承而来的。

49.eval是做什么的?

  eval的功能是对应的字符串解析成js代码并运行,应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。

50.null,undefined的区别?

  undefined表示变量声明但未初始化的值,null表示准备用来保存对象,还没有真正保存对象的值。从逻辑角度看,null表示一个空对象指针。

51.json的了解?

  json(JavaScript Object Notation)是一种轻量级的数据交换格式。它是基于JavaScript的一个自己。数据格式简单,易于读写,占用带宽小

52.js延迟加载的方式有哪些?

  defer和async、动态创建DOM方式(用的最多)、按需异步加载js

53.ajax是什么?ajax的缺点?

  异步JavaScript和XML,是指一种创建交互式网页应用的网页开发技术。通过后台与服务器进行少量数据交互,ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

  缺点:

  1. ajax不支持浏览器back按钮
  2. 安全问题暴露了与服务器交互的细节
  3. 对搜索引擎的支持比较弱
  4. 破坏了程序的异常机制
  5. 不容易调试

54.异步记载的方式有哪些?

  1. defer,只支持IE
  2. async:true
  3. 创建script,插入DOM中,加载完毕后callback

55.jquery和jquery UI区别?

  jquery是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等。

  jquery UI则是在jquery的基础上,利用jquery的扩展性,设计的插件。提供了一些蝉蛹界面元素,诸如对话框、拖动行为、改变大小行为等等。

56.有哪些性能优化的方法?

  1. 减少http请求次数:css sprite,js、css源码压缩、图片大小控制合适;网页gzip,CDN托管,data换粗,图片服务器
  2. 前端模板js+数据,减少由于HTML标签导致的带宽浪费,前端用遍历保存ajax请求结果,每次操作本地变量,不用请求,减少请求次数
  3. 用innerHTML代替DOM操作,减少DOM操作次数,优化JavaScript性能
  4. 当需要设置的样式很多时设置className而不是直接操作style
  5. 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
  6. 避免使用css expression(css表达式)又成Dynamic properties(动态属性)。
  7. 图片预加载,将样式表放在顶部,将脚本放在底部,加上时间戳
  8. 避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示div+css布局慢

57.一个页面从输入url到页面加载显示完成,这个过程中都发生了什么?

  1. 查找浏览器缓存
  2. DNS解析、查找该域名对应IP地址、重定向(301)、发出第二个GET请求
  3. 进行HTTP协议会话
  4. 客户端发送报头(请求报头)
  5. 服务器回馈报头(响应报头)
  6. html文档开始下载
  7. 文档树简历,根据标记所需指定MIME类型的文件
  8. 文件显示

浏览器这边做的工作大致分为以下几步:

加载:根据请求的url进行域名解析,像服务器发起请求,接收文件(html、css、js、图片)

解析:对加载到的资源(html、js、css等)进行语法解析,建议相应的内部数据结构(比如HTML的DOM树,js的对象属性表,css的样式规则等等)



58.vue与react区别?

  相同点:

  都是JavaScript框架,有路由、状态管理、构建工具等、组件式开发,都用到了虚拟DOM,虚拟DOM是一个映射真是DOM的JavaScript对象,如果需要改变任何元素的状态,则现在虚拟DOM上改变,而不是直接改变真实的DOM。当有变化产生时,一个新的虚拟节点便会被创建,同时计算新旧虚拟结点之间的差别,最后映射真是的DOM节点

  不同点:

  vue react
框架类型

mvvm

mvc
构建工具 vue-cli creat-react-app
编写方式  模板  JSX
状态管理 vuex redux
移动端 weex  react native

  MVC:Model(模型)+View(视图)+controller(控制器),主要是基于分层的目的,让彼此的职责分开。view通过controller来和model联系,controller是view和model的协调者,view和model不直接联系,基本联系都是单向的。用户user通过控制器controller来操作模板model从而达到视图view的变化。

  MVVM:

MVVM是把MVC里的Controller和MVP里的Presenter改成了ViewModel。Model+View+ViewModel。

View的变化会自动更新到ViewModel,ViewModel的变化也会自动同步到View上显示。

这种自动同步是因为ViewModel中的属性实现了Observer,当属性变更时都能触发对应的操作。

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

vue的特性:

  • 轻量级的框架
  • 双向数据绑定
  • 指令
  • 插件化

 vue与angular的区别?

  相同点:

  • 都支持指令,内置指令和自定义指令
  • 都支持过滤器,内置过滤器和自定义过滤器
  • 都支持双向数据绑定
  • 都不支持低端浏览器

不同点:

  • angular的学习成本高,比如增加了Dependecy Injection,而Vue.js本身提供的API比较简单、直观
  • 在性能上,angular依赖对数据做脏检查,所以watcher越多越慢
  • vue使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的

vue和react的区别?

  相同点:

  • react采用特殊的JSX语法,vue在组件开发中推崇vue特殊文件格式,对文件内容有一些约定,两者都需要编译后使用
  • 中心思想相同,一切都是组件,组件实例之间可以嵌套
  • 都提供合理的钩子函数,可以让开发者定制化地区处理需求
  • 都不内置列数ajax,route等功能到核心包,而是以插件的方式加载
  • 在组件开发中都支持mixins的特性

    

  vue和react的相同点:

  1. 数据驱动视图,提供响应式的视图组件
  2. 都有virtual DOM,组件化开发,通过props参数进行父子组件数据的传递,都实现webComponent规范
  3. 数据流动单向
  4. 都支持服务器渲染
  5. 都有支持native的方案,react的react native,vue的weex

  vue和react不同点:

  1. 社区:react社区还是要比vue大很多
  2. 开发模式:react在view层侵入性要比vue的大的多,react严格上只针对MVC的view层,vue则是MVVM模式的一种实现
  3. 数据绑定:vue有实现数据双向绑定,react数据流动是单向的
  4. 数据渲染:对于大规模数据渲染,react要比vue的多,渲染机制启动时做的工作比较多
  5. 数据更新方面:vue由于采用依赖追踪,默认就是优化状态;你动了多少数据,就出发多少更新,不多也不少。react在复杂的应用了里面有两个选择:(1)手动添加shouldComponentUpdate来避免不需要的v dom re-render;(2)可能都用pureRenderMixin,然后采用redux结构+immutable.js.
  6. 开发风格的偏好:react推荐的做法是jsx+inline style,也就是把HTML的css全都写进JavaScript了,即“all in js“;vue进阶之后推荐的是webpack+vue-loader的单文件组件格式,即html,css,js写在同一个文件
  7. 使用场景:react配合redux架构适合超大规模多人协作的复杂项目;vue则适合小快灵的项目。对于需要对DOM进行很多自定义操作的项目,vue的灵活性由于react;

  不同点:

     React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查。

Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作DOM。


59.vue.js是什么?MVC、MVP、MVVM的区别?

  • vue是一个MVVM框架,和angular类似,相比angular小巧,比较容易上手;
  • vue是一个构建用户界面的渐进式框架,与其它重量级框架不同的是,vue采用自低向上增量开发的设计
  • vue的核心库“只关注视图层”,并且“非常容易学习”,非常容易与其它库或者已有的项目整合,另一方面,vue完全有能力驱动采用单文件和vue生态系统支持的库开发的复杂单页应用
  • vue的目标是通过尽可能简单的API实现“响应的数据绑定”和“组合的视图组件”

  MVC(视图view:用户界面,控制器controller:业务逻辑,模型model:数据处理)

  MVP是从经典的模式MVC演变而来,他们的基本思想有相通的地方:controller、presenter负责逻辑的处理,model提供数据,view负责显示。作为一种新的模式,MVP与MVC有着重大的区别:在MVP中view并不直接使用model,他们之间的通信是通过presenter(MVC中的controller)来进行的,所有的交互都发生在presenter内部,而MVC中view会从直接model中读取数据而不是通过controller。

  MVVM在概念上是真正将页面与数据逻辑分离的模式,在开发方式上,它是真正将前台代码开发者(js+html)与后台代码开发者分离的模式(asp,.net, php, .jsp)。双向绑定,view变动,自动反映在viewmodel,反之亦然。




60.vue组件之间通信?

  一、vue父子组件通信

   1.vue父子组件通信可以用vue.$emit发送消息,$on接受消息

//父组件
<single-address @edit-address="editAddress"></single-address> 
//子组件
methods:{
  editAddress(){
    this.$emit('edit-address',false)
  }
}

  2.也可以通过prop方式解决

//父组件
<one-address :addressitems="addressitems"></one-address>
//子组件
<div>{{addressitem.partment}}</div>

export default{
  props:{
    addressitems:Object
  }
}

  3.子组件$dispatch()派发事件传递给父组件,父组件$broadcast()广播事件传递给子组件,这种方式虽然减号了props的时候,但是需要额外定义几个事件,状态多了就会变得很复杂。

  二、非父子组件通信

  非父子组件通信同样也可以用$emit和$on来解决

var bus = new Vue()
//组件A
bus.$emit('id-selected',1)

//组件B
bus.$on('id-selected',function(id){
  console.log(id)
}

三、vue跨组件模块通信

  使用vuex状态管理器,state和getters主要是用于数据的存储与输出,而mutations和actions是用于提交事件并修改state中的数据。状态统一放store管理,修改状态通过mutations,组件action吊桶mutaitions,


61.es6有哪些更新?

 1.let命令

  • let和var的区别:let声明的变量只有所在的代码块有效
  • 没有变量的提升,一定要声明后使用。使用let命令声明变量之前,改变量都是不可用的,形成“暂时性死区”。
  • typeof不再是一个百分之百安全的操作

2.块级作用域

  • es5和es6比较:es5只有全局作用域和函数作用域,没有块级作用域
  • let实际上为JavaScript新增了块级作用域
  • es6允许块级作用域的任意嵌套
  • es5规定函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明,严格模式下会报错,为es5和es6环境避免报错,应不要在块级作用域里面声明函数

 3.const命令

  • const声明一个只读的常量。一旦声明,常量的值就不能改变。const一旦声明变量,就必须立即初始胡,不能留到以后赋值
  • 其他特性和let类似
  • 对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心。
const foo = {}
foo.prop = 123;
foo.props
foo ={}
//常量foo存储的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性

  es5只有两种声明变量的方法:var命令和function命令。es6除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法,import命令和class命令,所以es6一共有6中声明变量的方法。

  4.顶层对象的属性

  顶层对象,在浏览器环境指的是window对象,在node指的是global对象。es6规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性,也就是说,从es6开始,全局变量将逐步与顶层对象的属性脱钩。

var a = 1;//如果在node的REPL环境,可以写成global.a,或者采用通用方式,写成this.a
window.a //1

let b = 1;
window.b //undefined

  5.解构赋值

let [a,b,c] = [1,2,3]
let {x1,x2} = {x2:5,x1:6}
const [a,b,c,d,e] = 'hello'
function add([i,j]){}  add([5,6])

  模式匹配

  6.字符串

  Unicode表示法

"\u{码点}"
"\u{41}\u{42}\u{43}"                 //"ABC"

  7.模板字符串

    模板字符串采用反引号(`)标识,并且模板字符串中的空格、换行将在输出时有所保留

// 普通字符串
`In JavaScript '\n' is a line-feed.`

// 多行字符串
`In JavaScript this is
 not legal.`

console.log(`string text line 1
string text line 2`);

//字符串中嵌入变量
let name = 'Bob' ,time = 'today';
`Hello ${name},how are you &{time}?`

${主体},其中主体可以是表达式、运算、对象属性还可以是函数,若是字符串将直接输出该字符串

  8.函数function

function show(name="jack",sex="boy"){
  console.log(name+" is a "+sex + "!");
}
show() //jack is a boy
show("judy") //judy is a boy
show('judy','girl') //judy is a girl

  为函数的参数添加默认值,执行函数时如果不传该参数,那么就用默认值代替。

  箭头函数:

  var 变量名、函数名 = (参数,参数) => {代码块}

var f = v => v;
//等同于
var f = function(v){
  return v;
}

var f = () => 5
var f = function() { return 5}

var sum = (num1,num2) =>  num1+num2;
//等同于
var sum = function(num1,num2){
  return num1+num2
}

注意:如果return的是一个对象{id:id,age:age},那么箭头右边要用括号报起来()

  9.数字拓展

  和字符串对象类似,es6也为数值类对象例如number、Math添加了新的方法以及属性(常量)

10.数组的扩展

  扩展运算符为三个点(...),将一个数组转化为参数序列,通常与函数一起使用,show(...['judy','girl'])

  数组合并[...arr1,...arr2,...arr3]

字符串转字符数组:[...'hello'] -------['h','e','l','l','o']

  将实现iterator接口的对象转化为真正的数组:[...nodelist],这里的nodeist是一个类似于数组的nodelist对象

  generator函数:该函数执行后返回一个遍历器对象,扩展运算符也可将其转化为数组。

  

let a = function(){
  yield 3;
  yield 4;
  yield 5;
  return 6;
}
console.log([...a()]) ;//3,4,5

  62.什么是模块化、组件化?两者的区别?

  模块化中模块一般指的是JavaScript模块,比如一个用来格式化时间的模块。按照项目业务内容来划分模块,模块是抽象的,

  组件 则包含了template/style和script,而它的script可以由各种模块组成。比如一个现实时间的组件会调用上面的那个格式化时间的模块。按照一些小功能的通用性和可复用性来抽象组件

  一般来说,模块是由很多很小组件组成的。虽然两者侧重点不同,但是从包含关系上讲,组件是模块的子集。

@张云龙 画的一张图完美地解释了他们之间的关系;


63.请详细说下你对vue生命周期的理解?

答:总共8个阶段:创建前后,载入前后,更新前后,销毁前后

创建前后:在beforeCreated阶段,vue实例的挂载元素$el和数据对象data都为undefined,还未初始化,在created阶段,vue实例的数据对象data有了,$el还没有。

载入前后:在beforeMounted阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未被替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。

更新前后:当data变化时,会触发beforeUpdata和updated方法

销毁前后:当执行的destory方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。

64.请谈谈vue中的MVVM模式

  MVVM全程是model-view-viewmodel

  vue是以数据为驱动的,vue自身将dom和数据进行绑定,一旦创建绑定,DOM和数据将保持同步,每当数据发生变化,DOM会跟着变化。viewModel是vue的核心,它是vue的一个实例。vue实例时作用域某个HTML元素上的这个HTML元素可以是body,也可以是某个id所指代的元素。

  DOMListener和DataBinding是实现双向绑定的关键。DOMListener监听页面所有view层DOM元素的变化,当发生变化,model层的数据随之变化;DataBinding监听model层的数据,当数据发生变化,vue层的domg元素随着变化

65.v-show和v-if指令的共同点和不同点?

  v-show指令是通过修改元素的display的css属性让其显示或者隐藏

  v-if指令是直接消耗和重建DOM达到让元素显示和隐藏的效果

66.如何让css只在当前组件中起作用?

  将当前组件的<style>修改为<style scoped>

67.指令v-el的作用是什么?

  提供一个在页面上已存在的DOM元素作为vue实例的挂载目标,可以是css选择器,也可以是一个HTMLElement实例

68.<keep-alive></keep-alive>的作用是什么?

  <keep-alive></keep-alive>包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。比如:有一个列表和一个详情页,那么用户就会经常执行打开详情 -> 返回列表 -> 打开详情 。。。这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用<keep-alive></keep-alive>进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染。

69.vue中引入组件的步骤?

  1.采用ES6的import...from ...语法或Commonjs的reqiure()方法引入组件

  2.对组件进行注册,代码如下

//注册
Vue.component('my-component', {
  template:'<div> A custom component</div>'
})

  3.使用组件<my-component></my-component>

70.在vue中使用插件的步骤?

  1.采用ES6的import...from 或commonjs的require()方法引入组件

  2.使用全局方法Vue.use(plugin)使用插件,可以传入一个选项 对象Vue.use(Myplugin,{someOption:true)

71.请列举出3个Vue中常用的生命周期钩子函数?

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

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

  3.activated:keep-alive组件激活时调用

72.请简述vuex的原理和使用方法


数据单向流动

  一个应用可以看做是由上面三部分组成:view、actions、state,数据的流动也是从view -> actions ->state -> view 以此达到数据的当向流动,但是项目比较大的,组件嵌套过多的时候,多组件共享同一个state会在数据传递时出现很多问题vuex就是为了解决这些问题而产生的。

  vuex可以被看作项目中所有组件的数据中心,我们将组件中共享state抽离出来,任何组件都可以访问和操作我们的数据中心。



  上面可以很好的说明vuex的组成,一个实例化的vuex,store由state、mutations、actions三个属性组成:

  • state中保存着共有数据
  • 改变state中的数据有且只有通过mutations中方法,且mutations中方法必须是同步
  • 如果要写异步的方法,需要些在actions中,并通过commit到mutations中进行state中数据的更改

73.active-class是哪个组件的属性?嵌套路由怎么定义?

  vue-router模块和router-link组件

  在实际项目中我们会碰到多层嵌套的组件组合而成,但是我们如何实现嵌套路由呢?因此我们需要在VueRouter的参数中使用children配置,这样就可以很好的实现路由嵌套。

  index.html,只有一个路由出口

<div id="app">
  <!--router-view路由出口,路由匹配到的组件将渲染在这里->
  <router-view></router-view>
</div>

main.js,路由的重定向,就会在页面一加载的时候,就会将home组件显示出来,因为重定向指向了home组件,redirect的指向与path的必须一致。children里面是子路由,当然子路由里面还可以继续嵌套子路由。

import Vue from 'vue';
import VueRouter from 'vue-router';

//引入两个组件

import home from './home.vue';
import game from './game.vue';

//定义路由
const routes = [
    { path:'',redirect:'/home'}, //重定向,指向了home组件
    { path:'/home',component:home, children:[
        { path:'/home/game',component:game }
    ]}
]

//创建路由实例
new Vue({
	el:'#app',
	data:{

	},
	methods:{

	},
	router
})

home.vue 点击显示就会在子路由显示出来,子路由的出口必须在父路由里面,否则子路由由无法显示。

<template>
	<div>
		<h3>首页</h3>
		<router-link to="/home/game">
			<button>显示</button>
		<router-link>
		<router-view></router-view>
	</div>
</template>

game.vue

<template>
  <h3>游戏</h3>
</template>

74.怎么定义vue-router的动态路由?怎么获取传过来的动态参数?

  在router目录下的index.js文件下,对path属性就上/:id

  使用router对象的params.id

75.vue-router有哪几种导航钩子?

  三,

  • 全局导航钩子,router.beforeEach(to,from,next),作用:跳转前进行判断拦截
  • 组件内的钩子
  • 单独路由独享钩子

76.scss是什么?在vue-cli中的安装使用步骤是?有哪几大特性?

  css的预编译

  使用步骤:

  1. 用npm下三个loader(sass-loader, css-loader, node-sass)
  2. 在build目录找到webpack.base.config.js, 在那个extend是属性中加上一个扩展.scss
  3. 还是在同一个文件,配置一个module属性
  4. 然后在组件的style标签上加上lang属性,例如: lang ="scss"

  有哪几大特性:

  1. 可以用变量符不用,sass是$,less是@
  2. 可以用混合器
  3. 可以嵌套

77.mint-ui是什么?怎么使用?说出至少三个组件使用方法?

  基于vue的前端组件库。npm安装,然后import样式和js,vue.use(mintUi)全局引入。在单个组件局部引入:import {Toast} from 'mint-ui';

  •   Toast('登录成功')
  • mint-header
  • mint-swiper

78.v-model是什么?怎么使用?vue中标签怎么绑定事件?

  可以实现双向绑定,指令(v-class,v-for,v-if,v-show,v-on)。vue的model层的data属性。绑定事件<input @click=dolog()/>

79.iframe的优缺点?

  iframe也称作嵌入式框架,嵌入式框架和框架网页类似,它可以把一个网页的框架和内容嵌入在现有的网页中。

  优点:

  1. 解决加载缓慢的第三方内容如图标和广告等加载问题
  2. security sandbox
  3. 并行加载脚本
  4. 方便制作导航栏

  缺点:

  1. iframe会阻塞主页面的onload事件
  2. 即使内容为空,加载也需要时间
  3. 没有语意

80.简述一下sass、less,且说明区别?

  他们都是动态样式语言,是css预处理器,css上的一种抽象层。他们是一种特殊的语法/语言而编译成css

   不同点:

  • 变量符不同,less是@,sass是$
  • sass支持条件语句,可以使用if{}else{},for()循环等等,而less不支持
  • sass是基于ruby的,是在服务器处理的,而less是需要引入less.js来处理less代码输出css到浏览器

81.axios是什么?怎么使用?描述使用它实现登录功能的流程?

  请求后台资源的模块,npm install axios -s 装好,然后发送的是跨域,需在配置文件中config/index.js进行配置。后台如果是TP5则定义一个资源路由。js中使用import进来,然后.get或.post。返回在.then函数中如果成功,失败则是在.catch函数中

82.axios+tp5进阶红,调用axios.post('api/user')是进行的什么操作?axios.put('api/user/8')呢?

  跨域,添加用户操作,更新操作

83.vuex是什么?怎么使用?哪种功能场景使用它?

  vue框架中状态管理。在main.js引入store,注入。新建一个目录store,...,export。场景哟:单页应用中,组件之间的状态。音乐状态、登录状态、加入购物车

84.MVVM框架是什么?它和其他框架(jquery)的区别是什么?哪些场景适合?

  一个model+view+viewModel框架,数据模型model,viewModel连接两个

  区别:vue数据驱动,通过数据来显示视图层而不是节点操作

  场景:数据操作比较多的场景,更加便捷

85.自定义指令(v-check, v-focus)的方法有哪些?它有哪些钩子函数?还有那些钩子函数参数?

  全局定义指令:在vue对象的direcative方法里面有两个参数,一个是指定名称,另外一个是函数。组件内定义指令:directives

  钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更新)

  钩子函数参数:el、binding

86.说出至少4种vue当中的指令和它的用法?

  v-if:判断是否隐藏;

  v-for:数据循环出来

  v-bind:class 绑定一个属性;

  v-model:实现双向绑定

87.vue-router是什么?它有哪些组件?

  vue用来写路由一个插件。router-link、router-view

88.导航钩子有哪些?它们有哪些参数?

  导航钩子:a/全局钩子和组件内独享的钩子。b/beforeRouteEnter、afterEnter、beforeRouterUpdate、beforeRouteLeave

  参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,如果不能就拦截)。

89.vue的双向数据绑定原理是什么?

  vue.js是才用数据劫持结合发布者-订阅模式的方式,通过Object.defineProperty()来劫持各个属性的setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

  具体步骤:

  1. 需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和get特然这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
  2. complie解析模块指令,将模板中的变量替换成数据,然后初初始化,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。
  3. watcher订阅者是observer和compile之间的通信的桥梁,主要做的事情是:

       1)在自身实例化时往属性订阅器里面添加自己

       2)自身必须有一个update()方法

       3)待属性变动dep.notice()通知,能调用自身的update()方法,并触发compile中绑定的回调,则攻成身退

     4.MVVM作为数据绑定的入口,整合observer、compile和watcher三者,通过observer来监听自己的model数据的变化,通过compile来解析编译模板指令,最终利用watcher搭起observer和compiler之间的通信桥梁,达到数据变化->视图更新;视图交互变化 -> 数据model变更的双向绑定效果

90.请说下封装vue组件的过程?

  首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。

  然后,使用vue.extend方法创建一个组件,然后使用vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。

91.vue-loader是什么?使用它的用途有哪些?

  解析.vue文件的一个加载器,跟template、js、style转换成js模块

  用途:js可以写成es6、style样式可以scss或less、template可以加jade等

92.gulp和webpack区别?

  •   gulp是一种工具,我们可以用它来优化前端的工作流程,比如自动刷新页面、combo、压缩css、js、编译less等等。具体体现为:在gulp的配置文件中书写一个个的task,webpack则是一种打包工具,或者说是一种模块化解决方案,实际上很大一部分人刚开始使用webpack的方式就是通过gulp-webpack这个插件,写好task来使用webpack对前端的一些文件进行打包
  • gulp的处理任务需要自己去写,webpack则有现成的解决方案,只需要在webpack.config.js配置好即可

93.JavaScript中如何检测一个变量是一个string类型?

typeof (obj) === 'string';
typeof obj === 'string';
obj.constructor === String;

94.请用js去除字符串空格?

  方法一:

  • 去除所有空格:str = str.replace(/\s*/g,'');
  • 去除两头空格:str = str.replace(/^\s*|\s*$/g,'');
  • 去除做空格:str = str.replace(/^\s*/, '');
  • 去除右空格:str = str.replace(/(\s*$)/g, '')
var str = " 23 23 ";
var str2 = str.replace(/\s*/g,"");
console.log(str2); // 2323

  方法二:使用str.trim()方法

  str.trim()局限性:无法去除中间的空格;

var str = "   xiao  ming   ";
var str2 = str.trim();
console.log(str2);   //xiao  ming 
  同理,str.trimLeft(),str.trimRight()分别用于去除字符串左右空格。


95.如何获取浏览器URL中查询字符串的参数?测试地址为:http://www.runoob.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=23

function UrlSearch(){
    var url = window.location.href;
    var arr = url.split('?')[1].split('&');
    var obj = {};
    if (url.split('?')[0] == url ) {
        return '';
    }
    for (var i = 0; i < arr.length; i++) {
        var arg = arr[i].split('=');
        obj[arg[0]] = arg[1];
    }
    return obj;
}

var href = UrlSearch(); //obj
console.log(href('name')); //xiaoming

96.js字符串操作函数?

  • concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串。
  • indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1 。
  • charAt() – 返回指定位置的字符。
  • lastIndexOf() – 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1 。
  • match() – 检查一个字符串是否匹配一个正则表达式。
  • substr() 函数 -- 返回从string的startPos位置,长度为length的字符串
  • substring() – 返回字符串的一个子串。传入参数是起始位置和结束位置。
  • slice() – 提取字符串的一部分,并返回一个新字符串。
  • replace() – 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。
  • search() – 执行一个正则表达式匹配查找。如果查找成功,返回字符串中匹配的索引值。否则返回 -1 。
  • split() – 通过将字符串划分成子串,将一个字符串做成一个字符串数组。
  • length – 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。
  • toLowerCase() – 将整个字符串转成小写字母。
  • toUpperCase() – 将整个字符串转成大写字母。

97.怎样添加、移除、移动、复制、创建和查找节点?

  1.创建新节点

    createDocumentFragment()//创建一个DOM片段

    createElement();//创建一个具体的元素

    createTextNode();//创建一个文本节点

   2.添加、移除、替换、插入

     appendChild(); //添加

     removeChild(); // 移除

     replaceChild(); //替换

     insertBefore(); //插入

   3.查找

     getElementsByTagName(); //通过标签名称

     getElementsByName(); //通过元素 的name属性值 

     getElementById(); //通过元素id,唯一性

98.JavaScript面向对象中继承实现?

  面向对象的基本特征有:封闭、继承、多态

  在JavaScript中实现继承的方法:

  1.原型链(prototype chainning)

  2.call() apply()

  3.混合方式(prototype和call或者apply结合)

  4.对象冒充

  继承的方法如下:

    1.prototype原型链

function teacher(name){
    this.name = name
}

teacher.prototype.sayName = function(){
    console.log('name is'+this.name)
}

var teacher1 = new teacher('xiaoming');
teacher1.sayName();

function student(name){
    this.name = name;
}

student.prototype = new teacher();
var student1= new student('xiaohong');
student1.sayName();
//name is xiaoming 
//name is xiaohong

2.使用call、apply方法

function teacher(name,age){
    this.name = name;
    this.age = age;
    this.sayHi = function(){
        alert('name:'+name+", age:"+age);
    }
}

function student(){
    var args = arguments;
    teacher.call(this,args[0],arg[1]);
    // teacher.appley(this,arguments)
}

var teacher1 = new teacher('xiaoming',23);
teacher1.sayHi();

var student = new student('xiaohong',12);
student1.sayHi();

//name:xiaoming, age:23
//name:xiaohong, age:12

3.混合方式(prototype,call, apply)

function teacher(name,age){
	this.name = name;
	this.age = age;
}

teacher.prototype.sayName = function(){
	console.log(name)
}

teacher.prototype.sayAge =function(){
	console.log(age)
}

function student(){
	var arg = arguments;
	teacher.call(this,arg[0],arg[1])
}

student.prototype = new teacher();

var student1 = new student('xiaohong',23);
student1.sayName(); //xiaohong
student1.sayAge(); //23

4.对象冒充

function Person(name,age){
	this.name = name;
	this.age = age;
	this.show = function(){
		console.log(this.name+','+this.age)
	}
}

function student(name,age){
	this.student = Person; //将person类的构造函数赋值给this.student
	this.student(name,age); //js中实际上是通过对象冒充来实现继承的
	delete this.student; //移除person的引用
}

var s = new student('xiaoming',17)
s.show();

var p = new Person('xiaohua',18);
p.show()



猜你喜欢

转载自blog.csdn.net/maggie_live/article/details/80317836