JavaScript总是给人以惊喜,学习不止,进步不断,今天继续补充JS容易搞错的几道笔试/面试题,为了秋招继续努力,欢迎一起为秋招努力的小伙伴共勉
系列笔记:
”老生常错“的this与作用域相关
Q1. 下面程序的输出结果是?
1 | var length = 10; |
output:
1 | 10 |
这个我做错在第二个输出上,其实对this
了解后就知道,第一个输出10
应该是很显然的:虽然在程序执行时,使用了obj.method
方法,让this指向了obj
,但是真正的函数执行在函数体内部,也即当fn()
执行的时候,this
是指向window
的,所以第一次执行结果是10
那么这里第二次执行arguments[0]
为什么结果是2
?
分析下在method(fn,1)
执行时,经历了什么: 首先两个参数fn
和1
会被放入arguments
中,在arguments
中第一个参数就是我们传入的函数;接下来fn
执行,此时this
没有绑定因此指向window
,输出10
。 然而到了arguments[0]()
这一句,相当于把arguments[0]
中的第一个参数拿来执行, 效果如下:
1 | arguments[0]() //执行,等同于下面的 |
arguments.length
就是它本身的长度(arguments是一个类数组,具有length属性),因此输出2
Q2. try..catch程序的输出结果
1 | (function () { |
输出结果:
1 | 1 |
我们都知道var
是在预编译阶段会有一个变量提升,这种类型很容易解决,但是当遇到在catch(x)
中与已有变量重名的情况,一定要区分两者之间的关系。
用变量提升的方法,把程序重写并分析如下:
1 | (function () { |
这样子就很清晰,之后注意预编译的过程,把变量和函数定义进行提升后,进行分析,会清楚很多
Q3. 下面程序的输出
1 | var x = 21; |
输出:
1 | undefined |
说实话,这个题目我没做错,我没做错,我没做错!
因为和Q2一样,而且还没有Q2难,一句话解释就是: 函数内部变量提升。 相当于
1 | var x = 21; |
那些诡异的边角知识
Q1. 运算符考点: 下面程序输出是什么?
1 | console.log(1 < 2 < 3); |
输出:
1 | true |
第一个输出结果是好理解的,主要看下第二个为什么是false
核心在于js怎么去解析<
和>
运算符。 在JS中,这种运算符是从左向右运算的,所以3>2>1
就被转换成了true>1
,而true
的值是1
,接着比较1>1
就返回false了。
Q2. typeof,下面输出结果是什么
1 | console.log(typeof typeof 1); |
答案是string
会输出string
,这个题目不仅仅是typeof的考察,也是对js运算的一个考察。 在js中一般有两种操作
- 赋值操作,例如
a = b
2>3
之类的,上面的题目提到过,是从左向右的顺序 - 取值操作, js问内存:
有没有见过这个家伙?
,比如console.log(a)
typeof a
都属于这个类型,是从右向左的
因此,这个题就被分解为typeof 1
返回"number"
,注意是一个字符串。 接下来typeof "number"
,返回string
Q3. typeof undefined == typeof NULL
输出结果是什么
首先搞清楚两点:
typeof undefined
输出是undefined
typeof null
输出是object
但是,另一方面,因为js对大小写敏感,null
≠ NULL
,所以typeof NULL
返回
undefined`
结果是: true
Q4. 递归设计。 实现一个函数,给该函数一个DOM节点,函数访问其所有子元素(所有子元素,不仅仅是直接子元素),每次访问子元素的时候,并为其传一个callback。
访问一个DOM tree,是一个经典的深度优先搜索的算法
1 | function Traverse(DOM,callback) { |