前端面试拾遗——this、类型检测、es6
来源:互联网 发布:淘宝换货需要先签收吗 编辑:程序博客网 时间:2024/06/06 13:00
前端面试拾遗——this、类型检测、es6
前言
上一篇文章主要讲了我到某公司面试前端岗位时跟CSS有关的部分,这一篇文章将会总结一下面试过程中跟JS有关的部分,JS部分面试官主要问到了JS的类型以及ES6新增的类型,如何改变函数中this指针的指向,以及说一下平常使用过的ES6新特性。下面会有我面试后查阅资料后的相关解答。
this相关
关于this的详细介绍可以查看 MDN this 。在谈如何改变函数中this的指向时,我们先来谈一下this指向的究竟是什么。在传统的面向对象语言中,this指向的就是对象本身,那么JS是不是也一样呢?首先我们先执行下面的代码
function getThis() { console.log(this)}getThis(); //Windowvar ObjectB = { getThis: getThis}ObjectB.getThis() //Objectvar getThisA = ObjectB.getThisgetThisA() //Object
输出结果如下所示
如果this指向的是对象本身的话,那么三个输出应该是一样的,而在这里我们可以看到三个输出并不是完全相同。其实在JS中this指向的是执行上下文,什么是执行上下文呢,通俗来说也就是执行这个函数的对象。像第一次执行执行的对象是全局Window,而第二次执行是ObjectB,第三次执行也是全局Window。根据这个原理,我们只要改变执行函数的对象就能改变this的指向。执行函数的方式有以下方式:
- 直接调用
- 作为对象的方法调用
- call和apply方法
- bind方法
- 还有一个不太确定的就是箭头函数
直接调用和作为对象方法调用改变this指向在上个例子已经展示出来了,接下来着重介绍call、apply和bind方法,为何方便辨识对象下面定义类都使用构造函数的方法定义。
测试代码如下
var getThis = function() { console.log(this)}function ObjectA() {}objectA = new ObjectA()// 直接执行时getThis的this指向console.log("直接执行时getThis的this指向")getThis()// call方法改变getThis中this的指向console.log("call方法改变getThis中this的指向")getThis.call(objectA)// apply方法改变getThis中this的指向console.log("apply方法改变getThis中this的指向")getThis.apply(objectA)// bind方法改变getThis中this的指向console.log("bind方法改变getThis中this的指向")var newGetThis = getThis.bind(objectA)newGetThis()
执行结果如下所示
可以看出通过call,apply和bind方法可以轻松改变函数中this的指向。
还有就是箭头函数,相对与普通函数来说,箭头函数this的指向一定是声明他的对象,那么相对与普通函数来说,应该改变的却没有改变,那究竟算不算改变了指向呢?如果是面试的话可以跟面试官讨论一下,就从我的面试来说,面试官是不同一箭头函数改变this指向这种说法的。箭头函数跟普通函数this指向的测试如下
var ObjectA = function() { this.getThis = () => { console.log(this) } this.otherGetThis = function() { console.log(this) }}var objectA = new ObjectA()var getThis = objectA.getThisconsole.log("箭头函数this指向")getThis()var otherGetThis = objectA.otherGetThisconsole.log("普通函数this指向")otherGetThis()
运行结果如下
可以看到箭头函数的指向是没有改变的还是指向ObjectA而普通函数this指向了调用它的全局Window
类型检测
在面试过程中,面试官有问到关于JS类型检测的问题,之前也没有考虑过这个问题,就答了一个 instanceof
运算符,然后面试官接着就问除了 instanceof
呢或者是 instanceof
有什么缺陷。当时就没想起来,其实在JS中有 instanceof
和 typeof
两个关于类型检测的运算符,在《JavaScript高级程序设计》中有这种说法:当检测的是基础类型的时候使用 typeof
更好,而当检测的是引用类型的时候使用 instanceof
更好。为什么会有这种说法呢,我们可以看一下测试代码
var ObjectA = function() {}var objectA = new ObjectA()console.log("获取objectA的类型")console.log(typeof objectA)console.log("判断objectA是否为Object的引用")console.log(objectA instanceof Object)console.log("判断objectA是否为ObjectA的引用")console.log(objectA instanceof ObjectA)var num = 1console.log("判断num的类型")console.log(typeof num)console.log("判断num是否为Number的引用")console.log(num instanceof Number)num = new Number(1)console.log("判断重新赋值的num的类型")console.log(typeof num)console.log("判断重新赋值的num是否为Number的引用")console.log(num instanceof Number)
输出的结果如图所示
我们可以看到使用 typeof
运算精度只能是基础类型也就是 number
, string
, undefined
, boolean
, object
,要注意的是 null
和数组使用 typeof
运算符得到的也是 object
而 instanceof
运算符可以精确到是哪一种类型的引用例如测试程序中的ObjectA
,但 instanceof
也有一个缺陷就是对于直接赋值的数字,字符串,布尔值以及数组是不能将其识别为Number
,String
,Boolean
,Array
。这时候怎么将两者的优势结合起来让直接赋值的数字,字符串,布尔值和数组能直接获取到正确的类型呢?我主要是从loadash的源码中获取灵感的,我们可以使用Symbol.toStringTag
的方法获取各种类型的tag,其中Number
类型的tag为[object,Number]
,以此类推。而自定义的属性可一通过重写get[Symbol.toStringTag]
来自定义tag,测试的代码入下
class ObjectA { get [Symbol.toStringTag]() { return "ObjectA"; }}var objectA = new ObjectA()console.log("获取自定义类型的类型")console.log(Object.prototype.toString.call(objectA))var num = 1console.log("获取普通类型的对应的类型")console.log(Object.prototype.toString.call(num))num = new Number(1)console.log("获取引用类型的类型")console.log(Object.prototype.toString.call(num))
运行结果如下图所示
通过这种方法无论是直接赋值还是构造函数赋值,无论是内置类型还是自定义类型都能够识别,相对来说是比较通用的解决办法。
es6
我觉得现在前端的面试是肯定会问到的,所以在面试前特意复习了一下,然而到了面试的时候面试官问的关于es6的东西几乎都没有答上。面试官主要问了两个问题,es6新增了哪些数据类型;你使用过es6哪些新特性。
es6仅仅新增了一个数据类型那就是Symbol,关于Symbol的详细介绍可以参考 阮一峰的es6入门教程 。
至于es6的新特性那就多了,在这里列出常用的几种,数据解构,class,promise,构造器,Proxy,Reflect,箭头函数。
es6要展开写实在太多东西写了,所以就只给出了链接,方便以后查阅。
总结
这篇文章主要是总结了面试过程中面试官问到的关于JS语言层面的知识点,通过查阅资料后给出的解答。
- 前端面试拾遗——this、类型检测、es6
- 前端面试拾遗——CSS选择器、Flex布局、position
- 【拾遗】检测cin输入是否满足类型
- 【笔试/面试】—— linux 拾遗(一)
- 【笔试/面试】—— 计算机组成原理拾遗(一)
- 前端面试纪实(三):ES6的const和let
- C++拾遗--this指针
- web前端拾遗
- 面试拾遗(1)
- jsp、el、jstl——前端面试
- 前端面试宝典——来自cnblog
- 前端面试集锦——CSS篇
- 前端面试题目搜集——理论知识
- 前端面试宝典——来自cnblog
- 前端面试宝典——栈
- 前端面试必备——图
- 前端面试常见问题——字符串反转
- C#基础原理拾遗——引用类型的值传递和引用传递
- 会自动伸缩的文本输入框HPGrowingTextView
- 洛谷9月月赛--T2[T2]预生成密码
- 学习浅墨opencv入门教程三之综合实例犯错总结
- Math函数
- Struts2+Ajax实现检测用户名是否唯一
- 前端面试拾遗——this、类型检测、es6
- Android开发之线程池使用总结
- android点赞效果--LikeView
- 并发的HashMap为什么会引起死循环
- How to make 9-patch image downloaded from the Network
- Vue-01
- Tomcat在虚拟机下的Linux(ubuntu)上的安装与配置
- 使用jcrop进行头像剪切
- javaScript学习基础知识汇总