美文网首页
前端面试题

前端面试题

作者: 杀破狼real | 来源:发表于2017-07-23 12:21 被阅读0次

    HTML相关

    1、XHTML和HTML有什么区别

    HTML是一种基本的WEB网页实际语言,XHTML是一种基于XML的置标语言

    最主要的不同:

      1. XHTML 元素必须被正确的嵌套;
      1. XHTML 元素必须被关闭;
      1. XHTML 标签名必须用小写字母;
      1. XHTML 文档必须拥有根元素。

    2、什么是语义化的HTML?

      1. 直观的认识标签,对于搜索引擎的抓取有好处,用正确的标签做正确的事。HTML语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;
      1. 在没有css样式加持的情况下也以一种文档格式显示,并且是容易阅读的。搜索引擎的爬虫依赖于标记来确定上下文和各个关键字的权重,利于SEO。
      1. 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。

    3、常见的浏览器内核有哪些?

      1. Trident内核 IE、360、搜狗等
      1. Gecko内核 Netscape6及以上版本、Firefox
      1. Presto内核 Opera7及以上
      1. Webkit Safari、Chrome等

    4、H5有哪些新特性?移除了哪些元素?如何处理HTML5新标签的浏览器兼容问题?

    新特性

      1. canvas绘图;
      1. 本地离线存储localStorage长期存储数据,浏览器关闭后数据不丢失;
      1. sessionStorage数据在浏览器关闭后会自动删除;
      1. 用于媒体回放的video和audio;
      1. 语义化更好的内容标签如article、footer、header、nav、setion;
      1. 表单控件 calendar、date、time、email、url、search;
      1. 新的技术 web worker、web socket、geolocation。

    移除元素

      1. 纯表现元素 font、big、center、u、tt、s;
      1. 对可用性产生负面影响的元素:frame、frameset、noframes

    兼容

    IE8/IE7/IE6支持通过document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签。

    5、如何实现浏览器内多个标签页之间的通信?

    调用 localStroage、cookie 等本地存储方式

    6、HTML5为什么只需要写!DOCTYPE HTML?

    HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照他们应该的方式来运行);而HTML4.0基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。

    7、Doctype作用?标准模式与兼容模式各有什么区别?

    !DOCTYPE声明位于HTML文档中的第一行,处于html标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。

    标准模式的排版和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。

    8、label的作用是什么?怎么用?

    label标签是用来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。

    用法:

    <label for = "Name">Number:</label>
    <input type="text" name="Name" id="Name" />
    

    or

    <label>Data:<input type="text" name="B" /><label>
    

    CSS相关

    1、如何居中div?如何居中一个浮动元素?

    //居中div
    margin: 0 auto
    
    //居中浮动元素
    float:left;
    position:relative;
    left:50%;
    
    //居中绝对定位div
    position:absolute; 
    top: 50%; 
    left: 50%;
    margin:-100px 0px 0px -100
    

    2、经常遇到的浏览器兼容性有哪些?简述原因和解决办法?

    1)不同浏览器的标签,默认的margin和padding不同

    解决方案:加一个全局的*{margin:0;padding:0;}来统一。

    2)IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。

    解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性。

    3)在IE6,IE7中元素高度超出自己设置高度。

    原因:IE8以前的浏览器中会给元素设置默认的行高的高度导致的。

    解决方案:加上overflow:hidden或设置line-height为更小的高度。

    4)min-height在IE6下不起作用

    解决方案:添加 height:auto !important;height:xxpx;其中xx就是min-height设置的值。

    5)a(有href属性)标签嵌套下的img标签,在IE下会带有边框

    解决方案:加上a img{border:none;}样式。

    6)IE6下border:none无效

    解决方案:用:border:0或border:0 none;或border:none:border-color:transparent;,推荐用第三种方案。

    3、CSS3的新特性

    • 选择器(E:last-child)
    • @Font-face
    • 圆角
    • 多列布局
    • 阴影效果
    • 弹性盒子
    • 特效
    • 渐变效果

    4、CSS优化、提高性能的方法有哪些?

    • 加载性能,不要用import、压缩等,减少文件体积,减少阻塞加载,提高并发
    • 选择器性能 建议使用ID,类选择器,避免属性,后代选择器,通用选择器。组合选择器,优化最右边的关键选择器。
    • 渲染性能 是不是大量使用了 text-shadow?是不是开了字体抗锯齿?CSS 动画怎么实现的?合理利用 GPU 加速了吗?
    • 可维护性能 命名合理吗?结构层次设计是否足够健壮?对样式进行抽象复用了吗?

    5、简要说说CSS的元素分类?

    • 块级元素:div、h1、form、ul、li、p
    • 行内元素:span、a、label、input、img
    • CSS盒模型:内容、border、margin、padding

    6、CSS清除浮动的几种方法

    • 父级 div 定义 height;
    • 父级 div 定义 display:table;
    • 结尾处使用带 clear 属性的空 div;
    • 使用 CSS 的 overflow 属性(hidden、auto);
    • 使用 CSS的 :after 伪元素。

    7、display有哪些值?说明他们的作用。

    • block 块类型。默认宽度为父元素宽度,可设置宽高,换行显示。
    • none 缺省值。象行内元素类型一样显示。
    • inline 行内元素类型。默认宽度为内容宽度,不可设置宽高,同行显示。
    • inline-block 默认宽度为内容宽度,可以设置宽高,同行显示。
    • list-item 象块类型元素一样显示,并添加样式列表标记。
    • table 此元素会作为块级表格来显示。
    • inherit 规定应该从父元素继承 display 属性的值。

    8、position的值, relative和absolute分别是相对于谁进行定位的?

    • absolute 生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位。
    • fixed(老IE不支持)生成绝对定位的元素,通常相对于浏览器窗口或 frame 进行定位。
    • relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。
    • static 默认值。没有定位,元素出现在正常的流中
    • sticky 生成粘性定位的元素,容器的位置根据正常文档流计算得出

    9、CSS引入的方式有哪些? link和@import的区别是?

    内联 内嵌 外链 导入

    区别:同时加载

    前者无兼容性,后者CSS2.1以下浏览器不支持
    Link 支持使用javascript改变样式,后者不可

    10、CSS选择器 ~ 和 + 有什么区别?

    ~ 匹配所有兄弟元素,+ 匹配紧挨着的兄弟元素。

    另外:> 匹配所有子元素,(空格) 匹配所有后代元素。

    11、CSS中的常见单位?

      1. px: 绝对单位,页面按精确像素展示;
      1. em: 相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算,整个页面内1em不是一个固定的值;
      1. rem: 相对单位,可理解为“root em”,相当于根节点html的字体大小来计算。
      1. vm: viewpoint width,视窗宽度,1vm等于视窗宽度的1%;
      1. vh: viewpoint height,视窗高度,1vh等于视窗高度的1%。

    JS相关

    1、谈一谈JavaScript作用域链

    当执行一段 JavaScript 代码(全局代码或函数)时,JavaScript 引擎会为其创建一个作用域(又称为执行上下文),在页面加载后会首先创建一个全局作用域,然后每执行一个函数,会建立一个对应的作用域,从而形成一条作用域链。每个作用域都有一条对应的作用域链,链头是全局作用域,链尾是当前函数作用域。

    作用域链的作用是用于解析标识符,当函数被创建时(不是被执行),会将this、arguments、命名参数和该函数中所有局部变量添加到当前作用域中。当JavaScript需要查找变量x的时候(这个过程被称为解析),它首先会从作用域链中的链尾(也就是当前作用域)进行查找是否有x属性,如果没有找到就顺着作用域链继续查找,直到查找到链头(也就是全局作用域链),仍未找到该变量的话,就认为这段代码的作用域链上不存在x变量,并抛出一个引用错误的异常。

    2、原型是什么?原型链是什么?

    JavaScript中的每个对象都有一个prototype属性,我们称之为原型,而原型的值也是一个对象,因此它也有自己的原型,这样就串联起来了一条原型链,原型链的链头是object,它的prototype比较特殊,值为null。

    原型链的作用是用于对象继承,函数A的原型属性(prototype property)是一个对象,当这个函数被用作构造函数来创建实例时,该函数的原型将被作为原型赋值给所有实例对象,比如我们创建一个数组,数组的方法便从数组的原型上继承而来。

    原型五项规则

      1. 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了null除外)
      1. 所有的引用类型(数组、对象、函数),都有一个 __proto__(隐式原型)属性,属性值是一个普通的对象;
      1. 所有的函数,都有一个prototype(显式原型)属性,属性值也是一个普通的对象;
      1. 所有的引用类型(数组、对象、函数),__proto__ 属性值指向它的构造函数的prototype属性值;
      1. 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中寻找。

    3、构造函数,原型对象,实例对象三者之间的关系

    每创建一个函数,该函数都会自动带有一个prototype属性。该属性是一个指针,指向一个对象,该对象称之为原型对象。

    原型对象上默认有一个属性constructor,该属性也有一个指针,指向其关联的构造函数。

    通过调用构造函数产生的实例对象,都拥有一个内部属性,指向了原型对象。其实例对象能够访问原型对象上的所有对象和方法。

    总结:三者的关系是,每个构造函数都有一个原型对象,原型对象上包含着一个指向构造函数的指针,而实例都包含着一个指向原型对象的内部指针。通俗的讲,实例可以通过内部指针访问到原型对象,原型对象可以通过constructor找到构造函数。

    4、什么是闭包?闭包的作用?

    闭包就是函数中的函数,里面的函数可以访问外面函数的变量,外面的变量是这个内部函数的一部分。

    闭包就是函数能够记住并访问它的词法作用域,即使当这个函数在它的词法作用域之外执行时。

    闭包作用

      1. 使用闭包可以访问函数中的变量;
      1. 可以将变量长期保存在内存中,生命周期比较长。

    闭包使用场景

      1. 函数作为返回值
      1. 函数作为参数传递

    闭包不能滥用,否则会导致内存泄漏,影响网页的性能。闭包使用完成后,要立即释放资源,将引用变量指向 null 。

    4、JSON是什么

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它是基于 JavaScript 的一个子集。数据格式简单,易于读写,占用宽带小。是前后台交互最常见的一种数据格式。JSON也只不过就是一个js对象而已

    常用方法

    JSON.stringify({name: 'xiaoxin', age: 20}) //对象转为字符串
    JSON.parse('{name: \'xiaoxin\', age: 20}') //字符串转为对象
    

    5、JavaScript有几种类型的值?区别是什么?

    两大类

    • 栈: 原始数据类型(Undefined、Null、Boolean、Number、String、Symbol);
    • 堆: 引用数据类型(Object、Array、Function)

    区别

    原始数据类型 直接存储在栈(stack)中的简单数据段,占用空间小、大小固定,属于被频繁使用数据。

    引用数据类型 存储在堆(heap)中的对象,占用空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,首先会检索其在栈中的地址,然后从堆中获取实体。

    6、谈谈对this的理解?

    this 表示当前对象,this 的指向是根据调用的上下文来决定的,默认指向 window 对象,指向 window 对象时可以省略不写,例如

    this.alert() === window.this.alert() === alert()
    

    ,调用的上下文环境包括全局和局部。

    执行时才能确认值,定义时无法确认

    全局环境 就是在<script></script>中,这里的 this 始终指向的是 window 对象;

    局部环境

      1. 在全局作用域下直接调用函数,this 指向 window(普通执行);
      1. 对象函数调用,哪个函数调用就指向哪个对象(对象属性执行);
      1. 使用 new 实例化对象,在构造函数中 this 指向实例化对象(构造函数执行);
      1. 使用 call 或 apply 可以改变 this 的指向。

    7、同步和异步的区别?

    同步是一种线性执行的方式,执行的流程不能跨越。一般用于流程性比较强的程序,比如用户登录;

    异步是一种并行处理的方式,不必等待一个程序执行完,就可以执行其它任务。在程序中异步处理的结果通常使用回调函数来处理结果。在 JavaScript 中实现异步的方式一般是 Ajax 和 H5 新增的 Web Worker

      1. 同步会阻塞代码执行,而异步不会
      1. alert是同步,setTimeOut是异步

    何时需要异步?

      1. 在可能发生等待的情况
      1. 等待过程中不能像alert一样阻塞程序运行

    因此,所有的“等待的情况”都需要异步

    前端使用异步的场景?

      1. 定时任务:setTimeOut、setInterval
      1. 网络请求:ajax请求、动态img加载
      1. 事件绑定

    8、call和apply的区别?

    相同点 两个方法产生的作用是一样的,都用来改变当前函数调用的对象;

    不同点 调用的参数不同,

    foo.call(this, arg1, arg2, arg3) == foo.apply(this, args) == this.foo(arg1, arg2, arg3)
    

    9、eval是做什么的?

    把字符串参数解析成JS代码运行,并返回执行的结果。

    10、new操作符干了什么?

      1. 创建一个空对象 var obj = new Object();
      1. 设置原型链obj.__proto__ = Function.prototype;
      1. 让 Function 中的 this 指向 obj,并执行 Function 的函数体 var result = Function.call(obj);
      1. 判断 Function 的返回值类型,如果是值类型,返回 obj,如果是引用类型,就返回引用类型的对象。

    11、造成JS内存泄漏的情况?

    • 全局变量
    • 闭包
    • DOM被清空时,事件未被清除
    • 子元素存在引用

    12、写出下列结果?

    console.log(null == NaN); //false
    console.log(null == undefined); //true
    console.log(null == false); //false
    console.log(false == ''); //true
    console.log(false == 0); //true
    console.log(2 + 1 + '3'); //33
    console.log('2' + 1 + 3); //213
    console.log(Number(undefined)); //NaN
    console.log(Number(NaN)); //NaN
    console.log(Number(null)); //0
    console.log(Number('')); //0
    console.log(Number('123')); //123
    console.log(isNaN(23)); //false
    console.log(isNaN(NaN)); //true
    console.log(isNaN(undefined));//true
    console.log(isNaN(null)); //false
    console.log(typeof NaN); //number
    console.log(typeof '123'); //string
    console.log(typeof undefined); //undefined
    console.log(typeof 123); //number
    console.log(typeof null); //object
    console.log(typeof []); //object
    console.log(typeof Array); //function
    console.log(typeof console.log); //function
    console.log(NaN == NaN); //false
    console.log(undefined == undefined); //true
    

    13、JS绑定事件的方法?

    1)在DOM上直接绑定

    <input type="button" value="click me" onclick="hello()" />
     
    <script>
    function hello(){
        alert('hello')
    }
    </script>
    

    2)在JavaScript代码中绑定事件

    <input type="button" value="click me" id="btn">
     
    <script>
    document.getElementById('btn').onclick = function(){
        alert('hello');
    }
    </script>
    

    3)使用事件监听绑定

    W3C标准语法:

    element.addEventListener(event, function, useCapture)

    • event(必选)事件名,支持所有DOM事件;
    • function(必选)指定事件触发后执行的函数;
    • useCapture(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获;false,冒泡(default);
    <input type="button" value="click me" id="btn">
     
    <script>
    document
        .getElementById('btn')
        .addEventListener('click', function() {
            alert('hello);
        })
    </script>
    

    IE标准语法:

    element.attachEvent(event, function)

    • event(必须)事件类型,需要加“on”,例如“onClick”
    • function(必选)指定事件触发后执行的函数

    14、JavaScript事件流机制?

    1)冒泡型机制

    事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发

    2)捕获型机制

    事件从最不精确的对象(document对象)开始触发,然后到最精确。

    3)DOM事件流

    同时支持两种事件模型:捕获型事件和冒泡型事件,但是捕获型事件先发生。两种事件都会触发DOM中的所有对象,从document对象开始,也在document对象结束。

    事件捕获机制:事件从最上一级标签开始往下查找,直到捕获到事件目标;

    事件冒泡机制:事件从事件目标开始,往上冒泡直到页面的最上一级标签。

    事件的传播是可以阻止的:

    • 在W3C中,使用stopPropagation()方法;
    • 在IE下设置cancelBubble = true;

    在捕获的事件中stopPropagation()后,后面的冒泡过程也不会发生了

    阻止事件的默认行为:

    • 在W3C中,使用preventDefault()方法;
    • 在IE下设置window.event.returnValue = false

    不是所有事件都能冒泡,例如:blur、focus、load、unload等

    普通事件和事件绑定的区别?

    普通事件的方法不支持添加多个,最下面的事件会覆盖上面的;事件绑定可以添加多个

    15、JavaScript实现继承的几种方式?

    //父类
    function Animal(name) {
      this.name = name || 'Animal';
    
      this.sleep = function () {
        console.log(this.name + ' sleep');
      };
    }
    Animal.prototype.eat = function (food) {
      console.log(this.name + ' eating ' + food)
    };
    
    //原型链继承
    function Cat() {
    }
    Cat.prototype = new Animal();
    Cat.prototype.name = 'cat';
    
    //构造继承(不能继承原型方法)
    function Cat(name) {
      Animal.call(this);
      this.name = name || 'Tom';
    }
    
    //实例继承
    function Cat(name) {
      const instance = new Animal();
      instance.name = name || 'Tom';
      return instance;
    }
    
    //拷贝继承
    function Cat(name) {
      const animal = new Animal();
      for (let p in animal) {
        Cat.prototype[p] = animal[p];
      }
      Cat.prototype.name = name || 'Tom';
    }
    

    16、简要说明对模块化开发的理解?

    所谓模块化开发就是封装细节,提供使用接口,彼此之间互不影响,每个模块都是实现某一特定的功能。模块化开发的基础就是函数。

    17、Ajax的工作原理?写一个Ajax请求?

    Ajax的工作原理相当于在用户和服务器之间加了一个中间件(Ajax引擎),是用户操作与浏览器响应异步化。

    const xhr = new XMLHttpRequest();
    xhr.open('get', '/api', false);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) { // 0 请求未初始化 1 请求已建立 2 请求已发送 3 请求处理中 4 响应已完成
            if (xhr.status == 200) { // 2xx 请求成功 3xx 请求重定向 4xx 客户端错误 5xx 服务端错误
                console.log(xhr.responseText)
            }
        }
    };
    xhr.send(null);
    

    18、写出两种单例模式的实现?

    //自变量
    const singleton = {
        attr: 1,
        method: function () {
            return this.attr;
        }
    };
    
    //构造函数内部判断
    function Construct() {
        if(Construct.unique !== undefined){
            return Construct.unique;
        }
        this.name = 'name';
        this.age = 24;
        Construct.unique = this;
    }
    

    19、ES6中Array.isArray的代码实现?

    Array.isArray = function(obj) {
        return Object.prototype.toString.call(obj) == '[object Array]';
    }
    

    20、window.onload 和 DOMContentLoaded 区别

    • window.onload 页面的全部资源加载完才会执行,包括图片、视频等
    • DOMContentLoaded DOM渲染完即可执行,此时图片、视频还没有加载完

    21、随机打印1-100间的10个数字,去重后取出该10个数字之间的最大值和最小值。

    function randomMaxMin() {
      const numbers = [...new Set([...new Array(10)].reduce(origin => {
        origin.push(Math.ceil(Math.random() * 100));
        return origin;
      }, []))].sort((a, b) => a - b);
      return {min: numbers[0], max: numbers[numbers.length - 1]};
    }
    

    22、写一个长度一致的随机数

    let random = Math.random() + '0000000000';
    random = random.slice(0, 10);
    

    23、写一个能遍历数组和对象的forEach函数

    function forEach(obj, fn) {
      if (obj instanceof Array) {
        obj.forEach((item, index) => fn(index, item));
      } else {
        Object.keys(obj).forEach(key => fn(key, obj[key]));
      }
    }
    forEach({name: 'pp', age: 20}, (key, value) => {});
    forEach([1,2,3], (index, item) => {});
    

    24、写一个闭包的使用场景

    function isFirstLoad() {
      const _list = [];
      return function (id) {
        if(_list.indexOf(id) >= 0){
          return false;
        }else{
          _list.push(id);
          return true;
        }
      };
    }
    const firstLoad = isFirstLoad();
    console.log(firstLoad(10)); //true
    console.log(firstLoad(10)); //false
    console.log(firstLoad(20)); //true
    console.log(firstLoad(20)); //false
    

    25、动态创建10个标签,点击弹出对应的序号

    for (var i = 0; i < 10; i++) {
      (function (i) {
        var a = document.createElement('a');
        a.innerHTML = 'aaa' + (i + 1) + '</br>';
        a.addEventListener('click', function (e) {
          e.preventDefault();
          alert(i + 1);
        });
        document.body.appendChild(a);
      })(i);
    }
    

    最简单的方式用 let 替换 var 进行定义。

    26、写一个原型继承的案例

    function Elem(id) {
      this.elem = document.getElementById(id);
    }
    Elem.prototype.html = function (val) {
      const elem = this.elem;
      if(val){
        elem.innerHTML = val;
        return this;
      }else{
        return elem.innerHTML;
      }
    };
    Elem.prototype.on = function (type, fun) {
      const elem = this.elem;
      elem.addEventListener(type, fun);
      return this;
    };
    
    //exec
    const div1 = new Elem('app');
    div1.html('<p>Hello</p>').on('click', function () {
      alert('hello');
    }).html('<p>peter</p>');
    

    27、编写一个通用的事件监听函数?

    function bindEvent(elem, type, selector, fn) {
      if (fn == null) {
        fn = selector;
        selector = null;
      }
      elem.addEventListener(type, function (e) {
        if (selector) {
          //代理
          const target = e.target;
          if (target.matches(selector)) {
            fn.call(target, e);
          }
        } else {
          //不是代理
          fn(e);
        }
      });
    }
    
    const div1 = document.getElementById('div1');
    bindEvent(div1, 'click', 'a', function (e) {
      e.preventDefault();
      console.log(this.innerHTML);
    });
    
    const p1 = document.getElementById('p1');
    bindEvent(p1, 'click', function () {
      console.log(p1.innerHTML);
    });
    

    28、js写一个冒泡排序算法

    //冒泡排序
    function bubble() {
      const arr = [3, 1, 2, 4];
      for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length - i - 1; j++) {
          if (arr[j] > arr[j + 1]) {
            [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
          }
        }
      }
      console.log(arr);
    }
    bubble(); //[1, 2, 3, 4]
    

    29、JS写一个选择排序算法

    //选择算法
    function selection() {
      const arr = [3, 1, 2, 4];
      for (let i = 0; i < arr.length - 1; i++) {
        let min = i;
        for (let j = i + 1; j < arr.length; j++) {
          if (arr[j] < arr[min]) {
            min = j;
          }
        }
        [arr[i], arr[min]] = [arr[min], arr[i]];
      }
      console.log(arr);
    }
    selection(); //[1, 2, 3, 4]
    

    30、JS写一个插入排序算法

    
    //插入排序
    function insertion() {
      const arr = [3, 1, 2, 4];
      for (let i = 1; i < arr.length; i++) {
        for (let j = i - 1; j >= 0; j--) {
          if (arr[j] > arr[j + 1]) {
            [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
          }
        }
      }  
      console.log(arr);
    }
    insertion(); //[1, 2, 3, 4]
    

    31、写一个二分法的函数,返回给定值的索引

    //二分法找索引
    function dichotomy(arr, val) {
      let start = 0, end = arr.length - 1;
      while (start < end) {
        let middle = end == 1 ? 0 : Math.floor((start + end + 1) / 2);
        if (arr[middle] > val) {
          end = middle;
        } else if (arr[middle] < val) {
          start = middle;
        } else {
          return middle;
        }
      }
      return -1;
    }
    console.log(dichotomy([2,3,4,5], 3)); //1
    

    32、现有一个URL字符串“http://www.xxx.com?pn=0”,请写出删除其中的pn属性的js代码,请尽量实现完整,考虑全面。

    const arr = url.split('?');
    const new_url = arr[0] + '?' + arr[1].split('&')
        .reduce((origin, item) => {
          (item.split('=')[0] != 'pn') && origin.push(item);
          return origin;
        }, []).join('&');
    console.log(new_url); //http://www.xxx.com
    

    33、写一个函数,计算100以内的质数(只能被1或本身整除的数)。

    const calcPrimeNumbers = sum => (
      [...new Array(sum)].reduce((origin, item, index) => {
        const [number, arr] = [++index, []];
        for (let i = 1; i <= number; i++) {
          number % i == 0 && arr.push(i);
        }
        arr.length == 2 && origin.push(number);
        return origin;
      }, [])
    );
    console.log(calcPrimeNumbers(100)); //[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47 ]
    

    34、用 JS 实现一个无限累加的函数 add

    function add() {
      let sum = [...arguments].reduce((a, b) => a + b);
    
      const foo = function () {
        sum += [...arguments].reduce((a, b) => a + b);
        return foo;
      };
    
      foo.toString = () => sum;
    
      return foo;
    }
    console.log(add(1)(2)(3)(4)); // 10
    console.log(add(1,1)(2,2)(3,3)(4,4)); // 20
    

    35、手动实现一个sleep函数?

    function sleep(time) {
      const start = Date.now();
      while (true) {
        if(Date.now() - time > start)
        break;
      }
      console.log('休息了' + time / 1000 + '秒')
    }
    
    sleep(3000); //休息了3秒
    

    36、普通函数和箭头函数的区别?

      1. 箭头函数是匿名函数,不能作为构造函数,不能使用 new;
      1. 箭头函数不绑定 arguments,取而代之用rest参数(...)解决;
      1. 箭头函数不绑定 this,会捕获其所在的上下文的 this 值,作为自己的 this 值;
      1. 箭头函数没有原型属性。

    37、如何发送携带cookie的跨域请求?

    设置 withCredentials = true;

    38、根据id快速查找对应的元素

    const tree = {
      id: 'root',
      children: [
        { id: 1, children: [] },
        { id: 2, children: [] },
        { id: 3, children: [] },
        {
          id: 4,
          children: [
            { id: 5, children: [] },
          ]
        },
      ]
    };
    
    function find(id, node = tree) {
      if (node.id == id) {
        return node.children;
      }
    
      let target;
      node.children.forEach(child => {
        if (child.id == id) {
          target = child.children;
        } else {
          find(child.id, child);
        }
      });
      return target;
    }
    
    console.log(find(1)); // []
    

    39、实现对数组进行乱序

    var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    var sign = 1;
    
    arr.sort((a, b) => {
      sign = Math.random() > 0.5 ? 1 : -1;
      return (a - b) * sign;
    });
    
    console.log(arr);
    

    40、计算长度为100的数组前10个元素之和。

    var arr = [...new Array(100)].map((item, i) => i + 1);
    var result = arr.slice(0, 10).reduce((pre, current) => pre + current);
    console.log(result); // 55
    

    41、手动实现一个bind函数

    Function.prototype.myBind = function (oThis) {
      let args = [...arguments].slice(1);
      const context = this;
      const bound = function () {
        args = [...args, ...arguments];
        return context.apply(this instanceof F && oThis ? this : oThis, args);
      };
      const F = function () {
      };
      F.prototype = context.prototype;
      bound.prototype = new F();
      return bound;
    };
    
    function read(name, time, book) {
      console.log(`${name} is reading ${book} at ${time}`)
    }
    
    const tomRead = read.myBind(this, 'Tom', 'morning');
    tomRead('三体'); // Tom is reading 三体 at morning
    

    42、手动实现一个深拷贝

    function copy(obj) {
      const result = obj instanceof Array ? [] : {};
      for (let item in obj) {
        if (typeof obj[item] == 'object') {
          result[item] = copy(obj[item]);
        } else {
          result[item] = obj[item];
        }
      }
      return result;
    }
    

    6、HTTP状态码分别表示什么?

    2xx 成功

    • 200 OK,表示从客户端发来的请求在服务器端被正确处理
    • 204 No content,表示请求成功,但响应报文不含实体的主体部分
    • 205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
    • 206 Partial Content,进行范围请求

    3xx 重定向

    • 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
    • 302 found,临时性重定向,表示资源临时被分配了新的 URL
    • 303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
    • 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
    • 307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求

    4xx 客户端错误

    • 400 bad request,请求报文存在语法错误
    • 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
    • 403 forbidden,表示对请求资源的访问被服务器拒绝
    • 404 not found,表示在服务器上没有找到请求的资源

    5xx 服务端错误

    • 500 internal sever error,表示服务器端在执行请求时发生了错误
    • 501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
    • 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

    details

    • 100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分
    • 101 Switching Protocols 服务器将遵从客户的请求转换到另外一种协议
    • 200 OK 一切正常,对GET和POST请求的应答文档跟在后面
    • 201 Created 服务器已经创建了文档,Location头给出了它的URL。
    • 202 Accepted 已经接受请求,但处理尚未完成。
    • 203 Non-Authoritative Information 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝
    • 204 No Content 没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的
    • 205 Reset Content 没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容
    • 206 Partial Content 客户发送了一个带有Range头的GET请求,服务器完成了它
    • 300 Multiple Choices 客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。
    • 301 Moved Permanently 客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。
    • 302 Found 类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。
    • 303 See Other 类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取
    • 304 Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
    • 305 Use Proxy 客户请求的文档应该通过Location头所指明的代理服务器提取
    • 307 Temporary Redirect和302(Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是 POST,即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码: 当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只能跟随对GET请求的重定向。
    • 400 Bad Request 请求出现语法错误。
    • 401 Unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求。
    • 403 Forbidden 资源不可用。
    • 404 Not Found 无法找到指定位置的资源
    • 405 Method Not Allowed 请求方法(GET、POST、HEAD、Delete、PUT、TRACE等)对指定的资源不适用。
    • 406 Not Acceptable
      指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容
    • 407 Proxy Authentication Required
      类似于401,表示客户必须先经过代理服务器的授权。
    • 408 Request Timeout 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。
    • 409 Conflict 通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。
    • 410 Gone 所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。
    • 411 Length Required 服务器不能处理请求,除非客户发送一个Content-Length头。
    • 412 Precondition Failed 请求头中指定的一些前提条件失败
    • 413 Request Entity Too Large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头
    • 414 Request URI Too Long URI太长
    • 416 Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头
    • 500 Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求
    • 501 Not Implemented 服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求
    • 502 Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答
    • 503 Service Unavailable 服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头
    • 504 Gateway Timeout 由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答
    • 505 HTTP Version Not Supported 服务器不支持请求中所指明的HTTP版本

    相关文章

      网友评论

          本文标题:前端面试题

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