10道JavaScript基础题,看看你能对几道(一)

139 阅读3分钟

JavaScript中重要的特性和概念有很多,比如原型,原型链,this,闭包,作用域,隐式转换等等。如果不能熟练掌握,开发路上肯定会有很多坑在等着你,今天我们就来测测你的基础掌握程度, 看看你能作对几道。

下面进入正式开始:

第 1 题
if(false){
    var a = 1;
    let b = 2;
}
​
console.log(a);
console.log(b);
​
//输出
undefined
Uncaught ReferenceError: b is not defined

var不会产生块级作用域,let会产生块级作用域,其伪代码相当于

var a;
if(false){
    a = 1;
    let b = 2;
}
​
console.log(a);
console.log(b);
第 2 题
var a = 1;
if(true){
    console.log(a);
    let a = 2;
 }
 
// Uncaught ReferenceError: Cannot access 'a' before initialization 

let声明的变量不会提升,并且会产生暂存死区。在let声明变量之前访问变量会抛出错误。

第 3 题
var a = {n: 1}    
var b = a    //ba指向同一个对象 b = {n: 1}
a.x = a = {n: 2}  
// 先计算”.“运算符: 此时b = {n: 1, x: undefined};
//再计算”=“运算符,”=“运算符是从右向左开始运算
//先运算a = {n: 2}: 此时a指向 {n: 2}
//再运算(a.x) = (a = {n: 2}),此时相当于给x赋值a,即:b = {n:1, x: {n:2}}
​
console.log("输出开始---------")
console.log("a.n:",a.n);
console.log("b.n:",b.n);
console.log("a.x:",a.x);
console.log("b.x:",b.x);
console.log("输出结束---------")
​
// 输出
输出开始---------
a.n: 2
b.n: 1
a.x: undefined
b.x: {n: 2}
输出结束---------

解析要点:a.x = a = {n: 2} => ”.“运算符比 ”=“ 运算符高,先计算a.x

第 4 题
console.log("c:",c);
var c;
function c(a) {
    console.log("a:",a);
    var a = 3;
    function a(){
    }
}
c(2);
​
// 输出的结果都是
function c(a){
    console.log(a);
    var a = 3;
    function a(){
    }
}
function a(){
}

解析要点:函数声明会提升(提升到console.log前面), 变量提升也有优先级, 函数声明 > arguments > 变量声明。

第 5 题
var c = 1;
function c(c) {
    console.log("function c:",c);
    var c = 3;
}
console.log("c:",c);
c(2);
​
​
//  输出
c:1
TypeError: c is not a function  

解析:由于函数声明会提升(提升到console.log前面),当函数外的console.log("c:",c);执行时,c已经被赋值为1。因此,执行c(2)时会抛出TypeError,因为1不是函数。

第 6 题
var name = 'erdong';
(function() {
    console.log('name0:', name);
    if (typeof name === 'undefined') {
        var name = 'chen';
        console.log('name1:', name);
    } else {
        console.log('name2:', name);
    }
})();
​
//输出
name0: undefined
name1: chen

解析:自执行函数执行时,会先进行变量提升(这里涉及到执行上下文),在自执行函数执行时,伪代码为:

var name = 'erdong';
(function () {
    var name;  // 变量name会提升到当前作用域顶部
    if (typeof name === 'undefined') {
        name = 'chen'
        console.log(name)
    } else {
        console.log(name)
    }
})();
第 7 题
var a = 10;
function test() {
    a = 100;
    console.log('a1:', a);
    console.log('this.a:', this.a);
    var a;
    console.log('a2:', a);
}
test();
​
// 输出
a1: 100
this.a: 10
a2: 100

解析:test()为函数独立调用,作用域中的this绑定为全局对象window。

test函数执行时,var a被提升到了作用域顶部,因此函数作用域中存在一个变量a。所以在函数中访问的a都是局部作用域中的a。

第 8 题
if (!('a' in window)) {
    var a = 1;
}
console.log('a:', a);
​
// 输出
a: undefined// 解析
console.log("'a' in window:", 'a' in window)
// 'a' in window: truevar b;
console.log("b:", 'b' in window)
// b: truevar c
console.log("c:", c in window)
// c: false

'a' in window => true, !('a' in window) => false, 所以,var a = 1; 不会执行

第 9 题
var a = 1;
function c(a, b) {
    console.log('a1:', a);
    a = 2;
    console.log('a2:', a);
}
c();
​
// 输出
a1: undefined
a2: 2
第 10 题
var val = 1;
var obj = {
    val: 2,
    del: function() {
        console.log('this:', this);
        this.val *= 2;
        console.log('val:', val);
        console.log('this.val:', this.val);
    }
};
obj.del();
​
//输出
this: {val: 2, del: function() { console.log('this:', this); this.val *= 2; console.log('val:', val); } }  即obj(指向的值)
val: 1
this.val: 4
var val = 1;
var obj = {
    val: 3,
    del: () => {
        console.log('this:', this);
        this.val *= 4;
        console.log('val:', val);
        console.log('this.val:', this.val);
    }
};
obj.del();
​
//输出
this: Window {0: global, window: Window, ...此处省略无数行 [[Prototype]]: Window
val: 4
this.val: 4

解析: 当通过obj.del()调用del函数时,del函数作用域中的this绑定为obj。

在函数作用域中访问val时,由于函数中并没有变量val,因此实际上访问的是全局作用域中的val,即 1。

\