JavaScript 面试题04
1、14年百度的题
下面这段 js 代码执行完毕后 x, y, z 的值分别是多少?
var x = 1, y = z = 0; function add(n){ return n = n + 1; } y = add(x); function add(n){ return n = n + 3; } z = add(x); console.log(x, y, z); // 1 4 4 // x,y,z初始值 // var x = 1; // var y = 0; // z = 0; // y = add(x); // y = 4 // z = add(x); // z = 4 // 执行结果 // x = 1 // y = 4 // z = 4
考的是预编译,预编译函数要提升,函数提升符合第 4 步规则,
第 4 步先去找函数的名,把函数声明的名变成 AO 的一个属性名,属性名的值是函数体。
有两个函数起了一样的名,后面的函数肯定覆盖第一函数。
别管函数定义的位置在哪,后面的函数会被提升提,提升后位置就无关紧要了,
所以最后无论是 y = add(x) 还是 z = add(x),调用的函数 add() 都是一个,就是下面的那个函数。
2、阿里巴巴的题
下面代码中 console.log 的结果是 [1, 2, 3, 4, 5] 的是:
A(选中)
function foo(x){ console.log(arguments); return x; } foo(1,2,3,4,5); // foo(1,2,3,4,5)函数执行,1,2,3,4,5传到里面arguments是实参,打印实参是1,2,3,4,5的数组 // Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
B
function foo(x){ console.log(arguments); return x; }(1,2,3,4,5); /*** B跟A一样,只不过函数后面直接加了一个小括号(1,2,3,4,5),想执行这个函数声明。能执行吗?执行不了,但不报错。 为什么不报错? 本质上,如果把小括号写到函数声明后面,它是一定会执行这个函数的,但是又执行不了,所以肯定会报错的。 但是把小括号写到后面,括号里面又写了点东西。其实系统最想识别的语法,还是执行这个函数,但执行这个函数又执行不了。 执行不了就会先默认,看看有没有其它的出口,不发生错误呢(发生错误就终止程序)? 能不能不发生错误呢? "(1,2,3,4,5)",括号还可以把这些数圈到一起。 把这些数圈到一起,就相当于给这些数字,加一个数学运算的符号了,就不当做函数执行了,所以这样就不会报错。 function foo(x){ console.log(arguments); return x; } (1,2,3,4) 这个题报不报错都无所谓,因为问是那个结果能输出,但这道题它怎么也输出不了! ***/
C 选中
(function foo(x){ console.log(arguments); return x; })(1,2,3,4,5); // 立即执行函数里面传1,2,3,4,5,立即执行函数放小括号里面能执行。传进去之后,arguments还是1,2,3,4,5
D 选中
function foo(){ bar.apply(null ,arguments); } function bar(){ console.log(arguments); } foo(1,2,3,4,5); /*** call和apply的区别传参列表不一样,作用改变this指向。 function foo(){ // bar.apply(null ,arguments)就是让bar()去执行,apple()是改变this指向,但这里面不涉及this的事,所以第一位传的是null了,不想改变谁的this就是想执行,后面传的是arguments。 // 这块写的bar.apply(null ,arguments)和bar(arguments)没什么两样!只不过秀一下! bar.apply(null ,arguments); } function bar(){ console.log(arguments); } foo(1,2,3,4,5); 看一下最后输出结果,bar里面的arguments输出的是什么?打印Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ] 这个题做了一个参数的传导,怎么参数的传导呢? 首先foo()虽然它没写形参,没写形参不代表参数传不进去,实参列表里传着实参呢,foo里面的"arguments"(bar.apply(null ,arguments))代表实参列表1,2,3,4,5,这是foo自己的arguments。 然后foo()把arguments当做参数,又传到了bar()里面去,所以bar()里面有一个实参,是一个数组。 然后这个数组,又放到了bar()的arguments里面去了。就相当于把1,2,3,4,5打包又传到bar()的arguments里面去了,所以bar()的arguments存的还是1,2,3,4,5 倒了一下参数 ***/
003.
PS:每语句结束基本上都加分号,作为这个语句的结束符号。有些语句是不用加分号的比如if(){}, for(){}, function(){}
我是一行文本需要水平垂直居中。
004. EXAMINATION QUESTIONS
我是一行文本,需要水平和垂直居中
<style> div{ width:400px; height:100px; border:1px solid gray; line-height:100px; text-align:center; position:absolute; top:50%; left:50%; margin-left:-200px; margin-top:-50px; } </style> <div>我是一行文本,需要水平和垂直居中</div>
005. EXAMINATION QUESTIONS
请问以下表达式的结果是什么?
这题考的是parseInt()的应用,parseInt()前边的参数是要转化的数,后面是基底。基底是控制进制的,以后边的目标进制为基底转化为十进制
console.log(parseInt(3 ,8)); // 3当成八进制的3,八进制的3转化为十进制还是3 console.log(parseInt(3 ,2)); // 二进制里没有3,结果返回NaN console.log(parseInt(3 ,0)); // 这个比较特殊,下面详解一下 /*** parseInt(3 ,0) parseInt()后面的"基底"正常区间是2-36,有一个不正常的就是0。 写0,有些浏览器认为它是错的,因为根本不可能有零进制,一进制都不可能有,一进制就全是0了,一进制不能有1,二进制不能有2。一进制不可能有,0进制根本就不可能有。 有些浏览器(比如IE老版本)这么写"parseInt(3 ,0)"会报错,有的也不会报错是NaN。 现在高级谷歌浏览器,写0进制还真能识别,把写0进制写上,它认为没写,把0认为成10了,就跟没写一样,所以写3返回的还是3。 所以这个答案有两个,"other"也行"3、NaN、NaN"也行。 ***/
006. 进制
大家都有一个查数的标准,正常人的查数标准是1,2,3,4,5,6,7,8,9然后是10,1到9以是个位数,在9的基础上再加1就变成10个了。
"10个"和10是一个东西吗?给你10个苹果,再写出一个10,这俩个不是一个东西,十个苹果就是10个苹果,这个10代表的只是十进制里面的计数10。
比如10个苹果想表示它10个的数量,按照十进制的数量表示那就是"一零"(10),因为9 + 1在十进制里面就等于"一零"(10),这是我们正常生活中用的。
但是比如我们的进制是十一进制的,那9 + 1也等于10,但在十一进制里面这个10还算是个位的, 所以为了在个位表示这个10就变成a了(9 + 1 = a),这时候a代表10,a再加1"a + 1 = 10",在十一进制里10代表11
十一进制和十进制的区别,十一进制满11就要向前进一位,所以"a + 1 = 10",在十一进制里的"一零"(10)代表11。
通用的没有那么复杂,一般十进制、十六进制、二十进制
十六进制就9上面在加,十六进制里面的10是a,11是b,然后c、d、e、f,这个f代表15
什么叫进制?满足一个数,它要从个位变成十位,这就叫进制。
十进制,满十就要让个位变成0,让十位变成1。
十六进制,满16让个位变成0,十位变成1,所以f在往上就是一零(10)了。
十六进制的一零(10),这个10可不是10,这叫十六进制的"一零","一零"代表的真实的数是16个。
比如给一个十六进制的数,"一零"(10)个苹果,十六进制的10其实是16个苹果。
再比如给f个苹果,是15个苹果。
"1f"个苹果是31个,怎么算31个的呢?回归十进制,19个苹果就是19个,19个是怎么来的?是10加上9(10 + 9),十位加个位。
十六进制的"1f"个苹果,也是十分位加上个分位的东西,十分位的"1"代表16,个位的"f"代表15,所以就是16 + 15 = 31
经典的是二进制,二进制最加的迷幻,满2就可以往前进位了。
所以二进制的1就是1,二进制里没有2,到2就往前进位了,二进制里的"一零"(10)代表2,二进制的11代表3。
二进制的"100"?4
二进制的"1000"?8
二进制的"10000"?
看一个简单的规律,不管几进制,先看十进制的规律。
十进制的1 1 = 1
十进制的10 10 = 10
十进制的100是10的平方 100 = 10 ^ 2
十进制的1000是10的3次方 1000 = 10 ^ 3
十进制的10000是10的4次方 10000 = 10 ^ 4
所以十进制的几?有几个零就是多少次方。十进制的"100"有两个0就是10的2次方,十进制"1000"有三个0就是10的3次方,就看有几个0。
二进制和十进制的规律类似。
二进制的1 1 = 1
二进制的10 10 = 2
二进制的100 100 = 2 ^ 2
二进制的1000 1000 = 2 ^ 3
二进制的10000 10000 = 2 ^ 4
007. EXAMINATION QUESTIONS
typeof返回的六个结果: String、Boolen、Number、undefined、Object、function
那些是typeof返回的结果,那些值可以转换为false,这些是基础。
008. EXAMINATION QUESTIONS
javasctip的call和apply方法是做什么的,两种有什么区别? 改变this指向,区别传参列表不一样。
009. EXAMINATION QUESTIONS
看看下面console.log(a)的结果是什么?
function b(x ,y ,a){ arguments[2] = 10; console.log(a); } b(1,2,3); // 10 /*** "arguments[2]"代表实参第二位,实参第二位就是形参第三个,也就是"a"。 "arguments[2]"和"a"有关系吗?有关系,它俩是相互映射的关系。 实参列表里面,实参的那个位和行参有值的那个位,是相互映射的。它俩虽然不是一个人,但是它俩保持一个关系,你动我就动,你改完也改。 现在"arguments[2] = 10",a也是变成10了,别看一开始a传的是3,但是会变成10的。 反过来,如果a变成10,打印arguments[2]呢?也是一样的变成10了。 ***/
如果函数体改成下面,结果又会是什么?
function b(x ,y ,a){ // var a; 形参隐式的声明变量a,所以a=10是局部变量 a = 10; console.log(arguments[2]); } b(1,2,3); // 10
010. EXAMINATION QUESTIONS
先铺垫一个基础"逗号操作符",逗号操作符干什么的呢?
比如在控制台1, 2回车,先看一眼前面的,然后在看一眼后面的,最后把第二个返回回来,也就是说1, 2的结果是2。
现在变量num等于1 ,2,num结果应该等于几?结果报错
var num = 1, 2; // Uncaught SyntaxError: Unexpected number
为什么会报错,因为不写括号是不行的。
var num = (1, 2); console.log(num); // 2
要写一个等式就必须把这个东西给括起来,想要逗号操作符必须把这东西括起来。
否则会认为变量声明num等于1、逗号2什么什么东西了,相当于变量声明后一个逗号,相当于那个逗号,会识别混乱。
想要识别语法意义,一定要注意放到一起会不会发生语法混乱。所以想要逗号操作符实现操作加括号。
console.log((1, 2)); // 2
写出下面程序的执行结果(typeof的类型是什么):
var f = ( function f(){ return "1"; }, function g(){ return 2; } )(); typeof(f); // Number /*** 逗号操作符和这个题是一样的,变量f等于一个括号,括号里面一个逗号隔开两个函数,最后会把第二个函数function g(){}返回 返回后会变成这样,是一个立即执行函数,立即执行函数执行完要返回的是2,变量f变成数字2,"typeof f"返回Number var f = ( function g(){ return 2; } )(); typeof(f); //Number ***/
011. EXAMINATION QUESTIONS
写出下面程序的执行结果(这是一个很经典的题)
var x = 1; if(function f(){}){ x+=typeof f; } console.log(x); // "1undfined" /*** 这个题首先它很不符合语法规定,但是它就这么出了。 1. if括号里写了一个"function f(){}",括号还有什么什么东西,但凡把function变成了表达式的,function都会自动忽略它的引用"f"。 就是说一旦function变成了表达式,它就可以立即被执行了,但是相应的代价是它在也不可能被人找到了,这个名字"f"没有任何用了。 2. 虽然if括号里面写"function f(){}"挺匪夷所思的,但是确能写到里面去。能写到里面去,if这个括号表面上是作为条件判断的括号把"function f(){}"给括起来,实际上括号还有自己的用途,就是能把里面的东西转换成表达式。 3. 能转换成表达式,不论怎么转这个"function f(){}"肯定不是那六个能转化成false的值,所以结果一定是true,可用走到判断里面去。可以通过if判断,执行里面的"x+=typeof f"语句。 4. "x+=typeof f"这时候函数名"f"找不到了,因为函数放在括号里面,函数名f找不到了,找不到就是undefined,undefined正常情况下就报错了,但是唯独放到typeof里面没事,它能返回字符串格式的"undefined" 5. 所以数字1,数字1加上字符串"undefined",等于字符串"1undefined" ***/
012. EXAMINATION QUESTIONS
以下哪些表达式的结果为true
A.
undefined == null /*** undefined和null这俩非常有意思: undefined > 0 false undefined不大于0 undefined < 0 false 不小0 undefined == 0 false 不等于0 全是false 无论大、小、等于全是false和它类似的值还有null,null也不大0、null不小于0、null不等于0 null > 0 false null不大于0 null < 0 false 不小0 null == 0 false 不等于0 undefined和null挺像所以它俩相等吧! undefined == null 返回true它俩是相等的。 但它俩绝对等于吗,不绝对等于。 undefined === null false ***/
B.
undefined === null /*** 但它俩绝对等于吗,不绝对等于。 console.log(undefined === null); // false ***/
C.
isNaN("100"); /*** isNaN("100")结果不是NaN,所以返回true isNaN()意思是否是NaN,标准的意思是,这个数经过Number()转化之后是不是NaN isNaN("abc")这次返回true,它会先把"abc"放到Number里面经历隐式类型转换,然后再和NaN进行比对。 ***/
D.
parseInt("1a") == 1; // parseInt("1a")得出数字类型1,数字类型1肯定等于1返回true
按照C. 有一个探索能力,自己写一个isNaN()方法
function myIsNaN(num){ var ret = Number(num); // 1. 调用Number(num)结果赋给ret,NaN自己都不等于自己,ret怎么比对呢? ret += ""; // 3. 把NaN转化成字符串的"NaN",然后在比对,是不是就等于"NaN"字符串了 if(ret == "NaN"){ // 2. 一旦ret等于"NaN"就返回true,逻辑是这逻辑。NaN怎么和NaN比对? return true; }else{ return false; } } console.log(isNaN('123')); // false console.log(isNaN('abc')); // true console.log(isNaN('NaN')); // true console.log(isNaN(NaN)); // 放什么形式的NaN都返回true,这就和系统的一样了。
013. EXAMINATION QUESTIONS
问一个问题,空对象等于空对象吗?
123 == 123 //true {} == {}; // false /*** "{} == {}"不相等返回false,对象和对象比对的是什么呢? 原始值和原始值比对,只能是比对值了。一个对象代表一个房间,这是两房间,虽然外表长的一样但没有用,因为是引用值。这个房间和那个房间看起来格局一样,但毕竟是两个房间,所以肯定不等。 记住,引用值它比的是地址,地址一样才相等。 ***/
这样写,两个对象指向一个房间,它俩必须相等,它俩也绝对相等,都是一个房间,干嘛不绝对相等!引用值比的是地址。
var obj = {}; var obj1 = obj; console.log(obj1 == obj); //true console.log(obj1 === obj); //true
014. EXAMINATION QUESTIONS
请阅读以下代码,写出以下程序的执行结果:
var foo = '123'; function print(){ var foo = '456'; this.foo = '789'; console.log(foo); } print(); // 456
请阅读以下代码,写出以下程序的执行结果:
function print () { console.log(foo); var foo = 2; console.log(foo); console.log(hello); } print();