美文网首页
前端面试常见知识点总结

前端面试常见知识点总结

作者: linwalker | 来源:发表于2017-01-14 09:24 被阅读0次

    HTML

    • 对html5的理解,web语义话,SEO
    • 页面加载过程
    • 新增API,本地存储,Canvas

    CSS

    • 经典圣杯布局
    • CSS3 transition transform animate
    • w3c盒模型和IE盒模型,box-sizing属性
    • 居中
    • 浮动,position
    • 块级元素和行内元素
      • 块级元素: div,h1,p,ul,ol,li
      • 行内元素: a,span,img,em, input, label
      • 区别:
        • 块级元素占一行且宽度默认占满父元素,行内元素可以排在同一行;
        • 块级元素可以设置宽高,当仍然占一行;行内元素设置宽高无效;
        • 块级元素可以设置margin和padding属性,行内元素可以设置水平方向的margin和padding属性,竖直方向无效
    • BFC
    • 优先级
    • less与sass
    • background-*系列属性

    JS

    • 原型

    • 对象

      工厂模式

      
      function createPerson(name, age, job) {
          var o = new Object();
          o.name = this.name;
          o.age = this.age;
          o.job = this.job;
          o.sayName = function () {
              alert(this.name);
          };
          return o;
      }
      var person1=createPerson('lin',29,'programmer');
      var person2=createPerson('li',30,'teacher');
      

      解决创建多个相似对象的问题,没解决对象识别的问题

      构造函数模式

      
      function Person(name, age, job) {
          this.name = name;
          this.age = age;
          this.job = job;
          this.sayName = function () {
              alert(this.name);
          };
      }
      var person1 = new Person('lin', 29, 'programmer');
      var person2 = new Person('li', 30, 'teacher');
      

      调用构造函数4个步骤:

      • 创建一个对象;
      • 将构造函数的作用域赋给新对象;(this指向新对象)
      • 执行构造函数中的代码
      • 返回新对象

      主要问题:每个方法都要在每个实例上重新创建一遍,不同实例上的同名函数是不想等的。

      原型模式

      function Person() {}
      Person.prototype.name = 'lin';
      Person.prototype.age = 29;
      Person.prototype.job = 'programmer';
      Person.prototype.sayName = function () {
          alert(this.name);
      }
      var person1 = new Person();
      
      • 创建函数会创建一个prototype属性,指向函数的原型对象
      • Person的每个实例内部包含一个属性,指向Person.prototype
      • 读取某个对象的某个属性,搜索先从对象实例本身开始,没有再搜索指针指向的原型对象
      • 在实例对象上添加或修改同名属性,会屏蔽原型对象属性,但对于包含引用类型值的属性,会直接修改原型对象上的属性
      • 对象字面量重写原型对象,其constructor属性会指向Object构造函数,切断现有原型与之前存在的实例对象之间的联系(即之前生成的的实例无法访问现有原型对象上的属性与方法)
      function Person() {
      }
      var friend = new Person();
      Person.prototype = {
           constructor: Person,
           name: 'lin',
           age: 29,
           sayName: function () {
               alert(this.name);
           }
      };
      friend.sayName(); //error
      

      原型模式问题:省略了构造函数参数传递,结果所有的实例在默认情况下都取得相同的属性值;实例改变包含引用类型值的属性时,会改变原型对象上的相应属性值,其他实例的相应属性值也会改变;

      组合使用构造和原型模式

      function Person(name.age,job) {
          this.name=name;
          this.age=age;
          this.job=job;
          this.friends=['lucy','lily']
      }
      Person.prototype={
          constructor:Person,
          sayName:function(){
              alert(this.name);
          }
      }
      var person1=new Person('lin',29,'programmer');
      

      动态原型模式

      function Person(name.age,job) {
          this.name=name;
          this.age=age;
          this.job=job;
          
          if(typeof this.sayName !='function') {
              Person.prototype.sayName = function() {
                  alert(this.name);
              }
          }
      }
      var person1=new Person('lin',29,'programmer');
      

      注意不能使用对象字面量重写原型

      寄生构造函数模式

      稳妥构造函数模式

    • 继承

      原型链

      每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象内部的指针;让原型对象等于另一个构造函数的实例,此时原型对象就有指向另一个原型的指针,另一个原型也包含着指向另一个构造函数的指针,以此类推构成实例与原型的链条。

      function One() {
          this.oneprototype = true;
      }
      One.prototype.getOneValue = function () {
          return this.oneprototype;
      }
      function Two() {
          this.twoprototype = false;
      }
      Two.prototype = new One();
      Two.prototype.getTwoValue = function () {
          return this.twoprototype;
      }
      var Three = new Two();
      alert(Three.getOneValue()); //true
      

      通过重写Two的原型对象,继承One,原本存在One的实例中的属性和方法,现在也存在Two.prototype中,新原型中还有一个指向One原型的指针。最终时Three指向Two的原型,Two的原型指向One的原型。oneprototype在Two.prototype中,但getOneValue()方法仍在One.prototype上。

      给子类原型添加或则覆盖某个方法,添加方法的代码放在原型重写代码的后面。

      原型链继承的问题:超类实例中属性的值为引用类型值时,子类的实例修改该属性,其他子类实例中也会相应改变。

      function One() {
          this.color = ['red', 'blue'];
      }
      function Two() {
      }
      
      Two.prototype = new One();
      var three = new Two();
      three.color.push('black');
      alert(three.color);     // 'red,blue,black'
      var four = new Two();
      alert(four.color);      //'red,blue,black'
      var five = new One();
      alert(five.color);      //'red,blue'
      

      借用构造函数

      function One() {
          this.color = ['red', 'blue'];
      }
      function Two() {
          One.call(this);
          this.age=29;
      }
      var three = new Two();
      three.color.push('black');
      alert(three.color);      // 'red,blue,black'
      alert(three.age)         //29
      var four = new new Two();
      alert(four.color);       //'red,blue'
      
      

      问题:无法避免构造函数模式存在的问题。

      组合继承

      function Ono(name) {
          this.name = name;
          this.num = [1, 2, 3];
      }
      One.prototype.sayName = function () {
          alert(this.name);
      }
      
      function Two(name, age) {
          One.call(this, name);
          this.age = age;
      }
      
      Two.prototype = new One();
      Two.prototype.constructor = One;
      Two.prototype.sayAge = function () {
          alert(this.age);
      }
      
      var three = new Two('lin', 29);
      three.num.push(4);
      alert(this.num);     //1,2,3,4
      three.sayAge();       //29
      three.sayName();      //'lin'
      var four = new Two('li', 30);
      alert(four.num);    //1,2,3
      four.sayAge();      //30
      four.sayName();     //'li'
      

      通过原型链对原型属性和方法继承,通过借用构造函数对实例属性继承。

      问题:调用两次超类的构造函数,一次是创建子类型原型的时候,另一次是在子类型构造函数内部

      原型式继承

      function object(o) {
          function F(){};
          F.prototype=o;
          return new F();
      }
      
      ES5 Object.create()
      
      var person={
          name:'lin',
          num:[1,2,3];
      }
      
      var person2=Object.create(person);
      person2.name='li';
      person.num.push(4);
      alert(person.num); //1,2,3,4
      

      寄生式继承

      function createAnother(original) {
          var clone = abject(original);
          clone.sayHi = function () {
              alert('hi');
          }
          return clone;
      }
      
      var person = {
          name: 'lin',
          num: [1, 2, 3];
      }
      
      var person2 = createAnother(person);
      person2.sayHi(); //'hi';
      

      寄生组合继承

      function inheritPrototype(Two,One) {
          var prototype = Object(One.prototype);
          prototype.constructor=Two;
          Two.prototype=prototype;
      }
      
      function One(name) {
          this.name=name;
          this.num=[1,2,3];
      }
      
      One.prototype.sayName=function(){
          alert(this.name);
      }
      
      function Two(name,age) {
          One.call(this,name);
          this.age=age;
      }
      
      inheritPrototype(Two,One);
      Two.prototype.sayAge=function() {
          alert(this.age);
      }
      

      通过借用构造函数来继承实例属性,通过原型链的混成形式继承原型方法和属性。不必为了指定子类的原型而调用超类型构造函数,使用寄生式继承来继承超类型的原型,在将结果指定给子类型的原型

    • 变量 作用域

      变量

      变量包含两种不同数据类型值,基本类型值和引用类型值。

      基本类型值:简单的数据段;
      number,string,boolean,null,undefined

      引用类型值:由多个值构成的对象;保存在堆内存中,复制对象的某个变量时实际上是操作对象的引用,但在为对象添加属性时,操作的是实际对象。

      执行环境

      定义变量或函数有权访问的其他数据;

      环境中定义的所有变量和函数都保存在一个变量对象中;

      作用域链

      保证对执行环境有权访问的变量和函数的有序访问;

      作用域链的前端,是当前执行代码所在环境的变量对象,接着是来自包含环境的变量对象,以此类推,一直延续到全局执行环境,全局执行环境的变量对象是作用域链的最后一个对象。

      内部环境通过作用域链访问外部环境。

    • 闭包

      闭包是指有权访问另一个函数作用中的变量的函数,常见的创建方式,在一个函数内部创建另一个函数;

      闭包的作用包含外部函数的变量对象;

      闭包只能取得包含函数中任何变量的最后值

      function fun() {
        var result = new Array();
      
        for (var i = 1; i < 10; i++) {
          result[i] = function () {
              return i;
          };
         }
      
        return result;
      }         
      function fun() {
          var result = new Array();
      
          for (var i = 1; i < 10; i++) {
              result[i] = function (num) {
                  return function(){
                      return num;
                  };
              }(i);
          }
      
          return result;
      }
      

      在匿名函数中定义的任何变量会在执行结束被销毁,从而限制像全局作用中添加更多的变量和函数

      利用闭包的作用域链访问外部函数的变量,用于创建访问私有变量的公有方法

      模块模式:为单例(只有一个实例的对象,通过对象字面量创建)创建私有变量和特权方法(有权访问私有变量和函数)

      闭包的作用,通过作用域可以提供访问私有变量和函数的接口

    • 函数调用方式

      • 方法调用
      • 函数调用
      • 构造器调用
      • apply调用
    • JSON

    • 高阶函数

    • JSONP跨域iframe通信

    • Ajax

    • 原生DOM操作,逆序DOM节点

    • 事件捕获,冒泡,代理

      事件流
      * 手指放在同心圆的圆心,手指向的不是一个圆,而是所有的圆;即单击按钮的同时,也单击了按钮的容器元素,也单击了整个页面。
      * 事件流描述的是从页面中接受事件的顺序。
      * IE的事件流是事件冒泡,即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点:div > body >html > document
      * Netscape事件流是事件捕获,与IE相反;
      * DOM 事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段

      事件处理

      • DOM2级事件处理程序
      
      var btn = document.getElementById('myBtn');
      btn.addEventListener('click',handle,fasle); //fasle表示事件在冒泡阶段触发
      btn.removeEventListener('click',handle,false)
      handle 如果为匿名函数则取消无效
      
      • IE事件处理程序
      
      var btn = document.getElementById('myBtn');
      btn.attachEvent('onclick',handle); 
      btn.detachEvent('onclick',handle)
      只有IE和Opera支持
      
      • 跨浏览器事件处理程序
      var EventUtil = {
          addHandler: function (element,type,handler) {
              if (element.addEventListener) {
                  element.addEventListener (type,handler,false);
              } else {
                  element.attachEvent ('on'+type,handler);
              } else {
                  element['on'+type] = handler;
              }
          },
          removeHandler:function (element,type,handler) {
              if(element.removeEventListener) {
                  element.removeEventListener (type,handler,false);
              } else {
                  element.detachEvent ('on' + type,handle);
              } else {
                  element['on'+type] = null;
              }
          }
      }
      var btn = document.getElementById('mybtn');
      EventUtil.addHandler(btn,'click',handler);
      EventUtil.removeHandler(btn,'click',handler);
      

      事件对象

      • DOM中的事件对象:event

        1. this = currentTarget :事件处理程序存在对象;

        2. target:事件的目标(如单击的按钮);

        3. 阻止特定的默认行为:event.preventDefault()

        4. 阻止事件冒泡:stopPropagation()

      • IE中的事件对象:window.event

        1. srcElemnt事件的目标
        2. 阻止特定的默认行为:window.event.returnvalue =false
        3. 阻止事件冒泡:window.event.cancelBubble()
        var EventUtil = {
          addHandler: function (element, type, handler) {
          },
          getEvent: function (event) {
            return event ? event : window.event;
          },
          getTarget: function (event) {
            return event.target || event.srcElement;
          },
          preventDefault: function (event) {
            if (event.preventDefault) {
              event.preventDefault();
            } else {
              event.returnvalue = false;
            }
          },
          stopPropagation: function (event) {
            if (event.stopPropagation) {
              event.stopPropagation();
            } else {
              event.cancelBubble = true;
            }
          }
        }
        

      事件委托

      • 事件处理程序数量关系到页面性能,因为每个函数都是对象,会占用内存
      • 利用事件冒泡,只指定一个事件处理程序,管理某一类型的所有事件;
      • 为document对象添加一个事件处理程序,处理页面上发生的某种特点类型的事件:document对象访问快,只添加一个事件处理程序所需DOM的引用少,用时短,占内存空间小
    • Array常用函数

      检测数组

      if(Array.isArray(value)) {
      }
      

      转换方法

      var colors =['red','blue','green'];
      alert(colors.toString());  //red,blue,green
      alert(colors.join('-'));   //red-blue-green
      
      

      栈方法

      • last-in-first-out
      • push():将任意数量的参数,逐个添加到数组末尾,并返回修改后数组的长度;
      • pop():从数组末尾移除最后一项,然后返回移除的项。
      var colors = new Array();
      var count = colors.push('red','blue');
      alert(count.length);      //2
      
      count.push('black');
      alert(count.length);      //3
      
      var item = count.pop();
      alert(item);             //'black'
      alert(count.length);     //2
      

      队列方法

      • first-in-first-out
      • shift():移除数组的第一项并返回该项,同时将数组长度减1;
      • unshift():在数组前端添加任意个项,并返回新数组的长度。
      var num = [1,2,3];
      num.push(4);
      var item = num.shift();
      alert(item);        //1
      alert(num.length)   //3
      num.unshift(5);
      alert(num.length);  //4
      

      重排序

      • reverse():反转数组项的顺序
      • sort():调用每个数组项的toString()转型方法,然后比较得到的字符串,确定如何排序
      function compare(value1, value2) {
           if (value1 < value 2) {
               return -1;
           } else if (value1 > value2) {
               return 1;
           } else {
               return 0;
           }
      }
      
      var values = [0,1,4,2,10];
      values.sort(compare);
      alert(values);  //0,1,2,4,10
      

      操作方法

      • concat():创建当前数组的副本,将接收到的参数添加到副本的末尾,返回新构建的数组;
      • slice():参数为起始和结束项位置,返回起始和结束位置之间的项不包括结束位置,没有结束位置,则到末尾,不影响原始数组;
      • splice():参数为删除项的起始位置,项数,插入的项。返回一个数组,包含从原始数组中删除的项(如没有删除则返回一个空数组);
      var colors = ['red','green'];
      var colors2 = colors.concat('yellow',['blue','purple']);
      alert(colors2);    //red,green,yellow,blue,purple
      
      var colors3 = colors2.slice(2);    //yellow,blue,purple
      var colors4 = colors2.slice(1,4);  //green,yellow,blue
      
      var removed = colors2.splice(0,2);  //red,green
      alert(colors2);                     //yellow,blue,purpel  
      
      var removed2 = colors2.splice(1,0,'red','green');  //空数组
      alert(colors2);                     //yellow,red,green,blue,purple
      

      位置方法

      • indexOf():参数为要查找的项和起点位置索引,返回查找项所谓位置索引,为找到返回-1
      • lastIndexOf()
      var num = [1,2,34,5,4,2,6];
      alert(num.indexOf(2));   //1
      alert(num.indexOf(2,3);  //5
      

      迭代方法

      • every():数组中每一项运行给定函数,每一项都返回true,则返回true;
      • some(): ...,任意项返回true,则返回true;
      • filter(): ...,返回该函数会返回true的项组成的数组;
      • forEach(): ...,没有返回值;
      • map(): ...,返回每次函数调用的结果组成的函数。
      var nums = [1,2,3,4,5];
      var everyResult = nums.every(function(item,index,array) {
          return (item > 2);
      })
      alert(everyResult);   //false
      
      var someResult = nums.some(function(item,index,array) {
          return (item > 2);
      })
      alert(someResult);   //true
      
      var filterResult = nums.filter(function(item,index,array) {
          return (item > 2);
      })
      alert(filterResult);   //[3,4,5]
      
      var mapResult = nums.map(function(item,index,array) {
          return (item * 2);
      })
      alert(mapResult);   //[2,4,6,8,10];
      
      

      归并方法

      • reduce():四个参数,前一个值,当前值,项的索引,数组对象
      var values = [1,2,3,4,5];
      var sum = values.reduce(function(prev,cur,index,array) {
          return prev + cur
      })
      alert(sum);    //15
      
    • string常用函数

      字符方法

      var stringvalue = 'Hello, world!';
      alert(stringvalue.charAt(2))
      

      字符操作方法

      • concat(): same as Array;
      • slice(): same as Array;
      • substring: same as slice;
      • substr: 第二个参数表示返回的个数

      字符串位置方法

      • indexOf()
      var stringValue = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit';
      var positions = [];
      var pos = stringValue.indexOf('e');
      while(pos > -1) {
        positions.push(pos);
        pos = stringValue.indexOf('e',pos + 1);
      }
      alert(positions);  //[3,24,32,35,52]
      

      trim()

      创建一个字符串的副本,删除前置及后缀的所有空格,返回结果;

      字符串大小写转换

      • toLowerCase()
      • toUpperCase()
      • toLocalLowerCase()
      • toLocalUpperCase()

      字符串匹配方法

      var text = 'cat, bat, sat, fat';
      var result = text.replace('at','ond);  //'cond, bat, sat, fat'
      result = text.replace(/at/g,'ond');    //'cond, bond, sond, fond'
      
      result.split(',');                     //['cond','bond','sond','fond']
      
    • ES5+ES6

    • 框架

    • 手动实现MVC

    • 衍生部分

    • HTTP1/2理解,状态码,优化,缓存控制

    • 页面加载过程

      • 输入URL
      • 解析URL获取协议,主机,端口,path,组装http请求报文,获取主机ip地址;
      • 打开socket与目标ip地址建立TCP链接:浏览器与远程Web服务器通过TCP三次握手协商来建立一个TCP/IP连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
      • 发送HTTP请求,服务器接受,检查缓存,返回对应状态码
      • 浏览器接受响应,关闭TCP,检查响应状态码,进行缓存,解码
      • 解析HTML文档,构建DOM树,下载资源,构建CSSOM树,执行js脚本
    • TCP三次握手,四次挥手

    • XSS与CSRF

    • 学习经历和方法

    • 性能优化

    • 单元测试

    • React+Reduct

    • 模块机制 AMD CMD commonjs

    • webpack

    相关文章

      网友评论

          本文标题:前端面试常见知识点总结

          本文链接:https://www.haomeiwen.com/subject/tsrebttx.html