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,5D 选中
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); // 10010. 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); //true014. 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();