JavaScript面试出现频繁的一些易错点整理


Posted in Javascript onMarch 29, 2018

1.前言

这段时间,金三银四,很多人面试,很多人分享面试题。在前段时间,我也临时担任面试官,为了大概了解面试者的水平,我也写了一份题目,面试了几个前端开发者。在这段时间里面,我在学,在写设计模式的一些知识,想不到的设计模式的这些知识,就是面试题里面,频繁让人掉坑的考点。

所以,今天就总结一下,那些让人掉坑的考点。下面话不多说了,来一起看看详细的介绍吧。

2.面向对象编程

关于面向对象和面向过程,个人觉得这两者不是绝对独立的,而是相互相成的关系。至于什么时候用面向对象,什么时候用面向过程,具体情况,具体分析。

针对于面向对象编程的。知乎上有一个高赞回答:

面向对象: 狗.吃(屎)

面向过程: 吃.(狗,屎)

但是这个例子觉得不太优雅,我改一下了,举一个优雅些的小例子说明一下面向对象和面向过程的区别。

需求:定义‘守候吃火锅'

面向对象的思想是:守候.动作(吃火锅)

面向过程的思想是:动作(守候,吃火锅)

代码实现方面:

//面向对象
//定义人(姓名)
let People=function(name){
 this.name=name;
}
//动作
People.prototype={
 eat:function(someThing){
 console.log(`${this.name}吃${someThing}`);
 }
}
//守候是个人,所以要创建一个人(new一次People)
let shouhou=new People('守候','男',24);
shouhou.eat('火锅');

//面向过程
let eat=function(who,someThing){
 console.log(`${who}吃${someThing}`);
}
eat('守候','火锅');

结果都一样,都是输出‘守候吃火锅'。但是万一我现在吃饱了,准备写代码了。这下怎么实现呢?看代码

//面向对象
shouhou.coding=function(){
 console.log(this.name+'写代码');
}
shouhou.coding();
//面向过程
let coding=function(who){
 console.log(who+'写代码');
}
coding('守候');

结果也一样:‘守候写代码'

但是不难发现面向对象更加的灵活,复用性和扩展性更加。因为面向对象就是针对对象(例子中的:‘守候')来进行执行某些动作。这些动作可以自定义扩展。

而面向过程是定义很多的动作,来指定谁来执行这个动作。

好了,面向对象的简单说明就到这里了,至于面向对象的三大特性:继承,封装,多态这个自行上网查找资料。

3.this

使用 JavaScript 开发的时候,很多开发者多多少少会被 this 的指向搞蒙圈,但是实际上,关于 this 的指向,记住最核心的一句话:哪个对象调用函数,函数里面的this指向哪个对象。

下面分几种情况谈论下

3-1.普通函数调用

这个情况没特殊意外,就是指向全局对象-window。

let username='守候'
function fn(){
 alert(this.username);//undefined
}
fn();

可能大家会困惑,为什么不是输出守候,但是在细看一看,我声明的方式是let,不会是window对象

如果输出守候,要这样写

var username='守候'
function fn(){
 alert(this.username);//守候
}
fn();
//---------------
window.username='守候'
function fn(){
 alert(this.username);//守候
}
fn();

3-2.对象函数调用

这个相信不难理解,就是那个函数调用,this指向哪里

window.b=2222
let obj={
 a:111,
 fn:function(){
 alert(this.a);//111
 alert(this.b);//undefined
 }
}
obj.fn();

很明显,第一次就是输出obj.a,就是111。而第二次,obj没有b这个属性,所以输出undefined,因为this指向obj。

但是下面这个情况得注意

let obj1={
 a:222
};
let obj2={
 a:111,
 fn:function(){
 alert(this.a);
 }
}
obj1.fn=obj2.fn;
obj1.fn();//222

这个相信也不难理解,虽然obj1.fn是从obj2.fn赋值而来,但是调用函数的是obj1,所以this指向obj1。

3-3.构造函数调用

let TestClass=function(){
 this.name='111';
}
let subClass=new TestClass();
subClass.name='守候';
console.log(subClass.name);//守候
let subClass1=new TestClass();
console.log(subClass1.name)//111

这个也是不难理解,回忆下(new的四个步骤)就差不多了!

但是有一个坑,虽然一般不会出现,但是有必要提一下。

在构造函数里面返回一个对象,会直接返回这个对象,而不是执行构造函数后创建的对象

JavaScript面试出现频繁的一些易错点整理

3-4.apply和call调用

apply和call简单来说就是会改变传入函数的this。

let obj1={
 a:222
};
let obj2={
 a:111,
 fn:function(){
  alert(this.a);
 }
}
obj2.fn.call(obj1);

此时虽然是 obj2 调用方法,但是使用 了call,动态的把 this 指向到 obj1。相当于这个 obj2.fn 这个执行环境是 obj1 。apply 和 call 详细内容在下面提及。

3-5.箭头函数调用

首先不得不说,ES6 提供了箭头函数,增加了我们的开发效率,但是在箭头函数里面,没有 this ,箭头函数里面的 this 是继承外面的环境。

一个例子

let obj={
 a:222,
 fn:function(){ 
  setTimeout(function(){console.log(this.a)})
 }
};
obj.fn();//undefined

不难发现,虽然 fn() 里面的 this 是指向 obj ,但是,传给 setTimeout 的是普通函数, this 指向是 window , window 下面没有 a ,所以这里输出 undefined 。

换成箭头函数

let obj={
 a:222,
 fn:function(){ 
  setTimeout(()=>{console.log(this.a)});
 }
};
obj.fn();//222

这次输出 222 是因为,传给 setTimeout 的是箭头函数,然后箭头函数里面没有 this ,所以要向上层作用域查找,在这个例子上, setTimeout 的上层作用域是 fn。而 fn 里面的 this 指向 obj ,所以 setTimeout 里面的箭头函数的 this ,指向 obj 。所以输出 222 。

4.call和apply

call 和 apply 的作用,完全一样,唯一的区别就是在参数上面。

call 接收的参数不固定,第一个参数是函数体内 this 的指向,第二个参数以下是依次传入的参数。

apply接收两个参数,第一个参数也是函数体内 this 的指向。第二个参数是一个集合对象(数组或者类数组)

let fn=function(a,b,c){
console.log(a,b,c);
}
let arr=[1,2,3];

JavaScript面试出现频繁的一些易错点整理

如上面这个例子

let obj1={
 a:222
};
let obj2={
 a:111,
 fn:function(){
  alert(this.a);
 }
}
obj2.fn.call(obj1);

call 和 apply 两个主要用途就是

1.改变 this 的指向(把 this 从 obj2 指向到 obj1 )

2.方法借用( obj1 没有 fn ,只是借用 obj2 方法)

5.闭包

闭包这个可能大家是迷糊,但是必须要征服的概念!下面用一个例子简单说下

let add=(function(){
let now=0;
return {
 doAdd:function(){
 now++;
 console.log(now);
}
}
})()

然后执行几次!

JavaScript面试出现频繁的一些易错点整理

上图结果看到,now 这个变量,并没有随着函数的执行完毕而被回收,而是继续保存在内存里面。

具体原因说下:刚开始进来,因为是自动执行函数,一开始进来会自动执行,这一块

JavaScript面试出现频繁的一些易错点整理

然后把这个对象赋值给 add 。由于 add 里面有函数是依赖于 now 这个变量。所以 now 不会被销毁,回收。这就是闭包的用途之一(延续变量周期)。由于 now 在外面访问不到,这就是闭包的另一个用途(创建局部变量,保护局部变量不会被访问和修改)。

可能有人会有疑问,闭包会造成内存泄漏。但是大家想下,上面的例子,如果不用闭包,就要用全局变量。把变量放在闭包里面和放在全局变量里面,影响是一致的。使用闭包又可以减少全局变量,所以上面的例子闭包更好!

6.小结

在学设计模式的时候,遇到的知识点就是这一些了,这些知识点,也是我在群聊,社区里面,让人掉坑比较多的考点。这些知识,可以说是开发常用,面试常考的知识,还是建议大家深入些学习。上面那里也是简单的过一下而已。不算深入。如果大家对文章有什么建议,欢迎指点。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JavaScript 动态改变图片大小
Jun 11 Javascript
jquery中对表单的基本操作代码
Jul 29 Javascript
基于jQuery的图片左右无缝滚动插件
May 23 Javascript
超级好用的jQuery圆角插件 Corner速成
Aug 31 Javascript
jQuery选择器源码解读(八):addCombinator函数
Mar 31 Javascript
JS实现简单的键盘打字的效果
Apr 24 Javascript
基于JavaScript实现移动端点击图片查看大图点击大图隐藏
Nov 04 Javascript
JS实现图片的不间断连续滚动的简单实例
Jun 03 Javascript
AngularJs Understanding the Model Component
Sep 02 Javascript
javascript创建对象的3种方法
Nov 02 Javascript
关于webpack代码拆分的解析
Jul 20 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
Sep 14 Javascript
jQuery实现的上传图片本地预览效果简单示例
Mar 29 #jQuery
详解Javascript中new()到底做了些什么?
Mar 29 #Javascript
Koa2 之文件上传下载的示例代码
Mar 29 #Javascript
AngularJS下$http服务Post方法传递json参数的实例
Mar 29 #Javascript
Vue 将后台传过来的带html字段的字符串转换为 HTML
Mar 29 #Javascript
利用js实现前后台传送Json的示例代码
Mar 29 #Javascript
vue中Npm run build 根据环境传递参数方法来打包不同域名
Mar 29 #Javascript
You might like
PHP 文件上传功能实现代码
2009/06/24 PHP
PHP与SQL注入攻击防范小技巧
2011/09/16 PHP
使用php get_headers 判断URL是否有效的解决办法
2013/04/27 PHP
PHP在线生成二维码代码(google api)
2013/06/03 PHP
php使用Imagick生成图片的方法
2015/07/31 PHP
Yii使用DeleteAll连表删除出现报错问题的解决方法
2016/07/14 PHP
PHP xpath()函数讲解
2019/02/11 PHP
PHP笛卡尔积实现原理及代码实例
2020/12/09 PHP
简单三步,搞掂内存泄漏
2007/03/10 Javascript
jQuery 中关于CSS操作部分使用说明
2007/06/10 Javascript
防止xss和sql注入:JS特殊字符过滤正则
2013/04/18 Javascript
JS实现太极旋转思路分析
2016/12/09 Javascript
jQuery.Form实现Ajax上传文件同时设置headers的方法
2017/06/26 jQuery
深入浅出es6模板字符串
2017/08/26 Javascript
jQuery图片加载失败替换默认图片方法汇总
2017/11/29 jQuery
vue页面切换过渡transition效果
2018/10/08 Javascript
vue实现密码显示与隐藏按钮的自定义组件功能
2019/04/23 Javascript
vue实现图片预览组件封装与使用
2019/07/13 Javascript
Vue的属性、方法、生命周期实例代码详解
2019/09/17 Javascript
layui前端时间戳转化实例
2019/11/15 Javascript
Python数据类型详解(四)字典:dict
2016/05/12 Python
【Python】Python的urllib模块、urllib2模块批量进行网页下载文件
2016/11/19 Python
安装python时MySQLdb报错的问题描述及解决方法
2018/03/20 Python
学习Python爬虫的几点建议
2020/08/05 Python
CSS3 选择器 基本选择器介绍
2012/01/21 HTML / CSS
CSS书写规范、顺序和命名规则
2014/03/06 HTML / CSS
详解css3中的伪类before和after常见用法
2020/11/17 HTML / CSS
英国领先的奢侈品零售商之一:CRUISE
2016/12/02 全球购物
英国领先的在线高尔夫商店:Scottsdale Golf
2019/08/26 全球购物
参观监狱心得体会
2014/01/02 职场文书
电大毕业生自我鉴定
2014/04/10 职场文书
2014年辅导员工作总结
2014/11/18 职场文书
2015年暑期社会实践方案
2015/07/14 职场文书
《钓鱼的启示》教学反思
2016/02/18 职场文书
i5-10400f处理相当于i7多少水平
2022/04/19 数码科技
微信小程序 根据不同用户切换不同TabBar
2022/04/21 Javascript