前端面试必掌握问题@令狐张豪

什么是闭包,优缺点?

闭包实际上就是一个嵌套函数,在一个函数内定义的一个函数。作为闭包的必要条件,内部函数应该访问外部函数中声明的私有变量、参数或者其他内部函数。当上述的两个条件实现后,此时如果在外部函数外调用这个内部函数,他就是成为了闭包函数。

【实例】 本例是一个经典的闭包结构
<script>
    function fn(x) {             //外部函数
        var a = x;               //外部函数的局部变量,并把参数值传递给它
        var b = function () {    //内部函数
            return a;            //内部函数访问外部函数的局部变量
        }           
        a++;                     //访问后,动态更新外部函数的变量
        return b;                //外部函数返回内部函数
    }
    var c = fn(5);
    console.log(c())
</script>

闭包的优点

  1. 方便调用上下文的局部变量
  2. 加强了封装性,可以达到对变量的保护作用
  3. 逻辑连续,当闭包作为另一个函数调用参数时,避免脱离当前逻辑而单独编写额外逻辑

闭包的缺点

  1. 由于闭包是驻留在内存中,会增大内存使用量,使用不当很容易造成内存泄露,降低程序的性能

三栏布局,都有几种?

  • 浮动布局
  • 弹性盒子
  • 定位布局
  • 网格布局
  • 表格布局

什么是原型链?原型链怎么实现继承?

定义原型

原型:声明函数时js会自动生成prototype,prototype会生成一个空对象(也就是原型对象),原型对象的constructor默认为你声明的对象

原型链.PNG
原型链

原型链:从实例往上寻找构造这个实例的相关联的对象,然后在这个关联的对象在往上查找创建它的上一级的原型对象,以此类推,一直到object.prototype终止,object.prototype是原型链的顶端。

任何一个实例对象通过原型链找到它上面的原型对象,这个原型对象上的方法和属性都被实例共享,这就是原型链的原理

原型链实现继承的几种方法
借用构造函数继承
function SuperType () {
  this.colors = ["red", "blue", "green"]
}
function SubType () {
  // 继承了SuperType
  SuperType.call(this)
  // 只能继承构造函数上的属性
}
  • 注意:
  1. 函数复用性不高
  2. 只能继承实例上的属性,原型上的方法不可见
组合继承(伪经典继承)
function SuperType (name) {
  this.name = name
  this.colors = ["red", "blue", "green"]
}
SuperType.prototype.sayName = function () {
  alert(this.name)
}
function SubType (name, age) {
  // 继承属性
  SuperType.call(this, name) // 第二次调用SuperType()
  this.age = age
}
//继承方法
SubType.prototype = new SuperType() // 第一次调用 SuperType()
Subtype.prototype.sayAge = function () {
  alert(this.age)
}
  • 注意:
  1. 组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为js中最常用的继承方式。
原型式继承
function object (o) {
  function F(){}
  F.prototype = o
  return new F()
}
  • 注意:
  1. 可以在不必预先定义构造函数的情况下实现继承,其本质是执行对给定对象的浅复制,而复制的副本还可以得到进一步的改造
    问题还是包含引用类型的属性都会被共享。
寄生式继承
function createAnother (original) {
  var clone = object(original) // 通过调用函数创建一个新对象
  clone.sayHi = function () { // 以某种方式来增强这个对象
    alert("hi")
  }
  return clone // 返回这个对象
}
  • 注意
  1. 基于某个对象或者某些信息创建一个对象,然后增强对象,最后返回对象,为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合继承一起使用
寄生组合式继承
function inheritPrototype (subType, superType) {
  var prototype = object(superType.prototype) // 创建对象
  prototype.constructor = subType // 增强对象
  subType.prototype = prototype // 指定对象
}

function SuperType (name) {
  this.name = name
  this.colors = {"red", "blue", "green"}
}
SuperType.prototype.sayName = function () {
  alert(this.name)
}
function SubType (name, age) {
SuperType.call(this, name)
  this.age = age
}
inheritPrototype(SubType, SuperType)
  • 注意
  1. 高效率只调用了一次构造函数,集寄生式继承和组合继承的优点于一身,是实现基于类型继承的最有效方式

什么是深拷贝什么是浅拷贝?

在了解深拷贝和浅拷贝之前我们先来了解一下堆和栈

堆stack 和 栈heap

什么是堆内存&&什么是栈内存?
  • stack:为自动分配的内存空间,它由系统自动释放;
  • heap:为动态分配的内存空间,它大小不一定,也不会自动释放
深拷贝和浅拷贝

使用场景:
深拷贝:在复杂对象里,对象的属性也是对象的时候;
浅拷贝:只复制一层对象,当对象的属性是引用类型时,实质上复制的是其引用,当引用指向的值发生变化的时候,原对象属性值也跟着变化;

浅拷贝

将原对象/原数组的引用,直接赋给新对象/新数组,新对象/数组只是原对象的一个引用


    
        let obj={a:1,arr:[2,3]};    
 
        let shallowObj=shallowCopy(obj);
        
        function shallowCopy(srcObj){
            var dest={};
            for(let prop in srcObj){
                    console.log(prop);
                if(srcObj.hasOwnProperty(prop)){
                    dest[prop]=srcObj[prop]
                    
 
                    }
 
                }// end of loop
                
                return dest;
            } 
        
//  当一个对象属性的引用值改变时,会导致另一个也改变;
    
    shallowObj.arr[1]=5;

深拷贝

深拷贝就是将原有对象重新拷贝一份,不论是修改哪一部分的值,都不会对原有对象造成影响。拷贝的永远是值,而不是引用。


你是怎么做响应式布局的?

什么是响应式布局?

简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。


令狐张豪.jpg
优点:
  • 面对不同分辨率设备灵活性强
  • 能够快捷解决多设备显示适应问题
缺点:
  • 兼容各种设备工作量大,效率低下
  • 代码累赘,会出现隐藏无用的元素,加载时间加长
  • 其实这是一种折中性质的设计解决方案,多方面因素影响而达不到最佳效果
  • 一定程度上改变了网站原有的布局结构,会出现用户混淆的情况
响应式设计——设置 Meta 标签

大多数移动浏览器将HTML页面放大为宽的视图(viewport)以符合屏幕分辨率。你可以使用视图的meta标签来进行重置。下面的视图标签告诉浏览器,使用设备的宽度作为视图宽度并禁止初始的缩放。在<head>标签里加入这个meta标签

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
viewport

通俗的讲,移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域,在具体一点,就是浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域

content属性值
  • width:可视区域的宽度,值可为数字或关键词device-width(device-width:定义输出设备的屏幕可见宽度。)
  • height:同width
  • intial-scale:页面首次被显示是可视区域的缩放级别,取值1.0则页面按实际尺寸显示,无任何缩放
  • maximum-scale=1.0, minimum-scale=1.0;可视区域的缩放级别,
  • maximum-scale用户可将页面放大的程序,1.0将禁止用户放大到实际尺寸之上。
  • user-scalable:是否可对页面进行缩放,no 禁止缩放

你是怎么用rem做自适应的?

什么是rem?

说到rem自然就会想到em,我们知道em是相对于父元素的字体大小的单位,那么rem则是相对于根元素也就是<html>元素的字体大小的单位。

如何用rem解决移动端适配
script方法
<script>
    window.addEventListener('orientationchange', setRem);
    window.addEventListener('resize', setRem);
    setRem();
    function setRem() {
        var html = document.querySelector('html');
        var width = html.getBoundingClientRect().width;
        html.style.fontSize = width / 16 + 'px';
    };
</script>

style方法
<style>
    // sass写法
    @function rem($px) {
        @return $px / 46.875 + rem;
    }
    //less写法
    @rem: 46.875rem;
    //stylus自行解决
    ?
</style>
用法:

如:元素宽300px,高500px;
传入参数即可:width:rem(300); height:rem(500);


vue的双向数据绑定

所谓双向数据绑定, 无非就是数据层和视图层中的数据同步, 在写入数据时视图层实时的跟着更新

实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。就必须要实现以下几点:

  1. 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
  2. 实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
  3. 实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
  4. mvvm入口函数,整合以上三者


    令狐张豪.png

说说vuex

什么是vuex?

是专门一个为vue.js应用程序开发的状态管理模式

vuex的运行机制
前端小学生.jpg
  • 在vue组件里面,通过dispatch来触发actions提交修改数据的操作。
  • 然后再通过actions的commit来触发mutations来修改数据。
  • mutations接收到commit的请求,就会自动通过Mutate来修改state(数据中心里面的数据状态)里面的数据。
  • 最后由store触发每一个调用它的组件的更新

如何使用promise封装axios?

class Http {
  //request 方法
  request(params) {
    return new Promise((resolve, reject) => {
      Axios({
         method: params.type || "get", //请求的方式
         url: params.url,              //请求的地址
         data: params.data,            //post 传的参数
        headers: params.headers       //headers 请求头
      }) 
        .then(res => { //请求成功触发
          if (res.data.code === 0) {
            resolve(res);
          } else {
            resolve(res);
          }
        })
        .catch(err => {
          reject(err.statusText); ///请求失败触发
        });
    });
  }
}
解释
  • 首先通过http类封装axios
  • 在http类中通过request方法return一个promise
  • 通过promise传递两个参数(resolve和reject)
  • 设置axios请求的方式、请求的地址、传递的参数
  • 通过判断code===0返回成功,反之请求失败触发

浏览器兼容问题如何解决?

Normalize.css

不同浏览器的默认样式存在差异,可以使用 Normalize.css 抹平这些差异。当然,你也可以定制属于自己业务的 reset.css

<link href="https://cdn.bootcss.com/normalize/7.0.0/normalize.min.css" rel="stylesheet">
html5shiv.js

解决 ie9 以下浏览器对 html5 新增标签不识别的问题。

<script type="text/javascript" src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
respond.js

解决 ie9 以下浏览器不支持 CSS3 Media Query 的问题。

<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>

详细查看解决方案


git常用指令

初始化git

git init

关联库

git remote add origin

克隆别人的项目

git clone

编写完之后提交到库里(更新)
  • 先合并 git pull
  • 再查状态 git status
  • 给你新写的内容加入缓存区 git add .
  • 起别名 git commit -m 'linghu'
  • 给他提交到库里 git push

什么是回调地狱?如何解决?

异步的JavaScript程序,或者说使用了回调函数的JavaScript的程序。简单说,就是函数作为参数层层嵌套(不利于维护和阅读)

例子:
setTimeout(function (name) {
    var catList = name + ','
    setTimeout(function (name) {
        catList += name + ','
        setTimeout(function (name) {
            catList += name
            console.log(catList)
        }, 200, 'Lion')
    }, 200, 'Jaguar')
}, 200, 'Panther')

// Panther,Janguar,Lion

解决回调地狱
1. 拆解 function:将各步拆解为单个的 function
function buildCatList(list, returnVal, fn) {
    setTimeout(function (name) {
        var catList = list === '' ? name : list + ',' + name
        fn(catList)
    }, 200, returnVal)
}

buildCatList('', 'Panther', getJanguar)

function getJanguar(list) {
    buildCatList(list, 'Janguar', getLynx)
}

function getLynx(list) {
     buildCatList(list, 'Lion', print)
}

function print(list) {
    console.log(list)
}

// Panther,Janguar,Lion

缺点:不利于后期维护

2. 通过 Promise 链式调用的方式
function buildCatList(list, returnVal) {
    return new Promise(function (resolve, reject) {
        setTimeout(function (name) {
            var catList = list === '' ? name : list + ',' + name
            resolve(catList)
        }, 200, returnVal)
    })
}

buildCatList('', 'Panther').then(function (res) {
    return buildCatList(res, 'Janguar')
}).then(function (res) {
    return buildCatList(res, 'Lion')
}).then(function (res) {
    console.log(res)
})

// Panther,Janguar,Lion

Promise 函数虽然改变了之前回调地狱的写法,但是在根本上还是函数套函数,看起来不是那么的美观


new操作符具体干了什么呢?

考察对new关键的深刻认识,是否对前端知识有专研,如果没有专研的人,肯定说创建了一个对象,恭喜你面试官知道你是小菜鸟来的,这次面试基本上没有太大的希望了。一定要对new过程的4个步骤非常清楚,这样才能深深地抓住面试官的心!

  1. 创建一个空对象
varobj=new Object();
  1. 设置原型链
obj.__proto__= Func.prototype;

3.让Func中的this指向obj,并执行Func的函数体。
4.判断Func的返回值类型:
如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。


sass和less都属于CSS预处理器。

Sass和Less的区别

sass:

  • Sass的安装需要安装Ruby环境。
  • sass有变量和作用域。
  • sass有函数的概念。

less:

  • Less基于Javascript(可以写js代码)。

Less和Sass处理机制不一样

less是通过客户端处理的,sass是通过服务端处理,相比较之下前者解析会比后者慢一点。


HTTP和HTTPS协议的区别

  • http是超文本传输协议,信息是明文传输
  • https则是具有安全性的ssl加密传输协议

HTTPS和HTTP的区别主要如下:

  1. https协议需要ca申请证书,并且大多数证书都是收费的。
  2. http以明文的形式传输信息,https则是具有安全性的ssl加密传输协议。
  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80(有时是8080),后者是443。
  4. http的连接简单,无状态;HTTPS协议是在HTTP协议的基础上,加上由SSL层,构建的可进行加密传输、身份认证的网络协议,比http协议安全。

js中数组的filter过滤器的理解

定义和用法

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意:filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。

语法

array.filter(function(currentValue,index,arr), thisValue)

参数说明

参数 描述
currentValue 必须。当前元素的值
index 可选。当前元素的索引值
arr 可选。当前元素属于的数组对象
thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"

实例

返回数组中所有年龄大于18的元素集合

<script>
        var info = [
            {
                id: '1',
                name: 'linghu',
                sex: "男",
                age: 24
            },
            {
                id: '2',
                name: 'yuchenglong',
                sex: "女",
                age: '15',
            }
        ];
        var arr = info.filter((item, index, arr) => item.age > 19)
        console.log(arr)
    </script>

结果是:

[{…}]
0: {id: "1", name: "linghu", sex: "男", age: 24}
length: 1
__proto__: Array(0)

想面试中基本还会问到animation、canvas、tranfroms、transform,请求职的小伙伴们务必去了解一下这些,祝各位求职成功!!!

一面二面详细视频链接(提取码:l10y)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,746评论 2 9
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,118评论 0 21
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 2,105评论 0 6
  • 1,javascript 基础知识 Array对象 Array对象属性 Arrray对象方法 Date对象 Dat...
    Yuann阅读 901评论 0 1