JavaScript笔试面试题收集(四)

本系列主要在于对自己的日常学习的内容做一个归纳整理,同时分享一些平时遇到的一些比较好的面试题.

通过对笔试面试题的学习,强化自己的所学知识面.

关于形参的传参问题

1
2
3
(function(foo){
return typeof foo.foo.bar;
})({ foo:{ bar: 1 } })

答案: number
解析: 其实这题考了我们闭包以及形参传参的问题,首先,我们将整体看成一个自执行函数,函数的变量是{ foo:{ bar: 1 } },那么我们可以把这一题简化一下:(当然,这个对象并不是存在于全局作用域的,我们只是把它拆开,做个比喻)

1
2
3
4
var baz = { foo:{ bar: 1 } }
(function(foo){
return typeof foo.foo.bar;}
})(baz)

那么现在就很明显了,其实就是把baz作为参数传递到这个自执行函数中,理解了这第一步,那么我们要先了解一下”左值”的概念,就是当我们遇到foo.foo.bar这一串的时候,可能很多同学很疑惑,怎么传了两次参数,其实两次参数的作用是不同的,执行这段代码,那么会先查找左边的值,并传入这个参数.

那么我们再简化一下这一题

1
2
3
4
var baz = { foo:{ bar: 1 } }
(function(baz){
return typeof baz.foo.bar;}
})(baz)

到这里,结果就很明显了,最后返回值就是

1
typeof { foo:{ bar: 1 } }.foo.bar

那么,自然结果就是number啦

关于作用域的问题

1
2
3
4
5
var x = 1;
if (function f(){}) {
x += typeof f;
}
console.log(x) // 1undefined

这一题比较简单,但是考的是细节,我们需要了解function f(){}这个函数,其实在括号中,它的作用域就仅仅是在括号中了,但是平常我们不能这样做,因为这是不符合ES语法规范的.

关于闭包的问题

1
2
3
4
5
6
7
;(function(x){
console.log(x) // 1
console.log(delete x) // false
console.log(x) // 1
return x
console.log(x) // 1
})(1)

这一题主要是考察我们对闭包中形参和实参的处理问题.

这里给出一些个人理解,不一定正确:

首先,我们要明白,其实形参在其函数内,也是有一个在局部作用域中的函数定义的操作的.也就是隐式地声明了这个形参,然后才把这个形参进行赋值

1
2
3
4
5
6
7
8
;(function(x){
var x // 这里是打了个比方
x = 1 // 这里是打了个比方
console.log(delete x) ;
console.log(x)
return x
console.log(x)
})(1)

对于delete操作符,我们知道,如果成功删除,则会返回true,不成功则返回false.

同时,当我们使用var定义的变量,是无法使用delete操作符进行删除的

1
2
3
var a
a = 1
delete a // false

关于闭包的参数问题

1
2
3
;(function f(f){
return typeof f(); // number
})(function(){ return 1; });

这一题还是关于自执行函数的传参,乍看可能有点懵逼,但是实际很简单,我们把这个自执行函数中打印出一个东西,你就明白了

1
2
3
4
;(function f(f){
console.log(f) // function(){ return 1; }
return typeof f(); // number
})(function(){ return 1; });

传进去的f就是一个函数,而在进行判断的时候是用的 typeof f() 我们会发现这个时候f已经被执行了,执行自然就会返回结果1,对1 进行类型判断,自然就是number了.

关于函数闭包的执行问题

1
2
3
4
5
6
7
8
9
10
11
function test() {
var i = 0;
var f1 = function() {
return ++i
}
return f1
}
var fn1 = test();
var fn2 = test();
console.log(fn1 == fn2) // false
console.log(fn1() + fn2() + fn1() + fn2()) // 6

fn1和fn2其实都是对test中返回值的引用,打印这两个值,都是一个函数,也就是f1

但是,fn1和fn2都是对test()函数值的浅拷贝,因此二者并不相等,返回false

fn1和fn2是两个完全不同的引用,引用的对象都是f1,所以我们每执行一次,i就会加一.

所以fn1执行一次,就会加一,fn1第一次是1,第二次执行是2,所以.fn1和fn2都执行两次,值就是6了

文章目录
  1. 1. 关于形参的传参问题
  2. 2. 关于作用域的问题
  3. 3. 关于闭包的问题
  4. 4. 关于闭包的参数问题
  5. 5. 关于函数闭包的执行问题
|