前端面试题

1、css实现垂直水平居中?
1.设置margin:0 auto
2.父元素设置为:position: relative; 
子元素设置为:position: absolute; 
距上50%,据左50%,然后减去元素自身宽度的距离就可以实现     
如果元素未知宽度,只需将上面例子中的margin: -50px 0 0 -50px;替换为:transform: translate(-50%,-50%); 
3.flex布局
    display: flex;//flex布局
    justify-content: center;//使子项目水平居中
    align-items: center;//使子项目垂直居中


2、获取随机数的方法
Math.random()    


3、JS中将一个变量强制改为浮点类型的方法?
parseFloat()


4、简述同步和异步的区别?
同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有等主线程任务执行完毕,
"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。


5、根据id获取元素的原生JS方法?
document.getElementById(id) 


6、js怎样添加,移除,移动,复制,创建和查找节点?
创建:createDocumentFragment()    //创建一个DOM片段
          createElement()   //创建一个具体的元素
          createTextNode()   //创建一个文本节点
添加: appendChild()
移除: removeChild()
替换: replaceChild()
查找: getElementsByTagName()    //通过标签名称
           getElementsByName()    //通过元素的Name属性的值
           getElementById()    //通过元素Id,唯一性
复制:  cloneNode()


7、 写一个function,清楚字符串前后的空格(兼容所有浏览器)
  //删除左右两端的空格
        function trim(str){
            return str.replace(/(^\s*)|(\s*$)/g, "");
        }
        //删除左边的空格
        function ltrim(str){
           return str.replace(/(^\s*)/g,"");
        }
         //删除右边的空格
        function rtrim(str){
         return str.replace(/(\s*$)/g,"");
        }
        //使用方法:trim(str)


8、js如何获取网页传输过来的参数a的值?
单个参数获取方法

function GetRequest() {
        var url = location.search; //获取url中"?"符后的字串
        if (url.indexOf("?") != -1) {  //判断是否有参数
            var str = url.substr(1); //从第一个字符开始 因为第0个是?号 获取所有除问号的所有符串
            strs = str.split("=");  //用等号进行分隔 (因为知道只有一个参数 所以直接用等号进分隔 如果有多个参数 要用&号分隔 再用等号进行分隔)
            alert(strs[1]);     //直接弹出第一个参数 (如果有多个参数 还要进行循环的)
        }


//正则方法
function GetQueryString(name)
{
     var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
     var r = window.location.search.substr(1).match(reg);
     if(r!=null) return  unescape(r[2]); return null;
}
 
// 调用方法
alert(GetQueryString("参数名1"));
alert(GetQueryString("参数名2"));
alert(GetQueryString("参数名3"));

//传统方法
function UrlSearch() 
{
   var name,value; 
   var str=location.href; //取得整个地址栏
   var num=str.indexOf("?") 
   str=str.substr(num+1); //取得所有参数   stringvar.substr(start [, length ]

   var arr=str.split("&"); //各个参数放到数组里
   for(var i=0;i < arr.length;i++){ 
    num=arr[i].indexOf("="); 
    if(num>0){ 
     name=arr[i].substring(0,num);
     value=arr[i].substr(num+1);
     this[name]=value;
     } 
    } 

var Request=new UrlSearch(); //实例化
alert(Request.id);


9、第1个人10岁,第2个比第1个人打2岁,依次递推,请用递归编写一个方法,可以计算出第8个人多大?(js语言编写)

    function a(n){
        var age = 0;
        if(n==1){
            age = 10;
        }else{
            age=a(n-1)+2;
            // console.log(age)
        }
        return age
    }
    console.log(a(8))


10、一个长度不超5位的正整数转换成对应的中文字符串,例如20876 返回‘两万零八百七十六’(js语言编写)

        var chnNumChar = ["零","一","二","三","四","五","六","七","八","九"];
        var chnUnitChar = ["","十","百","千","万"];

        function SectionToChinese(section){
            var strIns = '', chnStr = '';
            var unitPos = 0;
            var zero = true;
            while(section > 0){
                var v = section % 10;
                if(v === 0){
                    if(!zero){
                        zero = true;
                        chnStr = chnNumChar[v] + chnStr;
                    }
                }else{
                    zero = false;
                    strIns = chnNumChar[v];
                    strIns += chnUnitChar[unitPos];
                    chnStr = strIns + chnStr;
                }
                unitPos++;
                section = Math.floor(section / 10);
            }
            return chnStr;
        }

        alert(SectionToChinese(12322));

https://blog.csdn.net/huangbaokang/article/details/78465301


11、从输入URL到页面展示的详细过程
    1、输入网址
    2、DNS解析
    3、建立tcp连接
    4、客户端发送HTPP请求
    5、服务器处理请求 
    6、服务器响应请求
    7、浏览器展示HTML
    8、浏览器发送请求获取其他在HTML中的资源。

https://www.cnblogs.com/xianyulaodi/p/6547807.html

12、什么是生命周期

Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、
卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册js方法,
可以让我们用自己注册的js方法控制整个大局,在这些事件响应方法中的this直接指向的是vue的实例。

beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。

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

beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。

mounted
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。

beforeUpdate
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,
这不会触发附加的重渲染过程。

updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,
你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
该钩子在服务器端渲染期间不被调用。

beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。

destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
 该钩子在服务器端渲染期间不被调用。

13、vue常用指令
v-model双向绑定数据,v-for循环,v-show 显示与隐藏,v-if显示与隐藏  (dom元素的删除添加),v-bind属性绑定


14、如何理解vue中MVVM模式?
MVVM全称是Model-View-ViewModel;vue是以数据为驱动的,一旦创建dom和数据就保持同步,每当数据发生变化时,
dom也会变化。DOMListeners和DataBindings是实现双向绑定的关键。DOMListeners监听页面所有View层DOM元素的变化,
当发生变化,Model层的数据随之变化;DataBindings监听Model层的数据,当数据发生变化,View层的DOM元素随之变化。


15、vue的优点
1.低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,
当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
2.可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
3.独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,
使用Expression Blend可以很容易设计界面并生成xml代码。
4.可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。


16、请说下封装 vue 组件的过程?
首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。
然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。
子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。


17.this指向
在全局范围内,this指向全局对象(浏览器下指window对象)
对象函数调用时,this指向当前对象
全局函数调用时,应该是指向调用全局函数的对象。
使用new关键字实例化对象时,this指向新创建的对象
当用apply和call上下文调用的时候指向传入的第一个参数


18.call 和 apply
作用:动态改变某个类的某个方法的运行环境。
每个函数都包含两个非继承而来的方法
相同点:这两个方法的作用是一样的。
都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。
一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。
不同点:接收参数的方式不同。
call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文
改变为由 obj2 指定的新对象。 如果没有提供 obj2参数,那么 Global 对象被用作 obj2。 
apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
call ()和apply()作用一样,但是call()可以接收任何类型的参数,而apply()只能接收数组参数。

19.闭包
闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,
所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
闭包的作用在于,可以通过闭包,设计私有变量及方法。
闭包的三大特点为:
1、函数嵌套函数
2、内部函数可以访问外部函数的变量
3、参数和变量不会被回收。
优点 
- 希望一个变量长期驻扎在内存中 
- 避免全局变量的污染 
- 私有成员的存在 
缺点 
- 常驻内存,增大内存使用量,使用不当回造成内存泄漏;
自执行函数的好处
隔离作用域,避免全局作用域污染
模拟块级作用域


20.原型链和继承
原型:
每个函数都会默认有一个prototype属性,它是一个指针,指向此函数的原型对象。而构造函数作为一个函数,同样拥有自己的原型对象,
而通过构造函数生成的对象实例中,拥有一个_proto_ 属性,它指向构造函数的原型对象,我们把构造函数的原型对象称为对象实例的原型。

 访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着__proto__这条链向上找,这就是原型链。根据原型链可以确定继承关系。
由于所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。


21.关于Doctype、严格模式与混杂模式
所有的浏览器需要提供两种模式:兼容模式服务于旧式规则,严格模式服务亍标准规则。
? 浏览器根据 DOCTYPE 是否存在,以及使用的哪种 DTD 来选择要使用的呈现方法。
? 如果 XHTML、HTML 4.01 文档包含形式完整的 DOCTYPE,那举它一般以标准模式呈现。
? DOCTYPE 不存在或形式不正确会导致 HTML 和 XHTML 文档以混杂模式呈现。
? html5 既然没有 DTD,也就没有严格模式不宽松模式的区别,html5 有相对宽松的语法,实现时,已经
尽可能大的实现了向后兼容。


22.html5都有哪些新增标签?
新增标签:
   内容元素:article、footer、header、nav、section
   表单控件:calendar、date、time、email、url、search
   控件元素:webworker,websockt,Geolocation
移除标签:
   显现局元素:basefont,big,center,font,s,strike,tt,u
   性能较差元素:frame,frameset,noframes

23.Html5 语义化标签是什么?
html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析
即使在没有样式css情况下也以一种文档格式显示,并且是容易阅读的
搜索引擎的爬虫也依赖于html标记来确定上下文和各个关键字的权重,利于seo
使于都源代码的人对网站更容易将网站分块,便于阅读维护理解


24.页面导入样式时,使用link和@import 有什么区别
link属于XHTML标签,而@import 时css提供的
页面加载时,link会同时被加载,而@import引用的css会等到页面被加载完成在加载
@import只在IE5以上才能识别,而link时XHTML标签,无兼容问题
link方式的样式权重高于@import的权重

25常用浏览器内核
IE:trident
Firefox:gecko
safari:webkit
poera:blink
chrome:Blink


26.什么是面向对象的编程思想?
面向对象的编程的主要思想是把构成问题的各个事物分解成各个对象,
建立对象的目的不是为了完成一个步骤,而是为了描述一个事物在解
决问题的过程中经历的步骤和行为。对象作为程序的基本单位,
将程序和数据封装其中,以提高程序的重用性,灵活性和可扩展性。
类是创建对象的模板,一个类可以创建多个对象。对象是类的实例化。
面向对象有三大特性:封装,继承,多态。


27.异步编程有哪几种方法
      1.回调函数
     2.事件监听
     3.Promises对象
     4.发布/订阅(观察者模式)

如何实现浏览器内多个标签页之间的通信?
调用localstorge、cookies等本地存储方式

线程与进程的区别

一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。
但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。
但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。


你如何对网站的文件和资源进行优化?
期待的解决方案包括:
 文件合并
 文件最小化/文件压缩
 使用 CDN 托管
 缓存的使用(多个域名来提供缓存)


请说出三种减少页面加载时间的方法。
 1.优化图片
 2.图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)
 3.优化CSS(压缩合并css,如margin-top,margin-left...)
 4.网址后加斜杠(如www.campr.com/目录,会判断这个“目录是什么文件类型,或者是目录。)
 5.标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。
当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了。)
6.减少http请求(合并文件,合并图片)。

你都使用哪些工具来测试代码的性能?
Profiler, JSPerf(http://jsperf.com/nexttick-vs-setzerotimeout-vs-settimeout), Dromaeo


什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?
FOUC - Flash Of Unstyled Content 文档样式闪烁
<style type="text/css"media="all">@import "../fouc.css";</style>
而引用CSS文件的@import就是造成这个问题的罪魁祸首。IE会先加载整个HTML文档的DOM,然后再去导入外部的CSS文件,因此,在页面DOM加载完成到CSS导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。
 解决方法简单的出奇,只要在<head>之间加入一个<link>或者<script>元素就可以了。

null和undefined的区别?
null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN。
当声明的变量还未被初始化时,变量的默认值为undefined。 null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
null表示”没有对象”,即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

new操作符具体干了什么呢?
   1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
   2、属性和方法被加入到 this 引用的对象中。
   3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。

js延迟加载的方式有哪些?
defer和async、动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)、按需异步载入js


如何解决跨域问题?
jsonp、document.domain+iframe、window.name、window.postMessage、服务器上设置代理页面


documen.write和innerHTML的区别
document.write只能重绘整个页面
innerHTML可以重绘页面的一部分

哪些操作会造成内存泄漏?
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)

如何判断当前脚本运行在浏览器还是node环境中?
通过判断Global对象是否为window,如果不为window,当前脚本没有运行在浏览器中


HTML中href和src的区别
1. href 表示超文本引用(hypertext reference),在 link和a 等元素上使用。src 表示来源地址,在 img、script、iframe 等元素上。
2. src 的内容,是页面必不可少的一部分,是引入。href 的内容,是与该页面有关联,是引用。区别就是,引入和引用。

阻止事件冒泡,阻止默认事件
1.event.stopPropagation()方法
这是阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开,
2.event.preventDefault()方法
这是阻止默认事件的方法,调用此方法是,连接不会被打开,但是会发生冒泡,冒泡会传递到上一层的父元素;
3.return false  ;
这个方法比较暴力,他会同事阻止事件冒泡也会阻止默认事件;写上此代码,连接不会被打开,事件也不会传递到上一层的父元素;可以理解为return false就等于同时调用了event.stopPropagation()和event.preventDefault()

排序 

sort

冒泡
var canArr = [0,4,2,6,7,43,21];
function bubble(arr) { 
var s ;
for (var i =0;i<arr.length;i++) { 
  for (var j = 0; j < arr.length; j++) {
if (arr[j] < arr[j + 1]){ 
s = arr[j]; 
arr[j]=arr[j+1]; 
arr[j+1]=s; 

   }
}
 return arr;
}
console.log("冒泡排序:");
console.log(bubble(quchArr));


去重
//方法一
var arr = [1,23,1,1,1,3,23,5,6,7,9,9,8,5];
function removeDuplicatedItem(arr) {
   for(var i = 0; i < arr.length-1; i++){
       for(var j = i+1; j < arr.length; j++){
           if(arr[i]==arr[j]){
 8              arr.splice(j,1);//console.log(arr[j]);
              j--;
           }
       }
   }
   return arr;
}

arr2 = removeDuplicatedItem(arr);
console.log(arr);
console.log(arr2);


//方法二
//借助indexOf()方法判断此元素在该数组中首次出现的位置下标与循环的下标是否相等
var ar = [1,23,1,1,1,3,23,5,6,7,9,9,8,5];
function rep2(arr) {
    for (var i = 0; i < arr.length; i++) {
        if (arr.indexOf(arr[i]) != i) {
            arr.splice(i,1);//删除数组元素后数组长度减1后面的元素前移
            i--;//数组下标回退
        }
    }
    return arr;
}
var a1 = rep2(ar);
console.log(ar);
console.log(a1);


//方法四  借助新数组 通过indexOf方判断当前元素在数组中的索引如果与循环的下标相等则添加到新数组中
var arr = [1,23,1,1,1,3,23,5,6,7,9,9,8,5];
function rep(arr) {
    var ret = [];
    for (var i = 0; i < arr.length; i++) {
        if (arr.indexOf(arr[i]) == i) {
            ret.push(arr[i]);
        }
    }
    return ret;
}
arr2 = rep(arr);
console.log(arr);
console.log(arr2);


排序并且去重

//第一种
 var arr=[1,8,5,6,4,2,3,8,6,7,5,3];
       var res=[];
       for(var i=0;i<arr.length;i++){
         if(res.indexOf(arr[i])==-1){
             res.push(arr[i]);
          res.sort();
         }
      }
     console.log(res);


//第二种
  var arr=[1,8,5,6,4,2,3,8,6,7,5,3];
    var n={},r=[];  //n为hash表,r为临时数组
        for(var i=0;i<arr.length;i++){
          if(!n[arr[i]]){ //如果hash表中没有当前项
             n[arr[i]]=true;   /把当前项/存入hash表
         r.push(arr[i]); //把当前项
             r.sort();
             r.severse();
           }
         }
  console.log(r);

字符串反转
var str = "abcdef"; 
console.log( str.split("").reverse().join("") );
 


js求两个数的最大公约数
function getMax(n, m) {
    var min = n;
    (m < n) && (min = m);
    var max = 0;
    for (var i = 0, arr = []; i <= min; i++) {
        if (n % i == 0 && m % i == 0) {
            arr.push(i);
        }
    }
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] > arr[i + 1]) {
            arr[i] = [arr[i + 1], arr[i + 1] = arr[i]][0];
        }
 
    }
    max = arr[arr.length - 1];
    return max;
 
}

js实现n阶乘
方案一:利用while循环
function factorial(num){
        var result = 1;
        while(num){
            result *= num;
            num--;
        }
        return result;
    }

方案二:利用函数递归
function factorial(num){
        if(num <= 0){
            return 1;
        }else{
            return num*arguments.callee(num-1);
        }
    }

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值