据说只有10%的人能全部答对这5道JavaScript题目 ✨
“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第4篇文章,点击查看活动详情”
intspirit 创建了一个JS测验,里面包含了很多js基础的题目,今天和大家分享下
TOP-5 JS
错误问题(数据基于数百位前端开发测试的结果)。
让我们一起来看看这五道题目,解析结果放在下面。大家可以花个5-10分钟时间及看下这几道题目的输出,看下自己对了几道😉😉
Top5. 默认函数参数和函数长度属性(18%的人答对)
function foo(a, b, c = 10, d) {
console.log(foo.length)
}
foo(1, 2, 3, 4)
Top4. Object.defineProperty(14%的人答对)
const obj = {}
Object.defineProperty(obj, 'myCompany', {
value: 'intspirit'
})
console.log(obj.myCompany)
delete obj.myCompany
console.log(obj.myCompany)
Top3. Array.map 和 parseInt(14%的人答对)
const numbers = ['9', '10', '11'].map(parseInt)
console.log(numbers)
Top2. 使用Object.create 和 Object.assign克隆对象(11%的人答对)
function User() {
this.verified = true
}
const user = new User()
const admin = Object.create(user)
const clone1 = { ...admin }
const clone2 = Object.assign({}, admin)
console.log(admin.verified, clone1.verified, clone2.verified)
Top1. 字符串函数和 instanceof 运算符(8%的人答对)
var str = 'Hello'
var str2 = String('Hello')
console.log(str instanceof String)
console.log(str2 instanceof String)
答案解析
Top5代码解析
首先我们需要知道在ES6引入默认参数之前,函数长度属性用于返回所有函数参数长度,如下:
function foo(a, b, c, d) {
console.log(foo.length) // 输出4
}
foo(1, 2, 3, 4)
在ES6引入默认参数之后,长度属性发生了变化,由于具有默认值的形参是可选的,因为这样的参数不包含在函数的长度中。按照常识,默认值参数后面的所有参数也是可选的。因此,它们也不包含在函数的长度属性中。所以Top5代码的结果应该是2
Top4代码解析
这一题,有些小伙伴第一反应的输出结果是 intspirit undefined
,可是结果并不是这样的,这是为啥呢?
其实这题考察的是对Object.defineProperty(obj, prop, desc)
参数的了解
- obj 需要定义属性的当前对象
- prop 当前需要定义的属性名
- desc 描述符 一般是一个对象
Object.defineProperty(person, 'name', {
value: '张三', // 属性值
enumerable: false, // 控制属性是否可以枚举,默认值是false
writable: false, // 控制属性是否可以被修改,默认值是false
configurable: false // 控制属性是否可以被删除,默认值是false
})
可以看出 Object.defineProperty定义的属性,configurable值默认是false,意味着不可以删除,那么这一题的答案很明显了,输出intspirit intspirit
注意 :当使用了getter或setter方法,不允许使用writable和value这两个属性
Top3代码解析
首先我们要明白 Array.map 回调函数接受三个参数 currentValue, index, arrary, parseInt 只接受两个两个参数, 所以map实际上执行的代码如下:
parseInt('9', 0)
parseInt('10', 1)
parseInt('11', 2)
这里就涉及到了parseInt的第二个参数,对于第二个参数有以下几点需要注意:
- 参数是2~36之间的整数值,这个值其实就是我们说的进制
- 如果超出该范围,返回NaN
- 如果是0或未提供,在判定规则如下
- 如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制)。
- 如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决- 定。ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,最好明确给出第二个参数的值。
- 如果字符串 string 以其它任何值开头,则基数是10 (十进制)。
看了上面对于parseInt第二个参数的解析,那么答案就很明显了
答案:[9, NaN, 3]
Top2代码解析
看看这题的代码执行过程是怎样的
- 通过new实例化User, 包含属性verified为true
function User() {
this.verified = true
}
const user = new User()
- 使用 Object.create() 方法创建一个新对象 admin,使用现有对象作为新创建对象的原型
const admin = Object.create(user)
- 执行了两个浅拷贝:一个使用
...
扩展运算符,另一个使用Object.assign
const clone1 = { ...admin }
const clone2 = Object.assign({}, admin)
- 查看
verified
属性是否被拷贝:
console.log(admin.verified, clone1.verified, clone2.verified)
输出结果是:true, undefined, undefined
很明显,扩展运算符和Object.assign都没有克隆verified属性,这是因为 扩展运算符和Object.assign在克隆时都忽略了原型,这些对象的原型
admin.__proto__ User { verified: true }
clone1.__proto__ [Object: null prototype] {}
clone2.__proto__ [Object: null prototype] {}
那么,如何浅拷贝一个对象,并包括他的原型呢,如下:
const clone1 = { __proto__: Object.getPrototypeOf(admin), ...admin }
const clone2 = Object.assign(Object.create(Object.getPrototypeOf(admin)), admin)
测试结果:
Top1代码解析
有一部分人的答案是:true true
还有一部分人答案是: false true
正确的结果是false false
。因为
- instanceof 运算符仅适用于对象。
- 字符 Hello 是基本数据类型,所以返回false
- 非构造函数上下文中的字符串调用(不使用new关键字调用)返回一个原始字符串
上面的5个问题,你答对几道了呢,欢迎大家在评论区讨论 😎😎😎
题目来源:t.me/s/intspirit
转载自:https://juejin.cn/post/7145017279833440264