Предварительное интервью, письменный тест и руководство по неправильным вопросам (2)

внешний интерфейс JavaScript регулярное выражение опрос

Что ж, путь атаки Сяобая, продолжайте добавлять... Какие-то ямы перечитал еще раз.В первый раз пренебрег и ошибся, все равно делал заметки и прогрессировал вместе.

Что ж, серия интервью и ряды питов будут обновляться на гитхабе.Друзья, которые готовятся к осеннему набору, могут пройти мимо и зазвездиться, и вместе добиться прогресса O(∩_∩)O~:портал

JS специальный

1. Волшебные изменения в массивах

Каков результат следующего, пожалуйста

var arr1 = "john".split('');
var arr2 = arr1.reverse();
var arr3 = "jones".split('');
arr2.push(arr3);
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));

Отвечать:

"array 1: length=5 last=j,o,n,e,s"
"array 2: length=5 last=j,o,n,e,s"

Да, я обнаружил, что два выхода одинаковы.Давайте сначала поговорим о сути этого вопроса, а затем подумаем об этом.

  • Это массив не простого типа данных (типа значения), будет храниться в куче (куче), при использованииvar arr1 = arr2При присвоении значения это только поверхностная копия, и получаетсяarr2, проблема, которую это приносит, заключается в том, что изменениеarr1когдаarr2также пострадает.
  • arr1.push(arr2), поэтому существует функция, называемаяconcat,pushОн будет напрямую помещать в него весь массив, а не делать это отдельно Если вы понимаете два вышеуказанных пункта, проблема в основном решена.

2.+ - путаница операторов

Что выводит следующая программа?

console.log(1 +  "2" + "2");
console.log(1 +  +"2" + "2");
console.log(1 +  -"1" + "2");
console.log(+"1" +  "1" + "2");
console.log( "A" - "B" + "2");
console.log( "A" - "B" + 2);

Отвечать:

"122"
"32"
"02"
"112"
"NaN2"
NaN

Ну а ядром являются следующие моменты, хорошенько подумайте над этим

  • - +неявно преобразуется вNumberТипы
  • когда+появляется как оператор вStringПеред типом он будет думать, что требуется конкатенация строк, поэтому он будет неявно преобразован вString
  • NumberСодержит специальный тип NaN, который становится этим при выполнении числового преобразования нечислового.

Первый вопрос: Второй считает, что требуется конкатенация строк 1 преобразуется в1,Отвечать122 вопрос 2: обратите внимание на второй2передний+Нет, соответствует первой статье, поэтому вторая2преобразуется в числовой тип, ответ32 Вопрос 3: то же, ответ02 Вопрос 5.: Используя (1)(3), очевидноNaN2, шестой вопрос тот же

3. Тайна переполнения стека

Следующий код вызовет переполнение стека, как его оптимизировать без изменения исходной логики

var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        nextListItem();
    }
};

Отвечать:

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        setTimeout(nextListItem,0}
};

Прежде всего, мы должны выяснить причину переполнения стека.

В JS неосторожные операции или привычки программирования могут легко привести к переполнению стека, особенно при выполнении обратных вызовов или циклов. Процитируйте следующее, чтобы проиллюстрировать причину переполнения:

Причина в том, что каждый раз при выполнении кода будет выделяться пространство стека определенного размера (1M в системе Windows), и определенная информация (такая как параметры, локальные переменные, возвращаемые значения и т. д.) будет храниться в стековом массиве. стек каждый раз, когда вызывается метод.Неважно, насколько мало, это займет определенное количество места.Накопление тысяч таких мест, естественно, превысит пространство стека потока. Так как же решать такие проблемы?

Вот две идеи решения этой проблемы:

  1. асинхронный
  2. Закрытие

Очевидно, здесь используется первый метод — замыкания. Почему использование setTimeout решает проблему? Давайте посмотрим на разницу с предыдущим. Если setTimeout не используется, функция продолжит обратный вызов перед большими данными, пока не будет достигнута конечная точка, начальная функция будет выполняться до конца и память будет освобождена. Но если вы используетеsetTimeout, мы знаем, что он асинхронный, даже если время установлено на 0, он позволяет сначала выполнить следующее содержимое, что может освободить стек, тем самым избегая проблемы переполнения стека. Другими словами, добавлениеsetTimeout, функция nextListItem помещается вочередь событий, функция может выйти, поэтому стек служебной информации каждый раз очищается.

ЗакрытиеТо же самое верно, потому что этот вопрос не требует модификации исходной логики, первый из них является наиболее подходящим ответом, конечно, способ избежать его с помощью замыкания - это вернуть функцию

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        return nextListItem()
    }
};

Конечно, это изменит способ вызова функции, и нам нужно продолжать вызыватьnextListItem()()()Чтобы справиться с этим подходом, он может быть дополнительно инкапсулирован

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        return function() {
            return nextListItem()
        }
    }
};

function autoRun(fun) {
    var value = nextListItem();
    while(typeof value === 'function') {
        value = nextListItem()
    }
    return
}

Таким образом решается проблема переполнения стека. Источник идеи замыкания здесь тот же, что ирешение переполнения стека

4. Вы действительно понимаете тональность объекта?

Каков результат следующей функции?

var a={},
    b={key:'b'},
    c={key:'c'};

a[b]=123;
a[c]=456;

console.log(a[b]);

Отвечать: Выход такой456,нет123, по крайней мере, у меня есть немного снаружи ...

какова причина? Если вы понимаете новую карту типов данных ES6 здесь, вы должны понимать, что да, значение ключа объекта разрешено толькоStringtype, поэтому был введен тип данных карты. Что ж, если в качестве значения ключа используется объект, он будет вызыватьсяtoStringметод.

Object.prototype.toString(obj)Что вы получите? Правильно `[объект Объект]. так-так

a[b] ==> a["[object Object"] = 123;
a[b] ==> a["[object Object"] = 456;

Ответ очевиден

5. Палиндромное суждение

Пожалуйста, сделайте функцию оценки палиндрома, чтобы определить, является ли это палиндромом

Ответ: Это очень простой и традиционный метод. Связанный список — лучший способ судить о палиндроме, конечно, благодаря гибкому методу массива JS его проще реализовать.

Основным соображением здесь является проблема надежности, и есть дополнительный регулярный запрос для обнаружения:

function check(str) {
    str = str.replace(/\W/g,'').toLowerCase();
    return str === str.split('').reverse().join()
}