一些經典的前端面試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);
}
複製代碼
相關文章
相關標籤/搜索