面试题及日常小结(二)-代码篇

428 阅读6分钟

撸代码之余,偶尔刷刷面试题,回顾下基础的知识点也是极好的。个人通过看大佬文章,也整理了下基础的面试题,同时也夹杂了一些工作中遇到的小问题和方法。打算写成小系列文章做个记录,给自己和有需要的童鞋做个参考。

本篇是系列的第二篇,主要涉及一些面试中常见的给出代码说出答案的问题,大部分只写出问题和答案,个别会写下原因,有问题大家可以一起讨论~。

1、请说出下面代码的结果

var data = [];
for(var i = 0; i < 3; i++){
    data[i] = function(){
        console.log(i)
    }
}
data[0](); 
data[1](); 
data[2](); 
//输出答案均为: 3

2、请说出下面代码的结果

function fun(n, o){
    console.log(o);
    return {
        fun: function(m){
            return fun(m, n)
        }
    }
}
var a = fun(0); 
a.fun(1); 
a.fun(2); 
a.fun(3);   
//===> undefined 0 0 0

var b = fun(0).fun(1).fun(2).fun(3);            
//===> undefined 0 1 2

var c = fun(0).fun(1); c.fun(2); c.fun(3);      
//===> undefined 0 1 1

3、请说出下面代码的结果

var a = 100;
function fun(){
    var b = a * 20;
    var a = 200;
    var c = a / 2;       
    console.log(b);
    console.log(c)
}
fun()  
//===> NaN  100

4、请说出下面代码的结果

let person = {name:"Lydia"};
const members = [person];
person = null;
console.log(members)     //==> {name: “Lydia”} 

let person = {name:"Lydia"};
const members = [person];
person.name = null;
console.log(members)     //==> {name: null}

5、请说出下面代码的结果

parseInt("20*10")         //===> 20             
Number("10*20“)           //===> NaN

parseInt从左到右遍历字符串,遇到非数值字段时则停止,取前边数值

Number判断整体,包含非数字即返回NaN

6、请说出下面代码的结果

function Car(){
    this.color = 'red'         
    return {
        color: 'green'
    }
}
var car = new Car()
console.log(car.color)    //===> green

返回属性时,属性的值等于返回值,而不是构造函数设定的值

7、请说出下面代码的结果

const set = new Set([1,1,2,3,4,4,5]); 
console.log(set)          //===> {1,2,3,4,5}

Set收集独一无二的值,返回一个对象

8、请说出下面代码的结果

const name = “lilei”;  age = 10;              
console.log(delete name)         //false              
console.log(delete age)          //true 

delete操作符会返回一个布尔值,删除成功则为true,否则则为false;

通过var/const/let定义的变量无法通过delete删除;直接设定的age相当于给window添加了age属性,可以通过delete删除。

9、请说出下面代码的结果

let nn = 10;
const add = () => nn++;
const add1 = (nums) => nums++;
const a = add();
const bb = add1(a);
console.log(a,bb)     //==> 10, 10

10、请说出下面代码的结果

const val = {num: 10};
const ff = (v)=>{
    var aaa = v || val
    console.log(aaa.num *= 2)
}
ff()       //===> 20
ff()       //===> 40
ff(val)    //===> 80 

const val2 = {num: 10};
const ff2 = (v = {…val2}) => {
    console.log(v.num *= 2)
}
ff2()     //===> 20
ff2()     //===> 20
ff2(val2) //===> 20
ff2(val2) //===> 40

11、请说出下面代码的结果

async function gets(){
    return await Promise.resolve('aaaaa')
}
var aa = gets()
console.log(aa)    //===> Promise{<pending>}

执行完 gets 之后,返回的是一个挂起状态的promise,如果要执行resolve,需要调用then方法

12、请说出下面代码的结果

const getList = ([x, …y])=>[x, y];              
const getObj = (user)=>{
    name: user.name, 
    age: user.age
};              
const list = [1,2,3,4]              
const obj = {name: ‘lilei’, age: 20}              
console.log(getList(list))   //===> [1, [2,3,4]]              
console.log(getObj(obj))     //===> undefined

getObj函数接受一个对象,对于箭头函数,如果只返回一个值,则可以不写花括号;但是如果想从箭头函数返回一个对象,必须在圆括号之间编写,否则不会返回任何值,修改如下: const getObj = (user)=>({name: user.name, age: user.age})

13、请输出以下表达式结果

let a = {a: 10}       
let b = {b: 10}
let obj = {a: 10}       
obj[b] = 20       
console.log(obj[a])   //===> 20

原因:当一个对象的属性名表达式是一个对象的时候,会把对象转换为字符串[object Object],所以当设置obj[b]的时候其实是把obj变成了obj={a: 10, [object Object]: 20]}。因此对obj[a]的取值实际是取obj[object Object]的值。

14、关于JSON.stringify()

题目一:

const data = {
    a: ‘aaa’,
    b: undefined,
    c: Symbol(‘cc’),
    d: function(){
        return true
    }
}
JSON.stringify(data)     //====> “{“a”: “aaa”}”

原因:undefined、symbol以及任意的函数作为对象属性值时,JSON.stringify方法将忽略对他们的序列化。

题目二:

JSON.stringify([‘aaa’,undefined, Symbol(‘ccc’), function dd(){return true}])                //
//===> “[“aaa”, null, null, null]”

原因:undefined、symbol以及任意的函数作为数组元素时,JSON.stringify方法会将他们序列化为null

题目三:

JSON.stringify(functiona(){console.log(‘a’)})     
//===> undefined              
JSON.stringify(undefined)     
//===> undefined              
JSON.stringify(Symbol(‘dd’))     
//===> undefined

原因:undefined、symbol以及任意函被JSON.stringify方法单独进行序列化时都会返回undefined

题目四:

JSON.stringify({
    say: ‘hello stringify’,
    toJSON: function(){
        return ‘today hello’
    }
})    
//===> ”today hello”

原因:转换值如果有toJSON()函数,该函数返回什么值,序列化结果就是什么值,并且忽略其他属性值。

题目五:

JSON.stringify(NaN)        //===> ”null”       
JSON.stringify(null)       //===> ”null”       
JSON.stringify(Infinity)   //===> ”null”

原因:NaN、Infinity以及null都会序列化为null

15、如何定义变量a,使 a == 1 && a == 2 && a == 3都成立?

var a = {
    num: 1,       
    toString: function(){
        return this.num ++
    }
} 

16、请写出输出结果

function fun(a, b){
    console.log(b)
    return {
        fun: function(c){
            return fun(c, a)
        }
    }
}
var d = fun(0);  
d.fun(1); 
d.fun(2);  
d.fun(3);   
//===> undefined 0  0  0

说明:执行fun(0)之后,b=undefined,此时d={fun: function(c){return fun(c, a)}},后面调用 d. 方法的时候就相当于在此基础上调用。

d.fun(1):此时 c = 1, a = 0 ===> 执行fun(c, a) ===> 参数相当于a=c=1, b=a=0,输出0;同理后面执行 d.fun(2) d.fun(3)都是在最初 a = 0的情况下执行的。

var d1 = fun(0).fun(1).fun(2).fun(3) //undefined 0 1 2

说明:相当于依次执行函数,分别将参数替换成对应的数值。

var d2 = fun(0).fun(1); d2.fun(2); d2.fun(3); //undefined 0 1 1

说明:和第一个相似,只不过此时 d2 执行了两次,初始 a=1.

17、请写出下面输出值

function foo(){
    getName = function(){
        console.log(1)
    }              
    return this
}
Foo.getName = function(){console.log(2)}
Foo.prototype.getName = function(){console.log(3)}
var getName = function(){console.log(4)}
function getName(){
    console.log(5)
} 
Foo.getName();    //==== 2

解:此处直接执行Foo的getName方法,直接执行即可。

getName(); //==== 4

解:此处执行getName方法,注意函数声明会提升,因此相当于

function getName(){console.log(5)}

    var getName = function(){console.log(4)}

Foo().getName(); //==== 1

解:此处相当于先执行了Foo方法,函数内部getName相当于全局变量,也就相当于重写了window.getName方法,并且放回this(即window),同时此处又调用getName(),也就是执行window.getName()

getName(); //==== 1

解:因为上一步执行时已经重写了window.getName()

new Foo.getName(); //==== 2

解:此处会优先执行Foo.getName(),直接输出2。new会生成一个对象,但是对后面没有影响。

new Foo().getName(); //==== 3

解:此处优先执行new Foo(),生成一个Foo的实例,此时this指向实例,再调用getName方法相当于调用实例的方法,实例中不存在此方法,则去原型中查找。

new new Foo().getName(); //==== 3

解:由上一步可知,new Foo()生成一个实例,调用实例的getName方法,相当于执行了上一步,输出3。然后执行new方法生成一个新的对象。

18、请说出下面代码的结果

for(var i = 0, j = 0; i < 10, j < 6; i++, j++){
    value = i + j
}
console.log(value)
//===> 10

以上就是总结的一部分题目,其实大部分这种题目都是涉及到js的基础知识部分,例如:原型、继承、基础类型、引用类型、闭包等,可能题目中坑也稍微多一点,但是只要基础扎实,仔细分析大部分问题还是可以解决的。

此为面试系列第二篇文章,可点击链接查看历史文章:

面试题及日常小结(一)-基础篇