前端面试题及答案整理(一)(转)

各公司秋招很快就开始了,最近在准备面试的东西,干脆将发现的各类
面试题整理一下共享出来,大部分面试题是没有标准答案的,我给出的答案也是仅供参考,如果有更好的解答欢迎在评论区留言。

Part1 手写代码

现场手写代码是现在面试中很常见的一类面试题,考察基础的数据结构与算法能力。

1 数组去重的实现

  • 基本数组去重
Array.prototype.unique = function(){
    var result = [];
    this.forEach(function(v){
        if(result.indexOf(v) < 0){
            result.push(v);
        }
    });
    return result;
}
  • 利用hash表去重,这是一种空间换时间的方法
Array.prototype.unique = function(){
    var result = [],hash = {};
    this.forEach(function(v){
        if(!hash[v]){
            hash[v] = true;
            result.push(v);
        }
    });
    return result;
}

上面的方法存在一个bug,对于数组[1,2,‘1‘,‘2‘,3],去重结果为[1,2,3],原因在于对象对属性索引时会进行强制类型转换,arr[‘1’]和arr[1]得到的都是arr[1]的值,因此需做一些改变:

Array.prototype.unique = function(){
    var result = [],hash = {};
    this.forEach(function(v){
        var type = typeof(v);  //获取元素类型
        hash[v] || (hash[v] = new Array());
        if(hash[v].indexOf(type) < 0){
            hash[v].push(type);  //存储类型
            result.push(v);
        }
    });
    return result;
}
  • 先排序后去重
Array.prototype.unique = function(){
    var result = [this[0]];
    this.sort();
    this.forEach(function(v){
        v != result[result.length - 1] && result.push(v); //仅与result最后一个元素比较
    });
}
  • 利用ES6 Set去重
    //ES6环境下
    Array.prototype.unique = function(){
         return [...new Set(this)];
    }

2 快速排序的实现

方法一(尽可能不用js数组方法):

function quickSort(arr){
    qSort(arr,0,arr.length - 1);
}
function qSort(arr,low,high){
    if(low < high){
        var partKey = partition(arr,low,high);
        qSort(arr,low, partKey - 1);
        qSort(arr,partKey + 1,high);
    }
}
function partition(arr,low,high){
    var key = arr[low];  //使用第一个元素作为分类依据
    while(low < high){
        while(low < high && arr[high] >= arr[key])
            high--;
        arr[low] = arr[high];
        while(low < high && arr[low] <= arr[key])
            low++;
        arr[high] = arr[low];
    }
    arr[low] = key;
    return low;
}

方法二(使用js数组方法):

function quickSort(arr){
   if(arr.length <= 1) return arr;
   var index = Math.floor(arr.length/2);
   var key = arr.splice(index,1)[0];
   var left = [],right = [];
   arr.forEach(function(v){
       v <= key ? left.push(v) : right.push(v);
   });
   return quickSort(left).concat([key],quickSort(right));
}

另外要知道,快速排序的平均时间复杂度O(nlogn),最坏情况是有序的情况,时间复杂度为n的平方,另外快速排序是不稳定的。

Part2 JavaScript相关

1 JavaScript基础数据类型

JavaScript数据类型包括原始类型和引用类型,原始类型有五个:

  Number(数值) String(字符串) Boolean(布尔) Null(空) Undefined(未定义)

引用类型有一个:

 Object(对象)

通过typeof(x)可以返回一个变量x的数据类型“number”、“string”、“boolean”、“undefined”、"object",这里要注意一点:typeof运算符对于null类型返回的是object

《JavaScript高级程序设计》:
这实际上是JavaScript最初实现中的一个错误,后来被ECMAScript沿用了。现在null被认为是对象的占位符,从而解释了这一矛盾。但是从技术上来说,它仍然是原始值。

2 谈一谈JavaScript作用域链

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

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

3 如何理解JavaScript原型链

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

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

当访问对象的一个属性时, 首先查找对象本身, 找到则返回; 若未找到, 则继续查找其原型对象的属性(如果还找不到实际上还会沿着原型链向上查找, 直至到根). 只要没有被覆盖的话, 对象原型的属性就能在所有的实例中找到,若整个原型链未找到则返回undefined;

4 JavaScript变量声明提前

《JavaScript权威指南》中是这样解释的:JavaScript变量在声明之前已经可用,JavaScript的这个特性被非正式的称为声明提前(hoisting),即JavaScript函数中声明的所有变量(但不涉及赋值)都被“提前”至函数的顶部。

从一个例子来看:

var scope = "global";
function myFunc(){
    console.log(scope);
    var scope = "local";
}

控制台打印出来的不是“global”而是“undefined”,这是因为在myFunc这个函数的作用域中,局部变量scope声明被提前至函数顶部,而此时,scope仅声明,未赋值,因此输出undefined。实际上,上面的代码和下面的效果是一样的:

var scope = "global";
function myFunc(){
    var scope;
    console.log(scope);
    scope = "local";
}

5 如何理解和应用JavaScript闭包

关于闭包具体的定义文献中给的概念很抽象,我认为闭包是一种使函数能够都去其它函数的局部变量的语法机制。

举个例子:

function outFunc(){
    var name = "Vicfeel";
    function inFunc(){
        console.log(name);
    }
    return inFunc;
}
inFunc(); //控制台显示"Vicfeel"

这这个例子我们可以看出,在函数inFunc中依然可以访问outFunc的局部变量name。

闭包应用举例,模拟类的私有属性,利用闭包的性质,局部变量只有在sayAge方法中才可以访问,而name在外部也访问,从而实现了类的私有属性。

    function User(){
        this.name = "Vicfeel";  //共有属性
        var age = 23;    //私有属性
        this.sayAge:function(){
            console.log("my age is " + age);
        }
    }
    var user = new User();
    console.log(user.name); //"Vicfeel"
    console.log(user.age);  //"undefined"
    user.sayAge();   //"my age is 23"

要了解详细的闭包,推荐一下 阮一峰的网络日志-学习Javascript闭包(Closure)

6 new构建对象的本质

    function User(){
        this.name = "Vicfeel";
        this.age = 23;
    }

    var user = new User();

通过new操作符,实际上在构造函数User中完成了如下操作:

  • 创建一个新的对象,这个对象的类型是object;
  • 设置这个新的对象的内部、可访问性和prototype属性为构造函数(指prototype.construtor所指向的构造函数)中设置的;
  • 执行构造函数;
  • 返回新创建的对象。
    function User(){
        //this = {};
        //this.constructor = User;
        this.name = "Vicfeel";
        this.age = 23;
        //return this;
    }

    var user = new User();

如果构造函数默认返回的新创建的this对象,如果手动return 一个变量的话,如果该变量是原始类型则无效,如果是对象,则返回该对象。

7 JavaScript代理

当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。

比如我们需要向一个ul中动态添加很多个li,需要遍历li逐个添加点击事件

    <ul id=‘list‘></ul>
    var count = 100;
    var ulList = document.getElementById("list");
    //动态构建节点
    for(var i = count;i--;){
        var liDom = document.createElement(‘li‘);
        ulList.appendChild(liDom);
    }
    //绑定点击事件
    var liNode = ulList.getElementByTagName("li");
    for(var i=0, l = liNodes.length; i < l; i++){
        liNode[i].onClick = function(){
            //li点击事件
        }
    }   

众所周知,DOM操作是十分消耗性能的。所以重复的事件绑定简直是性能杀手。而事件代理的核心思想,就是通过尽量少的绑定,去监听尽量多的事件。如何做呢?答案是利用事件冒泡机制,对其父节点ul进行事件绑定(Event Bubble),然后通过event.target来判断是哪个节点触发的事件,从而减少很多EventHandler的绑定。

    var count = 100;
    var ulList = document.getElementById("list");
    //动态构建节点
    for(var i = count;i--;){
        var liDom = document.createElement(‘li‘);
        ulList.appendChild(liDom);
    }
    //绑定点击事件
    var liNode = ulList.getElementByTagName("li");
    liNode.onClick = function(e){
        if(e.target && e.target.nodeName.toUpperCase == "LI") {
            // li点击事件
        }
    }

发现新内容会持续更新...

博文作者:vicfeel
博文出处:http://www.cnblogs.com/vicfeel
本文版权归作者和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作!
如果阅读了本文章,觉得有帮助,您可以为我的博文点击“推荐一下”!

原文地址:https://www.cnblogs.com/qq575654643/p/11778484.html

时间: 2024-10-27 22:48:13

前端面试题及答案整理(一)(转)的相关文章

最全的web前端面试题及答案整理 你不得不看

面试web前端开发,不管是笔试还是面试,都会涉及到各种专业技术问题,今天小编整理了一些常见的web前端面试题及答案,希望对大家有所帮助. 1.常用那几种浏览器测试?有哪些内核(Layout Engine)? (Q1) 浏览器:IE,Chrome,FireFox,Safari,Opera. (Q2) 内核:Trident,Gecko,Presto,Webkit. 2. 说下行内元素和块级元素的区别?行内块元素的兼容性使用?(IE8 以下) (Q1) 行内元素:会在水平方向排列,不能包含块级元素,设

web前端面试题及答案

1.常用那几种浏览器测试?有哪些内核(Layout Engine)? 答: (Q1) 浏览器:IE,Chrome,FireFox,Safari,Opera.    (Q2) 内核:Trident,Gecko,Presto,Webkit. 2. 说下行内元素和块级元素的区别?行内块元素的兼容性使用?(IE8 以下) 答: (Q1) 行内元素:会在水平方向排列,不能包含块级元素,设置width无效,height无效(可以设置line-height),margin上下无效,padding上下无效. 块

前端面试题及答案,网络和优化

1.1.讲讲输入完网址按下回车,到看到网页这个过程中发生了什么 a. 域名解析 b. 发起TCP的3次握手 c. 建立TCP连接后发起http请求 d. 服务器端响应http请求,浏览器得到html代码 e. 浏览器解析html代码,并请求html代码中的资源 f. 浏览器对页面进行渲染呈现给用户 参考<输入URL到展现页面的全过程> 1.2.谈谈你对前端性能优化的理解 a. 请求优化: 合并JS和CSS,减少DNS查找次数,避免重定向,使用GET完成AJAX请求,减小请求中的Cookie,缓

史上最全前端面试题(含答案) - Web开发面试题

HTML+CSS 1.对WEB标准以及W3C的理解与认识 标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索几率.使用外 链css和js脚本.结构行为表现的分离.文件下载与页面速度更快.内容能被更多的用户所访问.内容能被更广泛的设备所访问.更少的代码和组件,容易维 护.改版方便,不需要变动页面内容.提供打印版本而不需要复制内容.提高网站易用性: 2.xhtml和html有什么区别 HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言 最主要的不同: XHTML 元素必须被正

Java -- Web前端面试题及答案(需更深入了解)

Web前端方面 1.CSS引入的方式有哪些? 1)外联:<link>标签 2)内联:<style>标签 3)元素内嵌:元素的style属性 2.CSS选择符有哪些? 标签选择符.类选择符.id选择符.组合选择符 3.你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? Ie(Ie内核) 火狐(Gecko) 谷歌(webkit) opear(Presto) 4."=="和"==="的不同 ==只比较值,===比较值和数据类型 5.什么是盒

前端面试题及答案,HTML

1.1.<img>标签上title属性与alt属性的区别是什么? alt属性是为了给那些不能看到你文档中图像的浏览者提供文字说明的.且长度必须少于100个英文字符或者用户必须保证替换文字尽可能的短. 这包括那些使用本来就不支持图像显示或者图像显示被关闭的浏览器的用户,视觉障碍的用户和使用屏幕阅读器的用户等. title属性为设置该属性的元素提供建议性的信息.使用title属性提供非本质的额外信息. 1.2.分别写出以下几个HTML标签:文字加粗.下标.居中.字体 加粗:<b>.&l

前端面试题及答案,CSS

1.1.请列举几种可以清除浮动的方法(至少两种) 浮动会漂浮于普通流之上,像浮云一样,但是只能左右浮动.正是这种特性,导致框内部由于不存在其他普通流元素了,表现出高度为0(高度塌陷). a. 添加额外标签,例如<div style="clear:both"></div> b. 使用br标签和其自身的html属性,例如<br clear="all" /> c. 父元素设置 overflow:hidden:在IE6中还需要触发hasL

一份来自于全球的前端面试题清单,看看老外喜欢考哪些题(部分有答案)

方括号中的蓝色标题是题目的出处,有些题目在原址内包含答案.搜集的大部分外国前端面试题没有做翻译,单词并不难,大家应该看得懂.题目旁边的方括号内, 简单记录了与此题相关的知识点.总共大概一千多道,包含国内的题目,如有错误,欢迎指正.有些原链可能已无法打开,有些可能需要代理才能查看. 一.HTML [HTML related interview questions] 1.What is doctype? Why do u need it? 2.What is the use of data-* at

web前端面试题整理(HTML篇)

web前端面试题整理(HTML篇)需要web前端课程工具和电子书,可以加: 33群105601600;  22群1203428331. h5的改进:新元素画布canvas: HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成音频audio视频video语义性: article,  nav ,  footer, section, aside, hgroup等.时间time 新属性拖放: draggable   <img draggable=&q