一道简单的面试题引起的思考

版权声明:此文首发于个人简书帐号人生还有多少个二十年,转载请注明出处。前端

此处有几百字唠叨:
  当天,我早早起床,跨越上百千米,高德导航,路人指点,跌跌撞撞到达招聘会现场,当时已经是中午十二点半,吃了午饭(半瓶白开水),开始准备投递简历。绕场2周,发现能提供我想要的岗位(前端开发)的公司有十家左右。我总共带了5份简历,投递了4家中意的公司,其中2家直接现场面试。
  先说说最糟糕的那场面试: “我是来应聘Web开端的” (而后面试官纠正了一下,“Web前端”,尴尬了)。面试官接着就个人简历提了若干问题,基本上对简历的提问,未涉及技术细节,其中有“你github上的代码有人看吗?”(我又尴尬了,github上传的只是我本身作过的一些做品,上传的目的只是为了让HR可以看到我写的代码,从未在其它地方说起我有github帐号,天然是没人访问了)。当时由于紧张,还有近期睡眠不足,头脑很迟钝,问题大多回答得一塌糊涂。
  另外一场面试,面试官应该就是该公司的技术人员,提问的都是技术问题,问题不难,我基本上都会,由于本身平时也认真总结过一些,因此大多数回答地还算流畅。其中有两个问题把个人脸都丢光了。一个是,“处理过浏览器的哪些兼容性问题”,我想了一两分钟竟然仍是想不出(脑子短路了)。学了一年多前端的我真没接触过兼容性问题吗?其实,我接触过的有很多,据说过的也有很多,例子那么多,但是当时竟然想不出一个例子来(脑子短路了)。另外一个问题,就是我下面要说起的做用域问题,我当时思考的时间过久了...git

这是回忆中的面试题

(实际略有差别,不纠结了):github

function foo(){
    var a = b = 2;
}
foo();
alert(a);
alert(b);

question:说一下脚本的运行结果?
answer: 引用错误(FF中给出的错误提示:ReferenceError: a is not defined)。
reason:函数内声明的变量的做用域为函数做用域,在全局做用域中不能直接访问到函数内变量的值;而在函数中未声明就赋值的变量,在非严格模式下变成全局变量,成为window对象的一个属性,在严格模式下则会报错。此题的代码至关于如下代码:面试

var b = 2;
function foo(){
    var a =b;
}
foo();
alert(a);  
alert(b);

显然,全局做用域中是没有变量a的,因此alert(a)会致使错误,脚本没法继续执行。数组

         简单的面试题已结束, 哈哈,如今让我当一回面试官吧?浏览器


改编题1

function foo(){
    var a = b = 2;
}
foo();
alert(b);
alert(a);

question: 说一下脚本运行的结果?
result:
alert(b); //2
alert(a); //ReferenceError: a is not defined
reason:原理同上函数


改编题2

function foo(){
    var a = b = 2;
}
foo();
alert(typeof a);
alert(typeof b);

question: 说一下脚本运行的结果?
result:
alert(typeof a); //undefined
alert(typeof b); //number
attention: 未定义的变量的数据类型为undefined,并不会报错。code


改编题3

var a = 1;
var b = 1;
function foo(b){
    var a = b = 2;
}
foo(b);
alert(a);
alert(b);

question: 说一下脚本运行的结果?
result:
alert(a); //1
alert(b); //1
reason:这里我主要说一下b的结果,函数中参数中有变量b,至关于在函数中声明了变量b,调用函数的时候,因为基本类型的变量值是按值传递的,因此,函数的局部变量b被赋值为1,接着,又对局部变量b的值进行了更新,但这并不会影响全局变量b的值,故全局变量b的值仍然为1对象


改编题4

var a = 1;
var b = 1;
function foo(a,b){
       arguments[0]=2;
       arguments[1]=2;
       b = 3;
       console.log(a);
       console.log(b);
}
foo(a,b);
alert(a);
alert(b);

question: 说一下脚本运行的结果?
result:
console.log(a); //2
console.log(b); //3
alert(a); //1
alert(b); //1
reason: 此处我主要说一下arguments对象,它是函数的一个实参对象,是一个类数组,有length属性,而且也能够经过数组表示法获取指定索引值的元素,甚至能够被修改(简言之,arguments对象的值可读、可写),对arguments对象的修改直接同步到存放实参的各个变量。索引


改编题5

foo();
alert(a);
alert(b);
function foo(){
    a = b = 2;
}

question: 说一下脚本运行的结果?
result:
alert(a); //2
alert(b); //2
question:函数未声明,就调用,怎么不会报错?
reason:这是由于声明被提早了(hoisting
),声明被提高到做用域的顶部,此处,即全局做用域的顶部,在foo()以前。代码至关于:

function foo(){
    a = b = 2;
}
foo();
alert(a);
alert(b);

改编题6

var a = 1;
var b = 1;
foo();
alert(a);
alert(b);
var foo = function(){
    var a = b = 2;
}

question: 说一下脚本运行的结果?
result:
TypeError: foo is not a function
reason: 这里使用函数定义表达式,要清楚的是,声明是会提早的,但赋值却不会。换句话说,函数调用的时候,foo已经存在了(不信,你能够试试alert(foo);),可是,它的值是undefined。因此,这里就出现了类型错误。顺便提一下,undefined和null没有任何的属性和方法。

END
这是个人github网址,初学者能够看一下,应该会有所帮助。也欢迎大牛们莅临指导。

相关文章
相关标签/搜索