javascript面试题集

1.如何把一句英文每个单词第一个字母大写?

var str = "what fuck is 1235 going on ?";
var newArr = str.split(" ");
for(var i=0,myArr=[];i<newArr.length;i++){
    myArr.push(newArr[i].replace(newArr[i].charAt(0),newArr[i].charAt(0).toUpperCase()));
}
console.log(myArr);
var myStr=myArr.join(" ");
console.log(myStr);

2.JS随机获取颜色的程序

<body>
  <div id="box">
</div>
<button id="button">获取颜色</button>    
</body>

 function getColor(){
    var r = Math.floor(Math.random()*256);
    var g = Math.floor(Math.random()*256);
    var b = Math.floor(Math.random()*256);
    document.getElementById('box').style.background="rgb("+r+','+g+','+b+")";
 }

3.截取url参数

$(function() {
       var search=location.search;//获得路径
       var params={};//定义一个空对象
       if(params!=''){
          var ps=search.slice(1).split('&');//截取?之后的路径,并以&切割
              for(var i=0;i<ps.length;i++){//遍历参数数组
                  var arr=ps[i].split('=');//将数组每个元素以=切割
                   params[arr[0]]=arr[1];//
          }
       }
       var userId=params.userId;
});

4.点击一个ul的五个li元素,分别弹出他们的序号

方法一:
<script> //设置index保存 var oLi=document.getElementsByTagName('li'); for(var i=0;i<oLi.length;i++){ oLi[i].index=i; oLi[i].onclick=function(){ alert(this.index); } } </script>

方法二: <script> var oLi=document.getElementsByTagName('li'); for(var i=0; i<oLi.length; i++){ (function(j){ oLi[j].onclick = function(){ alert(j); }; })(i); }
</script>

5.js数组去重

<script>
//方法一:indexof查找
var arr=new Array(1,2,2,2,3,3,5,6,8,8,9);
Array.prototype.unique1=function(){
    var n=[];
    for(var i=0;i<arr.length;i++){
        if(n.indexOf(arr[i])==-1){
            n.push(arr[i]);
        }
    }
    return n;
}
alert(arr.unique1());
</script>

<script>
//方法二:hash
var arr=new Array(1,2,2,2,3,3,5,6,8,8,9);
Array.prototype.unique2=function(){
    var hash={},//hash表
    n=[];//临时数组
    for(var i=0;i<this.length;i++){
        if(!hash[this[i]]){ //如果hash表中没有当前项
            hash[this[i]]=true;//存入hash表
            n.push(this[i]);//当前元素push到临时数组中
        }
    }
    return n;
}
alert(arr.unique1());
</script>

6.js编程找出一段字符串中出现次数最多的字符以及出现的次数

var str="we are friends";
var maxLen=0;
var index="";
var hash={};
for(var i=0;i<str.length;i++){
   if(!hash[str.charAt(i)]){
       hash[str.charAt(i)]=1;
   }else{
       hash[str.charAt(i)]++;
  }
}
for(var i in hash){
   if(hash[i]>maxLen){
       maxLen=hash[i];
       index=i;
   }
}
alert("出现次数最多的元素是:"+index+" 出现次数:"+maxLen);

7.js去掉字符串前后所有的空格

function Trim(str){ 
     return str.replace(/(^s*)|(s*$)/g, ""); 
}

8.求一个字符串的字节长度

function getLen(str){
      var len=0;
      for(var i=0;i<str.length;i++){
          if(str.charCodeAt(i)>255){//charCodeAt() 方法可返回指定位置的字符的 Unicode 编码
              len+=2;
          }else{
              len++;
          }
      }
      return len;
}

9.变量的坑

d();
e();
function d(){//用声明的方式声明的函数
  alert('hello');//hello
}
var e = function(){//函数表达式
  alert('world');//e is not a function
}

10.冒泡排序

function arrSort(arr){
    var len=arr.length;
    var nu = '';
    for(var i=0;i<=len-1;i++){
       for(var j=0;j<=len-1-i;j++){
          if(arr[j]>arr[j+1]){
             nu=arr[j];
             arr[j]=arr[j+1];
             arr[j+1]=nu;
          }
       }
    }
    return arr;
}

11.实现距离某一天还有多久?

function getDay(){
    var start = new Date();
    var end = new Date(start.getFullYear()+1,'0');
    var leftTime = (end.getTime()-start.getTime())/1000;//转成秒
    var second = Math.floor(leftTime%60);//取余
    var minute = Math.floor((leftTime/60))%60;
    var hour = Math.floor((leftTime/(60*60)))%24;
    var day = Math.floor((leftTime/(60*60*24)))%30;
    var month = Math.floor((leftTime/(60*60*24*30)))%12;
    return '距离明年还剩'+month+'月,'+day+'天,'+hour+'小时,'+minute+'分钟,'+second+'秒';
}
setInterval(function(){
    var text=getDay();
    document.getElementById('time').innerHTML=text;
},1000);

12.jquery 中如何将数组转化为json字符串,然后再转化回来?

    jQuery中没有提供这个功能,所以你需要先编写两个jQuery的扩展:

    $.fn.stringifyArray = function(array) {
        return JSON.stringify(array)
    }

    $.fn.parseArray = function(array) {
        return JSON.parse(array)
    } 

  然后调用:
  $("").stringifyArray(array)

13.非编程题

(1)  [ ]==[ ]
  答案:false.
  数组,在 Javascript 中是对象,对象使用 == 比较都是比较的引用。
  简单的说,就是,如果是同一个对象,就相等,如果不是同一个对象,就不等。
  每次使用 [] 都是新建一个数组对象,所以 [] == [] 这个语句里建了两个数据对象,它们不等。

 (2)Array.isArray(Array.prototype)

  答案:true
  Array.prototype为[],Array.isArray(a)是一个判断a是否为数组的方法。

 (3)声明提前

  var word="hello word";
  (function(){
    alert(word); //undefined
    var word="hello test";
  })();

谈话面试:

1、前端跨域你是如何处理的?如何处理安全性问题(劫持)?

2、关于JavaScript中this的详细总结?

解:1.全局上下文:无论是否在严格模式下,在全局执行上下文中(在任何函数体外部)this 都指代全局对象。【在全局执行上下文中 this 都是全局对象 window】(浏览器环境)

  2.函数上下文:在函数内部,this 的值取决于函数被调用的方式。【取决于被调用的方式】

  3.bind方法:ECMAScript 5 引入了 Function.prototype.bind。调用 f.bind(someObject) 会 创建一个与 f 具有相同函数体和作用域的函数,但是在这个新函数中,this 将永久地被绑定到了 bind 的第一个参数,无论这个函数是如何被调用的。

  4.箭头函数:在箭头函数中,this 与封闭词法上下文的 this 保持一致。在全局代码中,它将被设置为全局对象

  5.作为对象的方法:当函数作为对象里的方法被调用时,它们的 this 是调用该函数的对象

  6.原型链中的this:对于在对象原型链上某处定义的方法,同样的概念也适用。如果该方法存在于一个对象的原型链上,那么 this 指向的是调用这个方法的对象,就像该方法在对象上一样。

  7.作为构造函数:当一个函数用作构造函数时(适用 new 关键字),它的 this 被绑定到正在构造的新对象。虽然构造器返回的默认值是 this 所指的那个对象,但它仍可以手动返回其他的对象(如果返回值不是一个对象,则返回 this 对象)

  8.作为DOM事件的处理函数:当函数被用作事件处理函数时,它的 this 指向触发事件的元素(一些浏览器在使用非 addEventListener 的函数动态添加监听函数时不遵守这个约定)

  9.作为一个内敛事件处理函数:当代码被内联 on-event 处理函数 调用时,它的 this 指向监听器所在的 DOM 元素

3.理解JavaScipt中的深拷贝和浅拷贝?

解:需要先理解基本类型和引用类型:

  ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置。而引用类型值是指那些保存堆内存中的对象,意思是变量中保存的实际只是这个对象的引用,这个引用指向堆内存中的对象。

目前基本类型有:Boolean、Null、Undefined、Number、String、Symbol。
引用类型有:Object、Array、Function。

深拷贝与浅拷贝的概念只存在于引用类型。

浅拷贝:

var obj1 = {x:1, y:2},obj2 = obj1;
console.log(obj1) // {x:1, y:2}
console.log(obj2) // {x:1, y:2}
obj2.x = 2; // 修改obj2.x
console.log(obj1) // {x:2, y:2}
console.log(obj2) // {x:2, y:2}

深拷贝:

数组:slice()只能实现一维数组的深拷贝,Object.assign()也只能实现一维对象的深拷贝。
var arr1 = [1, 2], arr2 = arr1.slice();
console.log(arr1); //[1, 2]
console.log(arr2); //[1, 2]
arr2[0] = 3; //修改arr2
console.log(arr1); //[1, 2]
console.log(arr2); //[3, 2]

4.既然localStorage和sessionStorage能做到数据维护,为什么还要引入vuex?

解:可维护性:因为是单向数据流,所有状态是有迹可循的,数据的传递也可以及时分发响应

  易用性:它使得我们组件间的通讯变得更强大,而不用借助中间件这类来实现不同组件间的通讯

而且代码量不多,若是你要用 localStorage 或者 sessionStorage ,你必须手动去跟踪维护你的状态表,虽说可行,但是代码量会多很多,而且可读性很差

5、vuex的用户信息为什么还要载存一遍到浏览器里(localStorage ,sessionStorage )?

解:因为 vuex 的 store 干不过刷新啊
  保存在浏览器的缓存内,若用户刷新的话,值再取一遍呗。

3、什么是jsonp?

 解:浏览器在请求不同域的资源时,会因为同源策略的影响请求不成功,这就是通常被提到的“跨域问题”。

  同源策略",即同域名(domain或ip)、同端口、同协议的才能互相获取资源,而不能访问其他域的资源。在同源策略影响下,一个域名A的网页可以获取域名B下的脚本,css,图片等,但是不能发送Ajax请求,也不能操作Cookie、LocalStorage等数据。同源策略的存在,一方面提高了网站的安全性,但同时在面对前后端分离、模拟测试等场景时,也带来了一些麻烦,从而不得不寻求一些方法来突破限制,获取资源。

4、vue父子组件如何进行通讯?

 解:父组件传数据给子组件,通过props属性来实现

<parent>
    <child :child-msg="msg"></child>//这里必须要用 - 代替驼峰
</parent>

data(){
    return {
        msg: [1,2,3]
    };
}
方法一:
props: ['childMsg']
方法二:
props: { childMsg: Array
//这样可以指定传入的类型,如果类型不对,会警告 }
方法三:
props: { childMsg: { type: Array, default: [0,0,0] //这样可以指定默认的值 } }

  如果子组件想要改变数据呢?这在vue中是不允许的,因为vue只允许单向数据传递,这时候我们可以通过触发事件来通知父组件改变数据,从而达到改变子组件数据的目的.emit

子组件:
<template>
    <div @click="up"></div>
</template>

methods: {
    up() {
        this.$emit('upup','hehe'); //主动触发upup方法,'hehe'为向父组件传递的数据
    }
}
父组件:
<div>
    <child @upup="change" :msg="msg"></child> //监听子组件触发的upup事件,然后调用change方法
</div>
methods: {
    change(msg) {
        this.msg = msg;
    }
}

5、vue多个父子组件如何进行通讯?

 

vue的生命周期钩子
每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码。
beforeCreate: //创建之前:vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。
created: //创建完毕:vue实例的数据对象data有了,$el还没有
beforeMount: //挂载前,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的DOM节点,data.message还未替换。
mounted: // 挂载完毕,data.message成功渲染。
beforeUpdate: // 修改vue实例的data时,vue会自动更新渲染视图
beforeDestroy: // 销毁之前
destroyed: // 销毁成功

深入响应式原理

当你把一个普通的javascript对象传给vue实例的data选项,vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter
这些getter/setter对用户来说是不可见的,但是在内部他们让vue追踪依赖,在属性被访问和修改时通知变化。这里需要注意的问题是浏览器控制台在打印数据对象时getter/setter的格式化并不同,所以需要安装vue-devtools来获取更加友好的检查接口。
每个组件实例都有相应的watcher实例对象,他会在组件渲染的过程中把属性记录为依赖,之后当依赖的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。
⦁ Vue中实现了数据的双向绑定,为了支持双向绑定,就必须时刻追踪数据变化并及时响应到ui上。
⦁ Vue通过Object.defineProperty()设置对象的存储器属性,并对对象中的每个值,重写了其中的get、set,data中的每个key,都有一个独立的依赖收集器。
⦁ 在get中,向依赖收集器添加了监听
⦁ 在mount时,实例了一个Watcher,将收集器的目标指向了当前Watcher
⦁ 在data值发生变更时,触发set,触发了依赖收集器中的所有监听的更新,来触发Watcher.update


Vue中的MVVM模式
vue是以数据驱动的,vue本身将Dom和数据进行绑定,一旦创建绑定,DOM和数据将保持同步,每当数据发生变化,DOM会跟着变化。ViewModel是vue的核心,它是vue的一个实例。

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


computed和watch的区别
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算
监听某一个值,当被监听的值发生变化时,执行对应的操作
与computed的区别是,watch更加适用于监听某一个值的变化并做对应的操作,比如请求后台接口等,而computed适用于计算已有的值并返回结果

6、什么是事件代理?

解:javaScript的事件代理也叫事件委托。

比如我们有100个li,每个li都有相同的click点击事件,可能我们会用for循环的方法,来遍历所有的li,然后给它们添加事件,

通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,

代理呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。

就是利用事件冒泡的原理,把事件加到父级元素上,触发执行效果。从而可以很大程度上来提高执行的效率、而且就算新添加了元素还是会有代理的事件

7、javascript代理模式你知道吗?

 

8、call 和 apply 、箭头函数 在什么场景下使用,他们的作用是什么? 

 解:相同,call和apply,专门用于借用一个函数,并替换函数中的this为指定对象。

     不同,call要求传入函数的参数必须独立传入。

      apply要求传入函数的参数必须放入一个数组或集合中,整体传入。

9.请描述一下cookies,sessionStorage和localStorage的区别?

解:web存储,在开发web应用时,开发人员有时需要在本地存储数据,当前浏览器支持cookie存储,但其大小有4KB限制。

  html5中的web存储对象有两种类型:

  sessionStorage对象,负责存储一个会话的数据。如果用户关闭了页面或浏览器,则会销毁数据,一次会话结束,存储的信息会自动删除,

            存储的数据无法垮页面存在,只在当前页面。

  localStorage对象,负责存储没有到期的数据,当web页面或浏览器关闭时,仍会保持数据的存储,当然这还取决于为此用户的浏览器设置

            的存储量,如果不是人为删除,存储的信息会一直保留,存储的数据内容是可以跨页的。

10.移动页面专题如何适配不同分辨率(保持整个页面等比例一致)

解:设置width=device-width,然后用百分比来分配屏幕宽度,高度自适应变化,字体也使用相对大小em,rem等等

11.移动端点击穿透的原因是什么?怎么解决?

原因:click与300ms延迟

移动浏览器提供一个特殊的功能:双击(double tap)放大

300ms的延迟就来自这里,用户碰触页面之后,需要等待一段时间来判断是不是双击(double tap)动作,而不是立即响应单击(click),等待的这段时间大约是300ms。

a、不要混用touch和click

   既然touch之后300ms会触发click,只用touch或者只用click就自然不会存在问题了

12.什么是原型链?写一段原型链代码?

 在javaScript中一切皆对象,但是对象又分为函数对象和普通对象,通过new出来的都是函数对象,function是默认的函数对象,函数对象有一个默认的属性prototype,指向原型对象。原型对象上的方法和属性,可以被这个函数创建的实例引用。

为了实现继承,还有一个原型链指针__proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直指向Object的原型对象上,而Object的原型对象用Object.prototype.__proto__ = null表示原型链的最顶端,如此变形成了javascript的原型链继承function Person () {
this.name = 'John';
}
Person.prototype = {
     say: function() {
        console.log('Hello,' + this.name);
     }
};
var person = new Person();
person.say();//person.say is not a function



//函数B想要使用函数A的变量
function
 Super(){
    this.val = 1;

    this.arr = [1];

}

function Sub(){

    // ...

}

Sub.prototype = new Super();    // 核心


var sub1 = new Sub();

var sub2 = new Sub();

sub1.val = 2;

sub1.arr.push(2);

alert(sub1.val);    // 2

alert(sub2.val);    // 1

 
alert(sub1.arr);    // 1, 2

alert(sub2.arr);    // 1, 2

13.前端如何压缩用户上传的图片?

上传前用js对图片压缩,把利用canvas生成的base64字符串,传入后台,
 * (无所谓ajax或者form,同时也可以解决图片无刷新上传),
 * 在Java后台将获取到的base64字符串输出为图片,即可。

14.手机上拍照为什么有时候会得到旋转90度的照片?怎么解决?

解:其实是拿手机拍照的方向问题,iphone正确的手机拍照方式是横屏的,用户往往是竖屏拍照等于照相机反转了90度,出来的照片当然是反转90度,当你横屏拍照上传,图片就是正确的,一张生成的图片是无法辨别选择方向的,只有在上传前反转角度才行。

//获取图片方向
function getPhotoOrientation(img) {
     var orient;
     EXIF.getData(img, function () {
           orient = EXIF.getTag(this, 'Orientation');
     });
     return orient;
}
//图片压缩
function compress(img, width, height, ratio) {
      var canvas, ctx, img64, orient;
    
      //获取图片方向
      orient = getPhotoOrientation(img);

      canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;

      ctx = canvas.getContext("2d");

      //如果图片方向等于6 ,则旋转矫正,反之则不做处理
      if (orient == 6) {
            ctx.save();
            ctx.translate(width / 2, height / 2);
            ctx.rotate(90 * Math.PI / 180);
            ctx.drawImage(img, 0 - height / 2, 0 - width / 2, height, width);
            ctx.restore();
      } else {
            ctx.drawImage(img, 0, 0, width, height);
      }

      img64 = canvas.toDataURL("image/jpeg", ratio);
      return img64;
}

15.什么是前端路由?什么时候适合使用前端路由?前端路由有哪些优点和缺点?

解:路由是根据不同的 url 地址展示不同的内容或页面

       前端路由更多用在单页应用上, 也就是SPA, 因为单页应用, 基本上都是前后端分离的, 后端自然也就不会给前端提供路由。 

  优点:
  1.从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。
  2.在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户就不能复制到想要的地址,用前端路由做单页面网页就很好的解决了这个问题
  缺点:

  使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。

 16.请讲解一下闭包?

    解:包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

   使用闭包的注意点:

          由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

          闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。 

 17.js中的作用域和作用域链

   作用域指变量和函数的可使用范围,在JavaScript中变量的作用域分为局部作用域和全局作用域。

   1.全局作用域

   (1)最外层函数和在最外层函数外面定义的变量拥有全局作用域

    (2)所有末定义直接赋值的变量自动声明为拥有全局作用域。

    (3)所有window对象的属性拥有全局作用域

  2.局部作用域

       函数内部声明的变量。

  3.作用域链

  程序执行的时候会创建一个执行环境栈,首先将window的执行环境压入到执行环境栈中,window是全局的,里面存放全局的变量和函数。

当调用一个函数的时候,会将这个函数的执行环境压入到执行环境栈中,并且还会创建这个函数的活动对象,指向活动对象。活动对象中保存

函数内部的变量也就是局部变量,活动对象指向window。

函数调用完之后,它的执行环境会被释放,它指向的活动对象也会被释放。活动对象中保存的局部变量也被释放。当查找一个变量时,首先去

活动对象中查找,找不到就沿着作用域链向下查找,如果window中都找不到,就会报错。格局作用于逐级引用形成作用域链。

18.同步和异步

同步就是指一个进程在执行某个请求的时候,若该请求需要隔一段时间才能返回信息,那么这个进程会一直等待下去,直到收到返回消息才会继续执行下去

异步请求是指进程不需要一直等待下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时,系统会通知进程进行处理,这样可以提高执行效率。

setTimeout(function cbFn(){
    console.log('learnInPro');
}, 1000);
 
console.log('sync things');

setTimeout就是一个异步任务,当JS引擎顺序执行到setTimeout的时候发现他是个异步任务,则会把这个任务挂起,继续执行后面的代码。直到1000ms后,回调函数cbFn才会执行,这就是异步,在执行到setTimeout的时候,JS并不会傻呵呵的等着1000ms执行cbFn回调函数,而是继续执行了后面的代码

为什么要在js中写异步?

由于javascript是单线程的,只能在JS引擎的主线程上运行的,所以js代码只能一行一行的执行,不能在同一时间执行多个js代码任务,这就导致如果有一段耗时较长的计算,或者是一个ajax请求等IO操作,如果没有异步的存在,就会出现用户长时间等待,并且由于当前任务还未完成,所以这时候所有的其他操作都会无响应。

11.http://blog.csdn.net/gaoshanwudi/article/details/7355794闭包

19.重载

     argument。length判断参数的个数。

20.热加载

21.vue的缺点

22.不固定高宽div垂直居中的方法

<div class="block" style="height: 300px;">
    <div class="centered">
        <h1>haorooms案例题目</h1>
        <p>haorooms案例内容,haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容haorooms案例内容</p>
    </div>
</div>

/* This parent can be any width and height */
.block {
  text-align: center;
}

/* The ghost, nudged to maintain perfect centering */
.block:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

/* The element to be centered, can
   also be of any width and height */ 
.centered {
  display: inline-block;
  vertical-align: middle;
  width: 50%;
}

21.匿名函数和普通函数的区别?

普通函数可以在声明之前调用,

匿名函数会被当做普通表达式,存在声明提前。

a();//a函数可以在它定义的前面调用
b();//b函数这样调用就会出“未定义”错误
 
function a()
{
  alert("aaaaaa");
}
 
var b = function ()
{
  alert("bbbbbb");
}

22. 网页从输入网址到渲染完成经历了哪些过程?

大致可以分为如下7步:

输入网址;

发送到DNS服务器,并获取域名对应的web服务器对应的ip地址;

与web服务器建立TCP连接;

浏览器向web服务器发送http请求;

web服务器响应请求,并返回指定url的数据(或错误信息,或重定向的新的url地址);

浏览器下载web服务器返回的数据及解析html源文件;

生成DOM树,解析css和js,渲染页面,直至显示完成;

23.jquey如何扩展自定义方法

(jQuery.fn.myMethod=function(){
     alert('myMethod');
})
// 或者:
(function($){
  $.fn.extend({
    myMethod: function(){
      alert('myMethod')
    }
  })
})(jQuery)

// 使用
$("#div").myMethod();
亦心晗
原文地址:https://www.cnblogs.com/wanf/p/7207521.html