一些经典的前端面试JavaScript代码分析题(附答案)--第二回合

  1. 下面代码的输出是什么?
// counter.js
let counter = 10;
export default counter;

// index.js
import myCounter from './counter';

myCounter += 1;
console.log(myCounter);
复制代码

答案:Error
解析:数组

引入模块是只读的,不能修改。promise


  1. 下面代码的输出是什么?
const name = 'Jack';
age = 21;

console.log(delete name);
console.log(delete age);
复制代码

答案:false, true
解析:app

delete操做符返回一个布尔值,true表示返回成功,false为返回失败。可是经过varconstlet关键词声明的变量没法使用delete操做符删除。异步


  1. 下面代码的输出是什么?
const person = { name: 'Jack' };
Object.defineProperty(person, 'age', { value: 21 });

console.log(person);
console.log(Object.keys(person));
复制代码

答案:{ name: 'Jack', age: '21'}, ['name']
解析:async

使用Object.defineProperty方法添加的属性默认是不可枚举(not enumerable)。用defineProperty方法添加的属性默认不可变。你能够经过 writable, configurableenumerable属性来改变这一行为函数


  1. 下面代码的输出是什么?
let num = 10;

const increaseNumber = () => num++;
const increasePassedNumber = number => number++;

const num1 = increaseNumber();
const num2 = increasePassedNumber(num1);

console.log(num1);
console.log(num2);
复制代码

答案:10, 10
解析:ui

一元操做符 ++ 先返回 操做值, 再累加 操做值。num1的值是 10, 由于 increaseNumber函数首先返回num的值,也就是 10,随后再进行num的累加。
num2是10由于咱们将num1传入increasePassedNumber。形参number接收的值是10,因此num2也是10.this


  1. 下面代码的输出是什么?
const value = { number: 10 };
const multiply = (x = {...value}) => {
    console.log(x.number *= 2);
}

multiply();
multiply();
multiply(value);
multiply(value);
复制代码

答案:20, 20, 20, 40
解析:spa

x = {...value}这种解构赋值的结果是给x建立了与原对象有相同属性的新对象,产生了新的的内存空间,因此此时对x的属性操做不影响原来的对象。code


  1. 下面代码的输出是什么?
[1, 2, 3, 4].reduce((x, y) => console.log(x, y));
复制代码

答案:1 2, undefined 3, undefined 4
解析:

reduce传入的参数是函数,那么该函数应该有返回值,若是没有则默认返回undefined


  1. 下面代码的输出是什么?
// index.js
console.log('running index.js');
import { sum } from './sum.js'
console.log(sum(1, 2));

// sum.js
console.log('running sum.js');
export const sum = (a, b) => a + b;
复制代码

答案:running sum.js, running index.js, 3
解析:

import命令是编译阶段执行的,在代码运行以前。也就是说呗导入的模块会先运行,而导入模块的文件会后执行。这是CommonJS中require()import之间的区别。使用require(),您能够在运行代码时根据须要加载依赖项。若是咱们使用require则 running index.js, running sum.js, 3会被依次打印。


  1. 下面代码的输出是什么?
async function getData() {
    return await Promise.resolve('hello world');
}

const data = getData();
console.log(data);
复制代码

答案:Promise{}
解析:

异步函数始终返回一个promise。当咱们调用getData()并将其赋值给data,此时 datagetData方法返回的一个挂起的promise,该promise并无解决。若是咱们想要访问已解决的值 "hello world",能够在data上使用 .then()方法:data.then(res=>console.log(res)) 这样将打印 "hello world"


  1. 下面代码的输出是什么?
function addToList(item, list) {
    return list.push(item);
}

const result = addToList('apple', ['banana']);
console.log(resule);
复制代码

答案:2
解析:

push()方法返回新数组的长度。


  1. 下面代码的输出是什么?
var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log("outer func: this.foo = " + this.foo);
        console.log("outer func: self.foo = " + self.foo);
        (function() {
            console.log("inner func: this.foo = " + this.foo);
            console.log("inner func: self.foo = " + self.foo);
        }());
    }
};
myObject.func();
复制代码

答案:

outer func:  this.foo = bar
outer func:  self.foo = bar
inner func:  this.foo = undefined
inner func:  self.foo = bar
复制代码

解析:

在外部函数中,thisself 二者都指向了myObject,所以二者均可以正确地引用和访问foo。内部函数为自执行函数,其默认调用者是window,所以该执行性函数的内部this指向window。可是self是自定义变量,它会经过做用域链逐层向上查找,最后能够找到其在上层做用域中已经有定义。


  1. 下面代码的输出是什么?
console.log(typeof NaN === 'number');
console.log(NaN === NaN);
复制代码

答案:true, false


  1. 下面代码的输出是什么?
for (var i = 0; i < 5; i++) {
  setTimeout(function() { console.log(i); }, i * 1000 );
}
复制代码

答案:5, 5, 5, 5, 5
怎么才能按照预期输出0,1,2,3,4

// 方法1将var改成let
for (let i = 0; i < 5; i++) {
  setTimeout(function() { console.log(i); }, i * 1000 );
}

// 方法2 外面封装一层自执行函数,造成私有做用域
for (var i = 0; i < 5; i++) {
    (function(x) {
        setTimeout(function() { console.log(x); }, x * 1000 );
    })(i);
}
复制代码
相关文章
相关标签/搜索