JavaScript基础问答题
# 1. 输出是什么(循环)
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1)
}
2
3
4
5
6
7
答案是:333 和 012,因为 JS 的事件循环机制,setTimeout 属于宏任务,要等到同步代码执行完之后才能执行, var 在此处定义的是全局变量,因此同步代码执行完之后i已经变成了3,所以打印3个3,但是 let 定义的变量会形成一个块级作用域,因此是012。
# 2. 输出是什么(隐式类型转换)
+true;
!"Lydia";
2
答案是:+号会将 true 变为1,+号倾向于返回一个值,但是!倾向于返回一个布尔值,因为"Lydia"是真实存在的,所以取反之后是 false。
# 3. 输出是什么(new对象)
let a = 3
let b = new Number(3)
let c = 3
console.log(a == b)
console.log(a === b)
console.log(b === c)
2
3
4
5
6
7
答:输出是 true、false、false。之所以是这样,当我们是用==符号时,系统会检测两边是否有相同的值,有时候还会对值进行转换的比较,但是如果我们使用===符号时,不仅要求两边要有相同的值,还要求有相同的类型,new Number 出来的是一种对象,其身上不仅仅有值,还有一堆额外的功能。
# 4. 输出是什么(类的静态方法)
class Chameleon {
static colorChange(newColor) {
this.newColor = newColor
return this.newColor
}
constructor({ newColor = 'green' } = {}) {
this.newColor = newColor
}
}
const freddie = new Chameleon({ newColor: 'purple' })
freddie.colorChange('orange')
2
3
4
5
6
7
8
9
10
11
12
13
答:输出是 TypeError,之所以是错误,原因在于 Chameleon 是一个类,colorChange 是类中的静态方法,类中的静态方法只能被构造器使用,不能被实例进行调用。
# 5. 当我们这么做会发生什么(函数对象)
function bark() {
console.log('Woof!')
}
bark.animal = 'dog'
2
3
4
5
答:正常运行!之所以会这样,是因为 JS 中的函数也是一类特殊的对象,所以也可以通过点的形式添加属性。
# 6. 输出是什么(构造函数)
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
const member = new Person("Lydia", "Hallie");
Person.getFullName = function () {
return `${this.firstName} ${this.lastName}`;
}
console.log(member.getFullName());
2
3
4
5
6
7
8
9
10
11
答:TypeError,本题中 Person 是一个构造函数,不能像普通的对象给构造函数添加属性,要想给构造函数的实例添加属性,可以通过原型的方式来实现。
# 7. 输出是什么(隐式类型转换)
function sum(a, b) {
return a + b
}
sum(1, '2')
2
3
4
5
答:'12'
# 8. 输出是什么(标签函数)
function getPersonInfo(one, two, three) {
console.log(one);
console.log(two);
console.log(three);
}
const person = 'Lydia';
const age = 21;
getPersonInfo`${person} is ${age} years old`;
2
3
4
5
6
7
8
9
10
答:["", " is ", " years old "] "Lydia" 21
我刚开始看到这道题的时候,我在想 getPersonInfo 是不是少加一个括号,后来我发现并不是这样,本题意在考查标签函数。所谓的标签函数就是函数名后面直接带一个模板字符串,并从模板字符串中的插值表达式中获取参数。标签表达式的第一个参数是模板字符串中的普通文本,大括号标记的地方视为空字符串,第二个参数则是模板字符第一个大括号中的,以此类推。
# 9. 输出是什么(对象的比较)
function checkAge(data) {
if (data === { age: 18 }) {
console.log('You are an adult!')
} else if (data == { age: 18 }) {
console.log('You are still an adult.')
} else {
console.log(`Hmm.. You don't have an age I guess`)
}
}
checkAge({ age: 18 })
2
3
4
5
6
7
8
9
10
11
答:"Hmm.. You don't have an age I guess",对象在进行比较时,比较的是引用的内存地址,此处参数形式的对象的地址和用于比较的对象的地址是不同的,所以 === 和 == 返回的都是 false。
# 10. 输出是什么(拓展运算符)
function getAge(...args) {
console.log(typeof args)
}
getAge(21)
2
3
4
5
答:"object"、拓展运算符返回的是实参数组,数组属于 object 类型。
# 11. 输出是什么(严格模式)
function getAge() {
'use strict'
age = 21
console.log(age)
}
getAge()
2
3
4
5
6
7
答:ReferenceError、因为这是严格模式,所以会出现引用错误,如果不是严格模式的话,age 属性会被添加到全局对象中去。