常见的前端笔试题(后续不断补充)

第一题:

(function(){
	var a = b = 100;
})();
console.log(typeof a);
console.log(typeof b);

函数整体结构是一个匿名函数,声明完后立即执行。
输出:

undefined
number

注意:var a=b=100;
实际上是:

(function(){
	var a;	//变量提升
	b = 100;  //定义不加var,全局变量
	a = b;
})();

这里的b就成了全局变量,所以下面的输出就可以访问b。

下一题:

var res=null instanceof Object;
console.log(res);

输出:

false

这里说一下:

typeof null === 'object';

这二者是全等的,从一开始出现JS就是这样。
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。
由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null的类型标签也成为了 0,typeof null就错误的返回了"object"。(reference)
ECMAScript提出了一个修复(通过opt-in),但被拒绝。这将导致typeof null === ‘object’。

不知道instanceof、in 点击这里

下一题:

var val = 'a';
function f1(){
console.log(val);
var val = 'b';
console.log(val);
}
f1();

输出:

undefined
b

这题考的就是var声明的变量会变量提升,所以这题函数的结构实际上是这样的:

var val = 'a';
function f1(){
var val;	//变量提升
console.log(val);	//这里的val还没赋值,所以未定义
val = 'b';
console.log(val);	//b
}
f1();

下一题:

var array = [0, 1, 2, 3];
var spliceArray = array.splice(3, 1);
var sliceArray = array.slice(0, 1);
console.log(array);

输出:

[0,1,2]

这里只要明白 slice() 不会修改原数组,splice() 会影响原数组就OK了。

如果不知道这二者的区别,请阅读我的另外一篇博客。点击这里访问

下一题:

var i=5;
for(i=0;i<10;i++){}
console.log(i);
//-----------------
let j=5;
for(j=0;j<10;j++){}
console.log(j);
//-----------------
var k=5;
for(var k=0;k<10;k++){}	    //for循环中 var 定义的变量也是全局变量
console.log(k);
//-----------------
let n=5;
for(let n=0;n<10;n++){}    //let块级作用域
console.log(n);

输出:

10
10
10
5

下一题:

console.log(typeof undefined == typeof NULL);
console.log(typeof function(){} == typeof class{});

输出:

true
true

注意,这里是NULL不是null要区分大小写,如果是null的话,typeof null为object输出为false,但这里是NULL所以为undefined。
class类(ES6)的数据类型就是函数,类本身就指向构造函数。所以typeof class{}为function。
[注意]:使用class类的时候,直接对类使用new命令,和构造函数的用法完全一致。

下一题:

var tmp = {};
var A = function() {};
A.prototype = tmp;

var a = new A();
A.prototype = {};

var b = Object.create(tmp);	
b.constructor = A.constructor;

console.log(a instanceof A);
console.log(b instanceof A);

输出:

false
false
解析:
 instanceof 运算符是判断左侧的对象是否为右侧类的实例。
判断依据是对象的__proto__是否等于方法/类的prototype。

其次,这里Object.create();是什么作用?

Object.create()方法创建一个新对象,
使用现有的对象来提供新创建对象的对象的__proto__。

下面是直接通过输出__proto__和prototype验证结果:
请静下心,看完下面代码,一定要耐心看,细细体会,记住上面的知识点

var tmp = {};
var A = function() {};
//测试 
console.log(A.prototype);	//A {}
console.log(A.__proto__);	//[Function],继承Function对象/类的所有属性/方法

A.prototype = tmp;
//测试
console.log(A.prototype);	//{}

var a = new A();
//测试
console.log(a.__proto__);	//{}
console.log(a.__proto__ === tmp);	//true,这里的{}等于tmp
console.log(a.__proto__ === A.prototype);	//true,这里A.prototype也等于tmp

A.prototype = {};	//A.prototype等于{}了,不是tmp了,只要把这句去掉,最后两句都是true了
//测试
console.log(A.prototype);	//{}
console.log(a.__proto__ === A.prototype);	//false
//复杂的数据类型,{}=={},{}==={} 均返回false
console.log(A.constructor);		//[Function: Function]
//constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function。

var b = Object.create(tmp);	//这时,b实例的原型就是tmp了
//测试
console.log(b.constructor);		//[Function: Object]

b.constructor = A.constructor;
//测试
console.log(b.constructor);		//[Function: Function]
console.log(b.__proto__);		//{}
console.log(b.__proto__===tmp);	//true
console.log(b.__proto__===A.prototype);	//false

//结果
console.log(a instanceof A);	//false
console.log(b instanceof A);	//false

下一题:

var arr=['a',,'b',,];
console.log(arr);
console.log(arr.length);
arr.push(1);
console.log(arr);
console.log(arr.length);

输出:

[ 'a', <1 empty item>, 'b', <1 empty item> ]
4
[ 'a', <1 empty item>, 'b', <1 empty item>, 1 ]
5

下一题:

var array = [0,1,2];
var spliceArray = array.splice(0,1);
var sliceArray = array.slice(0,1);
var concatArray = array.concat("a");
console.log(array); //[ 1, 2 ]
console.log(spliceArray);  //[ 0 ]
console.log(sliceArray);  //[ 1 ]
console.log(concatArray);  //[ 1, 2, 'a' ]

解析:这里只有splice会修改原数组。
忘记数组方法,点击这里

下一题:

var name = 'World';
(function(){
 if(typeof name === 'undefined'){
  var name = 'JSON';
  console.log("Goodbye " + name);
 }else{
  console.log("Hello " + name);
 }
})();

输出:

Goodbye JSON

解析: 函数预编译不会看你if语句条件是否成立,会直接读变量声明语句,然后此时name发生变量提升,就是undefined。相当于以下代码:

var name = 'World';
(function(){
 var name;   //变量提升
 if(typeof name === 'undefined'){
  name = 'JSON';
  console.log("Goodbye " + name);   //Goodbye JSON
 }else{
  console.log("Hello " + name);
 }
})();

下一题:

function funcA(data) {
 data.key = 'data';
}
function funcB(data) {
 data = {};
 data.value = 'data';
}
var data = {
 key:'key',
 value:'value'
}
funcA(data);
funcB(data);
console.log(data.key);
console.log(data.value);

输出:

data
value

解析: 注意这里的funcB(data)中的data是局部变量,相当于下列代码:

function funcA(data) {
 data.key = 'data';
}
function funcB(data) {
 var data; 
 /*
 相当于在函数内部创建了一个新data对象,
 所以data = {}修改的只是此时函数funcB内部的data,
 如果在funcB内输出data.value,那么将会输出data,
 但是在函数外部,data.value依然是value。
 */
 data = {};
 data.value = 'data';
}
var data = {
 key:'key',
 value:'value'
}
funcA(data);
funcB(data);
console.log(data.key);
console.log(data.value);

下一题:

var y=0;
var x=1;
function f1(n){
     n+=1;
     return n;
}
function f1(n){
     n+=3;   //这里n为局部变量
     return n;
}
y=f1(x);
console.log(y);  

输出:

4

解析:假如有多个同名函数,则以最后一个函数为调用基准

下一题:

var a=1;
setTimeout(function(){
       console.log(a);
       a=10;
       console.log(a);
},0);
a=100;
console.log(a);

输出:

100
100
10

解析:需要知道事件循环机制才可以理解这道题,这里的setTimeout定时器异步任务挂起,最后才执行里面的代码。

下一题:

for(var i=0;i<5;i++){
   setTimeout(()=>{
      console.log(i);
   },200);
}

输出:

5
5
5
5
5

解析:这题也是事件循环机制。

下一题:

for(var i=0;i<5;i++){
   (function(num){
      setTimeout(()=>{
      console.log(num);
      },200);
   })(i);
}

输出:

0
1
2
3
4

解析:这里在for循环内部使用了一个闭包,使用num存储每次循环的i值,这样定时器最终执行时,输出的是每次闭包存储的i值,而不是最终的i值。

下一题:

function numAdd(num){
     num++;
     console.log(num);
}
setTimeout(numAdd,1000);

输出:

NaN

解析:因为num为undefined,经过num++所以成了NaN。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值