前端面试中有趣的题目(一)

543 阅读4分钟

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

虽然工作能力是很重要的一点,但是面试也是非常重要的一环

题目一: a == 1 && a == 2 && a == 3 是否能够返回true

a == 1 && a == 2 && a == 3 是否能够返回true

解析: 这是可以实现的

① 在JavaScript当中,有一个隐式转换的概念 特别是本题中使用的是 == ,而不是 === 全等

当进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较, 而===比较时, 如果类型不同,直接就是false

==的类型转换操作空间很大,在这里曾经出现过很多的经典前端面试题哦

比如:

[1,2,3] == '1,2,3'    结果为true     过程: [1,2,3] --> '1,2,3'

[1] == 1    结果为true     过程: [1] --> '1' --> 1

[] == false    结果为true     过程: [0] --> '0' --> 0 --> false

在这里插入图片描述




② JavaScript的原型中提供一种方法valueOf,此方法一般用于返回指定对象的原始值

MDN说明:developer.mozilla.org/zh-CN/docs/…

valueOf可以进行简单改写,通过对value的改写,可以实现 a == 1 && a == 2 && a == 3 返回true

在每次调用a变量进行 == 判断时时,就相当于调用一次valueOf,在valueOf中将数值+1

如下:

function defineNum(i) {
    this.i = i;
}
defineNum.prototype.valueOf = function(){
    return this.i ++;
}
var a = new defineNum(1);

if (a == 1 && a == 2 && a == 3) {
    console.log('成功')
}

输出结果: 在这里插入图片描述

当然了,也还有另外一种改写方式,下面的a定义也是可以成功

var a = {
    i: 1,
    valueOf: function() {
        return this.i++
    }
}
if (a == 1 && a == 2 && a == 3) {
    console.log('成功')
}

注意:这上面两种解答方式都是针对于题目而进行的,如果将判断顺序打乱,比如 a == 2 && a == 1 && a == 3 就会出错





题目二: ES5实现const

使用es5来实现一个类似es6中的const的定义方法

const介绍:

常量是块级范围的,非常类似用 let 语句定义的变量。但常量的值是无法(通过重新赋值)改变的,也不能被重新声明。 MDN地址

const num = 5;
num = 10;
console.log(num)

将会报错,num = 10的修改是无效的

解法一

如果要求不严格,可以使用Object.freeze 冻结来制造一个对象,在对象中有一个a属性,给a赋值之后,冻结该对象 最好是将a挂载到window对象上,不过使用freeze冻结window对象非常繁琐,要写一个可以冻结window的深冻结函数

freeze的效果: 可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改> 该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改

var k = {}
var Const = function(data, value) {
    k[data] = value;
    Object.freeze(k)
}
Const('a', 5);
k.a = 10;
console.log(k.a)

输出: 在这里插入图片描述

注意: 此种方式制造出来的Const有很大缺陷,因为一旦冻结之后,就不能再使用Const去定义其他值了



解法二

使用Object.defineProperty

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

MDN地址

在defineProperty使用时,可以挂载到window对象上,设置writable值为false,挂载上的属性就可以保持不变了

  • enumerable: 对象是否可以枚举
  • configurable: 对象元素的属性描述符是否可改,是否可删除
  • writable: 当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。

方法:

var Const = function(data, value) {
    // 挂载到全局window下,这也就可以直接使用a
    Object.defineProperty(window, data, {
        // enumerable: false,   
        // configurable: false,   
        writable: false,
        value: value
    })

}

Const('a', 5);
a = 10;
console.log(a)

Const('b', 7);
b = 0;
console.log(b)

输出:

在这里插入图片描述

当然了,即使是使用defineProperty制造出来的Const,也依旧只是很类似const,而不是一样的