15.测试题集JS
# 1.关于this的工作原理,下面四种情况的描述哪一个是错误的
A、在全局范围内,this指向全局对象
B、对象函数调用时,this指向当前对象
C、全局函数调用时,this指向全局函数
D、使用new实例化对象时,this指向新创建的对象
# 2.以下代码执行后,console输出的是?
var val = 'smtg'
console.log('Value is' + (val === 'smtg')? 'something' : 'nothing')
2
A、Value is something
B、Value is nothing
C、something
D、nothing
# 3.给出以下代码的执行结果
let arr= {a:1, b: 123}; a= 'a'; b='c'
arr.a = 321
arr[a] = 123
arr[b] = 456
console.log(arr)
2
3
4
5
# 4.下边这代码的输出结果是?
function showCase(value) {
switch (value) {
case 'A' :
console.log('Case A');
break;
case 'B' :
console.log('Case B');
break;
case undefined :
console.log(undefined);
break;
default:
console.log('Do not know');
}
}
showCase(new String('A'))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
A、Case A
B、Case B
C、undefined
D、Do not know
# 5.下边这代码的输出结果是
var string = 'string'
var number = 0
var bool = true
console.log(number || string)
console.log(number && string)
console.log(bool || number)
console.log(bool && number)
2
3
4
5
6
7
A、'string',0 ,true,0
B、'string',true,0,0
C、'string','string',true,0
D、'string',0 ,true,true
# 6.以下代码执行后,console输出的是?
var msg = 'hello'
for(var i=0 ; i< 0; i++) {
var msg = 'hello' + i*2 + i
}
console.log(msg)
2
3
4
5
6
7
# 7.以下代码执行后,console输出的是?
let x = 10
let foo = () => {
console.log(x)
let x = 20
x ++
}
foo()
2
3
4
5
6
7
A、输出ReferenceError
B、10
C、20
D、21
# 8.给出以下代码的执行结果
var foo = 1
function demo() {
console.log(foo)
var foo = 2
console.log(foo)
}
demo()
2
3
4
5
6
7
# 9.给出以下代码的执行结果
var a = new Object()
a.value = 1
b = a
b.value = 2
console.log(a.value)
2
3
4
5
# 10.以下那个选项可以将集合A转为数组
A、Array.from(A)
B、[].slice.apply(A)
C、[...A]
D、[].map.call(A, o => 0)
# 答案(解析):
1.C
2.C。与三元运算符有关,?前面就是条件,所以条件是Value is + true 为真,所以返回something
3.
// [a]里的a是一个变量, 而obj.a是直接就是取key为a的值
arr {
a: 123,
b: 123,
c: 456
}
2
3
4
5
6
4.D。new String('A') ---> String {'A'}。new String('A'), 是创建了key为0,值为'A'的一个对象,case 一个对象结果自然是Do not know
5.A。
- A || B, 若A为真,则返回A,若A为假,则返回B
- A && B, 若A为真,则返回B,若A为假,则返回A
6.A。这涉及到作用域的知识,console.log(msg)是在全局作用域,它会在全局作用域里寻找msg这个变量,全局作用域是拿不到for循环里的作用域的值的,所以答案为'hello'
7.A。在块级作用域里,let声明之前的执行瞬间会有一个暂时性死区,所以会报错
8.undefined和2。因为var声明的变量会提升,所以实际执行顺序是
var foo = 1
function demo() {
var foo
console.log(foo) // undefined
foo = 2
console.log(foo) // 2
}
demo()
2
3
4
5
6
7
8
9.2。 因为对象在内存中存放的是地址
var a = new Object()
a.value = 1
b = a // b=a 时 赋值赋是地址
b.value = 2 // b.value也是a.value 所以b.value改变实际上也改变了a.value
console.log(a.value)
2
3
4
5
10.选A、C, BD得到的会是一个空数组
const A = new Set(['a', 'n'])
console.log(Array.from(A)); // [ 'a', 'n' ]
console.log([].slice.apply(A));// []
console.log([...A]); // [ 'a', 'n' ]
console.log([].map.call(A, o => 0));// []
2
3
4
5
# 11.es6的新特性
- 块级作用域声明:使用 let 和 const 关键字可以在代码块中定义局部变量。
- const:const声明指的是常量,在声明时要初始化;声明的值不能修改;禁止重复声明。不存在变量提升
// 虽然const变量不能修改指针,但是可以修改值,比如我们定义一个对象,我们就可以修改对象里的属性值,但是不可以重写整个对象
const person = {
name: "蛙人",
age: 23
}
person.age = 18 // 没问题
person = {} // 报错 不能修改对象指针
// const只要不修改存储于栈内存的指针就没问题,可以任意修改堆内存的数据。
2
3
4
5
6
7
8
- let:声明的值后期可以修改;禁止重复声明。不存在变量提升
- 我们在全局作用域中或还是在局部作用域中,使用var关键字声明的变量,都会被提升到该作用域的最顶部,这就是我们常说的变量提升
function person(status) {
if (status) {
var value = "蛙人"
} else {
console.log(value) // undefined
}
console.log(value) // undefined
}
person(false)
// if代码块中的var声明的变量就被提升到了函数的顶端,这是因为javaScript引擎,在代码预编译时,javaScript引擎会自动将所有代码里面的var关键字声明的语句都会提升到当前作用域的顶端, 因此上面的代码就会被解析为下面。
function person(status) {
var value;
if (status) {
value = "蛙人"
} else {
console.log(value) // undefined
}
console.log(value) // undefined
}
person(false)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 暂时死区:
跟var相比,let和const定义变量不会被提升到作用域顶端,即便是用相对安全的typeof也会出现错误
console.log(typeof value)
let value = "蛙人"
2
上面example中,console.log(typeof value)会抛出错误是因为用let定义并初始化变量语句是不会执行的。此时的value还是处于在JavaScript所谓的暂时死区(temporal dead zone)简称为TDZ 中,虽然JavaScript没有明确标准TDZ,但是人们常用它描述let和const定义的变量不会提升 TDZ工作原理,JavaScript引擎在扫描代码时发现变量声明时,如果遇到var就会将它们提升到当前作用域的顶端,如果遇到let或const就会将声明放到TDZ中,如果访问TDZ中的变量就会抛出错误,只有执行完TDZ中的变量才会将它移出,然后就可以正常方法。这机制只会在当前作用域生效。 2. 箭头函数:使用箭头函数语法() => {} 可以定义函数,并且可以使用诸如this、arguments等
- 箭头函数没有自己的 this,它会捕获定义时所处的上下文的 this 值
- 箭头函数没有自己的 arguments 对象
- 模板字面量:使用反引号 ```` 可以定义字符串,并且可以嵌入表达式
const name = 'Tom';
console.log(`Hello, ${name}!`); // 输出 Hello, Tom!
2
- 解构赋值:可以通过解构赋值的方式将对象或数组的值赋给变量
// 解构数组
const [a, b, c] = [1, 2, 3];
console.log(a); // 输出 1
// 解构对象
const person = {name: 'Tom', age: 20};
const {name, age} = person;
console.log(name); // 输出 Tom
2
3
4
5
6
7
8
- 类和继承:ES6 提供了更好的类和继承机制
// 定义类
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(`My name is ${this.name}.`);
}
}
// 继承类
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
sayBreed() {
console.log(`My breed is ${this.breed}.`);
}
}
const dog = new Dog('Buddy', 'Labrador');
dog.sayName(); // 输出 My name is Buddy.
dog.sayBreed(); // 输出 My breed is Labrador.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- Promise 和异步/await:ES6 引入了 Promise 对象和异步/await 语法,以更好地处理异步操作
// 使用 Promise 处理异步操作
// fetchData 函数返回一个 Promise 对象,异步获取数据后,调用 resolve 或 reject 函数返回 Promise 的结果。通过 .then 方法可以处理 Promise 成功的结果,通过 .catch 方法可以处理 Promise 失败的结果
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = 'Hello, world!';
if (data) {
resolve(data);
} else {
reject('Failed to fetch data');
}
}, 1000);
});
}
fetchData()
.then(data => console.log(data))
.catch(error => console.log(error));
// 使用 async/await 处理异步操作
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = 'Hello, world!';
if (data) {
resolve(data);
} else {
reject('Failed to fetch data');
}
}, 1000);
});
}
async function main() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.log(error);
}
}
main();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44