常见笔试基础“快乐”题

144 阅读4分钟

前言

最近开始去做一些笔试题,然后发现自己的基础确实不好,但是在做笔试的过程中确实有所进步,还发现了一些基础快乐题,基于这些基础快乐题我进行了一些整合,希望也能让大家一起来快乐一下!

类型判断

最基础的题型,就是数据类型的判断了,如果是面试,可能会问你有多少中判断类型的方法,一般说一下typeof,instanceof,constructor和Object.prototype.toString.call()就差不多了,但是在笔试题中的类型判断,就会变成'' == false,'' === false之类的题目,那么我们简单的写一下以下的答案

console.log('' == false); // true
console.log([] == false); // true
console.log(0 == false); // true
console.log({} == false); // false
console.log('' === false); // false
console.log([] === false); // false
console.log(0 === false); // false
console.log({} === false); // false

好,相信大家的基础都很好,这对大家来说都是比较简单的题目,==会先进行类型转换,===则需要比较类型,这些都是很熟悉的知识点了,然后以为==比较的都是布尔值,所以需要将两边转换为Number来进行比较,最终得出结果。

但是肯定有好奇的刚开始学还好奇的朋友会疑惑为什么{} == false不是true,我们都知道,将false转换为Number就是0,但是{}转换为Number的时候其实不会转成0,而是转成了NAN

原型与原型链

最常见的面试和笔试题之一,请说一下对于原型和原型链的理解,其实就是两个属性:__proto__和prototype。

函数身上或者说对象上正常来说都会有一个prototype属性,而对应的实例上会有一个__proto__属性,他们指向了同一片空间,用代码来说就是

let obj = {
    name:'text'
}

console.log(obj.__proto__ === Object.prototype); // true

然后原型链就是,一直在原型对象上去寻找需要的属性,直到找到对应的属性或者null,这样就构成了一条原型链(作用域链其实也是一个的意思,往上一级访问)

好,大概理解了原型和原型链是什么,我们就可以来做题了,原型和原型链的题型基本上就是两种,一种就是判断__proto__和prototype相等,另一种就是判断原型链访问到什么时候为null,或者说怎么通过原型链去访问到数据

let obj = {
    name:'text'
}

let fn = function() {
    console.log(1);
}

class A {
    constructor(a,b) {
        this.a = 1
        this.b = 3
    }
}

class B extends A{
    constructor(b) {
        super()
        this.b = b
    }
}

Object.prototype.age = 20

let ca = new B(2)

console.log(obj.prototype === Object.prototype); // false
console.log(fn.prototype === Function.prototype); // false
console.log(obj.__proto__ === Object.prototype); // true
console.log(fn.__proto__ === Function.prototype); // true
console.log(ca.__proto__.__proto__.__proto__ === null); // false
console.log(ca.a); // 1
console.log(ca.b); // 2
console.log(obj.age); // 20

异步编程

JavaScript因为是单线程的原因,在代码运行的过程中就出现了同步和异步两种不同的方式,讲起来有点多,这里就不多说,以后有机会再写。

简单来说,JavaScript的执行顺序同步>异步,然后异步中又分为了宏任务(setTimeout...)和微任务(Promise...),宏任务和微任务的执行顺序可以理解为,先执行完当前的微任务,然后去执行一个宏任务,执行完一个宏任务之后回去检查是否有微任务,如果有则去执行微任务,然后再去执行宏任务。

通俗点比喻就是,一个动物园在排队进去,同步就是VIP用户,会在所有人前面先走,然后VIP进去之后,开启异步,但是在异步中我们遵循尊老爱幼的原则,先看有没有小孩,有小孩先放小孩进去,然后当前队伍没有小孩了,那开始放大人进去,每放一个大人就去就检查一下队伍里有没有新来的小孩,有就先放小孩进去。

好,我相信到这里大家已经简单的理解了,那么就开始做题吧

setTimeout(() => {
    console.log(1);
},0)

new Promise((resolve, reject) => {
    resolve(2)
    reject(3)
}).then(() => {
    console.log(4);
}).catch(() => {
    console.log(5);
}).finally(() => {
    console.log(6);
})

console.log(7);

// 7 4 6 1

为什么没有2345呢?这就涉及到Promise的一些机理了,有兴趣的朋友可以专门去了解一下异步编程,属于常考内容。

结语

那其实这些笔试题如果理解了原理的话都是比较简单的,但是在基础不够扎实的情况下面对这些题目,就是非常的痛苦,只能靠运气乱猜,最近的几次面试,面试官问项目或者说问八股,其实都是想去了解我们的基础到底好不好。本人因为学得不够就开始接触项目写按钮,其实基础这一块比较空中阁楼的感觉,现在才重新去回顾这些基础,挺浪费时间的,所以初学的小伙伴一定要打好基础!!!

番外(看起来很吓人的题目)

let obj = {
    name:'text'
}

let fn = function() {
    console.log(1);
}

class A {
    constructor(a,b) {
        this.a = a
        this.b = b
    }
}

let str = 'abc'

setTimeout(() => {
    console.log('' == false);
    console.log([] == false);
    console.log({} == false);
}, 0)

new Promise((resolve, reject) => {
    resolve(obj.prototype === Object.prototype)
    reject(obj.__proto__ === Object.prototype)
}).then(() => {
    console.log(fn.__proto__ === fn.prototype);
}).catch(() => {
    console.log(fn.prototype === fn.prototype);
}).finally(() => {
    console.log(typeof(Number(str)));
})

console.log(one);

var one = '123'
let ca = new A()

console.log(ca.__proto__.__proto__.__proto__ === null);

console.log(Object.prototype.toString.call());

这里就不备注答案了,有兴趣的话可以自己算一下或者编译运行一下。