Рукописный код, который часто тестируют на фронтенд-интервью, не запоминается!

JavaScript опрос
Рукописный код, который часто тестируют на фронтенд-интервью, не запоминается!

предисловие

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

Об авторе: koala, сосредоточив внимание на совместном использовании полного стека технологий Node.js, от JavaScript до Node.js, до серверной базы данных, я желаю вам стать отличным старшим инженером Node.js. [Руководство по развитию программиста] Автор, блог Github с открытым исходным кодомGitHub.com/koala-co Nth…

1. Название и конкретные функции

дать имя

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

  • Соответствие кодексу
  • Имя функции прямо названо английским именем функции (здесь вы должны знать, какую функцию может выполнить функция, которую вы хотите написать вручную)
  • Что касается передаваемых параметров, а также некоторых массивов, переменных и т.д., объявленных внутри функции, то вообще не думайте об этом слишком много, вы можете использовать их напрямуюarrа такжеarr+功能名称Стенография.

На самом деле, вы можете напрямую использовать arr1, arr2 вместо этого, это хорошо, чтобы иметь возможность различать, не тратьте время на такие вещи.

2. Новые переменные и возвращаемые значения

Прочитав рукописные вопросы собеседования, вы можете посмотреть, следует ли объявлять новую переменную, и результаты должны возвращать тип результатов.

  • сглаженный массив определенно нужновернуть массив, вы можете рассмотреть способ объявления массива в начале или вы можете рассмотреть возможность использования карты, фильтра и других функций для прямого возврата.
  • Глубокая копия объекта Обязательно нужно вернуть скопированный объект, который будет изначальнообъявить пустой объект,наконецвернутьэто обработанообъект.
  • Во многих случаях вы можете объявить новую переменную или не объявлять новую переменную, что может решить проблему, но вам необходимо учитывать временную и пространственную сложность, просто сначала используйте одну реализацию. Интервьюер будет продолжать спрашивать, есть ли у вас другие варианты, хе-хе.

3. Рассмотрите возможность использования цикла? рекурсия?

цикл

Для цикла

  1. FOR имеет три выражения: 1 объявляет переменные цикла, 2 оценивает условие цикла, 3 обновляет переменную цикла,

Между тремя выражениями используйте ;, чтобы разделить их.Все три выражения в цикле for можно опустить, но два ";" необходимы. 2. Характеристики выполнения цикла for: сначала оценить, а затем выполнить, как и в случае с while. 3. Три выражения цикла for могут состоять из нескольких частей.Множественные условия оценки второй части соединяются символом && ||, а первые три части разделяются запятыми;

for (var num =1; num<=10; num++) {
    document.write(num+" <br />"); //1 2 3 4 5 6 7 8 9 10 
}

для в цикле

Цикл for-in в основном используется для перебора объектов. Формат в for(): for(keys in object){} keys представляет собой ключ каждой пары ключ-значение объекта obj! ! Во всех циклах вам нужно использовать obj[keys] для получения каждого значения! ! !

Цикл for-in может не только считывать свойства члена самого объекта, но и продолжать цепочку прототипов для обхода свойств прототипа объекта. Итак, вы можете использовать hasOwnProperty, чтобы определить, является ли свойство свойством самого объекта.

obj.hasOwnProperty(keys)==true указывает, что это свойство является свойством-членом объекта, а не исходным свойством.

//声明一个Peson类
function Person(){
    this.name = "kaola";
    this.age = 24;
    this.func1 = function(){
        
    }
}
//实例化这个类
var bei = new Person();
//使用for-in遍历这个对象
for(keys in bei){
    console.log(bei[keys])
}

Для о циклов

Опираясь на C++, Java, C# и Python, ES6 представила цикл for...of как унифицированный способ обхода всех структур данных.

Считается, что структура данных имеет интерфейс итератора, пока развернуто свойство Symbol.iterator, а его элементы могут быть перебраны с помощью цикла for...of. То есть цикл for...of вызывает метод Symbol.iterator структуры данных.

Диапазон циклов for...of, которые можно использовать, включает массивы, структуры Set и Map, определенные массивоподобные объекты (такие как объекты arguments, объекты DOM NodeList), объекты Generator ниже и строки.

рекурсия

Подробнее о рекурсии см. в моей статье Рекурсивный рукописный код, обычно используемый в статье, написан.

4. Учитывайте границы

4.1 Оценка типа

Как определить тип данных? Как определить, является ли значение типом массива или объектом?

соответственно тремя способамиtypeof,instanceofа также Object.prototype.toString.call()

typeof

пройти черезtypeofоператор, чтобы определить, к какому примитивному типу принадлежит значение.

typeof 'seymoe'    // 'string'
typeof true        // 'boolean'
typeof 10          // 'number'
typeof Symbol()    // 'symbol'
typeof null        // 'object' 无法判定是否为 null
typeof undefined   // 'undefined'

typeof {}           // 'object'
typeof []           // 'object'
typeof(() => {})    // 'function'

Вывод приведенного выше кода можно увидеть,

  1. nullВ суждении есть ошибка, а результат получен

При использованииtypeof nullПолученный результатobject

  1. Оператор определяет тип объекта и его подтипы, такие как функции (вызываемые объекты), массивы (объекты упорядоченного индекса) и т. д., все, кроме функций, получатobjectрезультат.

в подтипах объектов иnullслучае видно, чтоtypeOfДля определения типа есть некоторые недостатки.

instanceof

пройти черезinstanceofОператор также может определить тип объекта, принцип заключается в проверке конструктора. prototypeПрисутствует ли он в цепочке прототипов обнаруженного объекта.

[] instanceof Array            // true
({}) instanceof Object         // true
(()=>{}) instanceof Function   // true

Копировать код Примечание:instanceofИ не панацея.

Например:

let arr = []
let obj = {}
arr instanceof Array    // true
arr instanceof Object   // true
obj instanceof Object   // true
obj instanceof Array   // false

В этом примереarrМассив эквивалентенnew Array()из экземпляра, поэтомуarr.__proto__ === Array.prototype,и потому, чтоArray принадлежатьObjectподтип, т.е. Array.prototype.__proto__ === Object.prototype,следовательноObjectКонструкторarrв цепочке прототипов. такinstanceofДо сих пор нет способа элегантно определить, принадлежит ли значение массиву или обычному объекту.

Еще одно замечание, скажут некоторые разработчики.Object.prototype.__proto__ === null, разве это не говоритarr instanceof nullтакже должно бытьtrue, этот оператор фактически сообщит об ошибке, указывающей, что параметр справа должен быть объектом, что также подтверждает, чтоtypeof nullРезультатobjectдействительно простоjavascriptодин из bug.

Object.prototype.toString()(рекомендуемые)

так сказатьJavaScriptОкончательное решение для типа данных в , см. следующий код для конкретного использования:

Object.prototype.toString.call({})              // '[object Object]'
Object.prototype.toString.call([])              // '[object Array]'
Object.prototype.toString.call(() => {})        // '[object Function]'
Object.prototype.toString.call('seymoe')        // '[object String]'
Object.prototype.toString.call(1)               // '[object Number]'
Object.prototype.toString.call(true)            // '[object Boolean]'
Object.prototype.toString.call(Symbol())        // '[object Symbol]'
Object.prototype.toString.call(null)            // '[object Null]'
Object.prototype.toString.call(undefined)       // '[object Undefined]'

Object.prototype.toString.call(new Date())      // '[object Date]'
Object.prototype.toString.call(Math)            // '[object Math]'
Object.prototype.toString.call(new Set())       // '[object Set]'
Object.prototype.toString.call(new WeakSet())   // '[object WeakSet]'
Object.prototype.toString.call(new Map())       // '[object Map]'
Object.prototype.toString.call(new WeakMap())   // '[object WeakMap]'

Мы можем обнаружить, что этот метод может возвращать соответствующий точный тип объекта, когда передается значение любого типа. Хотя использование простое и понятное, есть несколько моментов, которые необходимо четко понимать:

  • Этот метод по сути полагаетсяObject.prototype.toString() метод для получения внутренних свойств объекта[[Class]]
  • Передача примитивного типа, но возможность определить результат, потому что значение обернуто
  • nullа такжеundefinedВозможность вывода результатов обеспечивается внутренней реализацией

Для оценки типа мы можем выполнить простую инкапсуляцию через Object.prototype.toString(), чтобы при оценке типа мы могли напрямую использовать функцию типа.

код показывает, как показано ниже:

var type = function(data) {
      var toString = Object.prototype.toString;
      var dataType = toString
              .call(data)
              .replace(/\[object\s(.+)\]/, "$1")
              .toLowerCase()
      return dataType
};

Array.isArray()

Параметры передачи Array.isArray могут быть определены, является ли массив. Обратите внимание, что этоArray.isArrayдаES 5.1запущен, не поддерживаетсяIE6~8, поэтому вам также следует обратить внимание на проблемы совместимости при его использовании.

  • Решения несовместимости
    if (!Array.isArray) {
      Array.isArray = function(arg) {
        return Object.prototype.toString.call(arg) === '[object Array]';
      };
    }
    

4.2 Нулевое оценочное суждение

Важность нулевого решения

  if([]) {
    console.log('true');
  } else {
    consoel.log('false');
  }
  // res:true
  
  if({}) {
    console.log('true');
  } else {
    consoel.log('false');
  }
  // res:true

Глядя на этот код, я не знаю, подумает ли кто-нибудь из моих друзей, что вывод будет ложным.Хотя приведенные выше объекты и массивы пусты, они будут преобразованы в истину, поэтому обратите особое внимание при написании некоторых условий суждения.

Оценка пустого массива

Пустой массив очень прост, указанный выше тип считается типом массива, а затем егоlength>0Только что

Суждение о пустом объекте

  1. Object.getOwnPropertyNames()

    использоватьObject.getOwnPropertyNames(). Возвращаемое значение представляет собой массив именованных свойств в объекте.

    var obj = {}
    Object.getOwnPropertyNames(obj).length === 0; // true
    
  2. Строковый объект в json

    Преобразуйте объект JSON в строку, затем сравните строку и "{}" равно

    var obj = {};
    var a = JSON.stringify(obj);
    a === "{}"; // true
    // a === {}; // false
    
  3. for...in... петлевой суд

    var obj = {};
    
    function judgeObj(obj) {
      for(let key in obj) {
        return false
      }
      return true
    };
    
    judgeObj(obj); // true
    
  4. Object.keys()

    Используйте Object.keys(). Новый метод ES6, возвращаемое значение также представляет собой массив имен свойств.

    var obj = {}
    Object.keys(obj).length === 0; // true
    
  5. Оценка непосредственно по свойствам объекта Предпосылка состоит в том, чтобы убедиться, что если obj не пуст, он должен содержать атрибут имени

    var obj = {};
    
    obj && obj.name ? '不为空' : '为空'; // 
    

4.3 Использование знака равенства

Процесс сравнения:

  • Двойное равно ==:

(1) Если два типа значений одинаковы, сравните три знака равенства (===)

(2) Если два типа значений различны, они также могут быть равны, и преобразование типов должно выполняться в соответствии со следующими правилами сравнения:

1) Если одно равно нулю, а другое не определено, то равно

2) Если одно является строкой, а другое — числовым значением, преобразуйте строку в числовое значение, а затем сравните

  • Три знака равенства ===:

(1) Если типы разные, они не должны быть равны

(2) Если оба являются числовыми значениями и являются одним и тем же значением, то они равны; если хотя бы одно из них равно NaN, то они не равны. (Чтобы определить, является ли значение NaN, можно использовать только функцию isNaN().)

(3) Если обе являются строками и символы в каждой позиции одинаковы, то они равны, в противном случае они не равны.

(4) Если оба значения истинны или ложны, то они равны

(5) Если оба значения относятся к одному и тому же объекту или функции, то они равны, в противном случае они не равны

(6) Если оба значения равны нулю или не определены, то они равны

5. Освоение общих функций строковых объектов массива

5.1 Общие функции части массива

функция объединения (изменение исходного массива)

  • Есть функция добавления элементов в указанную позицию массива

Array.splice(begin, deleteCount, addItem1, addItem2...)

// a的初始值:[1,2,3,4,5]

var b = arr.splice(1,2)
// a: [1,4,5]
// b: [2,3]

var c = arr.splice(1,2,777,888)
// a: [1,777,888,4,5]
// b: [2,3]

функция slice (не меняйте исходный массив, создайте новый массив)

Метод slice() неглубоко копирует часть элементов массива в новый объект массива и возвращает объект массива.

语法:arr.slice([start[, end]])

параметрstartиндекс, определяющий начало репликации,endЕсли значение индекса указывает конечное положение воспроизведения (эта позиция не входит в комплект).

еслиstartЗначение отрицательное, если длина массиваlength, то есть начать копирование с позиции length+start, если параметр end имеет значение, то оно может быть только на отрицательное число больше start, иначе будет возвращен пустой массив.

Когда параметр метода slice пуст, как и метод concat, это поверхностная копия для создания нового массива.

var array = ["one", "two", "three","four", "five"];
console.log(array.slice()); // ["one", "two", "three","four", "five"]
console.log(array.slice(2,3)); // ["three"]

Поверхностная копия означает, что при копировании объекта копируется только ссылка на объект, а точка остается тем же объектом. Давайте объясним, почему slice — это поверхностная копия.

var array = [{color:"yellow"}, 2, 3];
var array2 = array.slice(0,1);
console.log(array2); // [{color:"yellow"}]
array[0]["color"] = "blue";
console.log(array2); // [{color:"bule"}]

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

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

console.log([1,2,3].slice(-1));//[3]

присоединиться к функции

Метод join() объединяет все элементы массива в строку.

语法 arr.join('xxx')

var b = arr.join(','); // b: '1,2,3'
var b = arr.join('*'); // b: '1*2*3'

функция нажатия

Добавьте значения в массив.

Функция CONCAT

метод concat() входящего массива или массива элементов с исходным, объединенным для формирования нового массива и возврата.

функция indexOf

Метод indexOf() используется для поиска индекса первого вхождения элемента в массив и возвращает -1, если его нет.

грамматика:arr.indexOf(element, fromIndex=0)

element — это элемент, который нужно найти.

fromIndex — это позиция для начала поиска, значение по умолчанию равно 0. Возвращает -1, если длина массива превышена. Если это отрицательное значение, то при условии, что длина массива равна length, поиск начинается с элемента length + fromIndex массива до конца массива, если length + fromIndex

indexOf использует строгое равенство (т. е. использует === для сопоставления элементов в массиве).

var array = ['abc', 'def', 'ghi','123'];
console.log(array.indexOf('def')); // 1
console.log(array.indexOf('def',-1)); // -1 此时表示从最后一个元素往后查找,因此查找失败返回-1
console.log(array.indexOf('def',-4)); // 1 由于4大于数组长度,此时将查找整个数组,因此返回1
console.log(array.indexOf(123)); // -1, 由于是严格匹配,因此并不会匹配到字符串'123'

включает в себя функции

включает() методНа основе спецификации ECMAScript 2016 (ES7), который используется для определения того, содержит ли текущий массив указанное значение, и если да, то возвращает true, в противном случае возвращает false.

грамматика:arr.includes(element, fromIndex=0)

element — это элемент, который нужно найти.

fromIndex означает поиск элемента с позиции индекса, по умолчанию 0, это прямой поиск, то есть поиск от индекса до конца массива.

var array = [-0, 1, 2];
console.log(array.includes(+0)); // true
console.log(array.includes(1)); // true
console.log(array.includes(2,-4)); // true

Кажется, что include игнорирует разницу между -0 и +0 , что не является проблемой, поскольку JavaScript всегда был неотличим от -0 и +0 .

Вы можете спросить, если есть метод indexOf, зачем создавать метод include, arr.indexOf(x)>-1 не равен arr.includes(x)? Кажется, да, почти всегда они эквивалентны, единственная разница в том, что include может найти NaN, а indexOf — нет.

var array = [NaN];
console.log(array.includes(NaN)); // true
console.log(arra.indexOf(NaN)>-1); // false

(Здесь вы можете рассмотреть, какие indexOf и include более эффективны, и базовую реализацию)

Есть много функций массива, и только несколько часто используемых перечислены выше.Я нашел очень подробную статью о функциях массива, которая очень хороша.Спасибо автору за то, что поделился, и рекомендую ее всем:Дом Луи.GitHub.IO/2017/04/28/…

5.2 Общие функции строк

функция разделения

  • разбить строку на массив
  • не изменяет исходную строку
string.split(separator,limit)

функция substr

Метод substr() возвращает указанное количество символов, начиная с указанной позиции в строке.

грамматика:str.substr(start[, length])

start указывает позицию начала перехвата символов, которая может принимать положительное или отрицательное значение. Положительное значение указывает индекс начальной позиции, а отрицательное значение указывает индекс длины+начальной позиции.

length указывает длину символов, которые необходимо обрезать.

var str = "Yesterday is history. Tomorrow is mystery. But today is a gift.";
console.log(str.substr(47)); // today is a gift.
console.log(str.substr(-16)); // today is a gift.

Есть много функций массива, и только несколько часто используемых перечислены выше.Я нашел очень подробную статью о строковых функциях, которая очень хороша.Спасибо автору за то, что поделился, и рекомендую ее всем:Дом Луи.GitHub.IO/2016/01/12/…

5.3 Общие функции объектов

Object.prototype.hasOwnProperty(prop)

Этот метод возвращает true, только если целевое свойство является собственным свойством объекта, и возвращает false, если свойство унаследовано от цепочки прототипов или вообще не существует.

var o = {prop:1};
o.hasOwnProperty('prop'); // true
o.hasOwnProperty('toString'); // false
o.hasOwnProperty('formString'); // false

Object.create(obj, descr) (ES5)

Этот метод в основном используется для создания нового объекта и установки для него прототипа с использованием (выше) дескриптора свойства для определения свойств прототипа объекта.

var parent = {hi: 'Hello'};
var o = Object.create(parent, {
    prop: {
        value: 1
    }
});
o.hi; // 'Hello'
// 获得它的原型
Object.getPrototypeOf(parent) === Object.prototype; // true 说明parent的原型是Object.prototype
Object.getPrototypeOf(o); // {hi: "Hello"} // 说明o的原型是{hi: "Hello"}
o.hasOwnProperty('hi'); // false 说明hi是原型上的
o.hasOwnProperty('prop'); // true 说明prop是原型上的自身上的属性。

Теперь мы даже можем использовать его для создания совершенно пустого объекта, что-то подобное невозможно в ES3.

var o = Object.create(null);
typeof o.toString(); // 'undefined'

Есть много функций массива, и только несколько часто используемых перечислены выше.Я нашел очень подробную статью об объектных функциях, которая очень хороша.Спасибо автору за то, что поделился, и рекомендую ее всем:Woohoo.Биография Лу Синя 12. Талант / is-object-ah...

6. Общие специальные инструкции

6.1 объект, подобный массиву аргументов

Что такое массивоподобный объект, например:

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

Несколько способов массивоподобного преобразования

  • Оператор распространения ES6 для преобразования

    var arr1 = [...arrayLike]; // ['a','b','c']
    
  • Array.from в ES6

    let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
    

    Array.from()Другое приложение состоит в том, чтобы преобразовать строку в массив, а затем вернуть длину строки.

    function countSymbols(string) {
      return Array.from(string).length;
    }
    
  • Array.prototype.slice.call() в ES5

    function test(a,b,c,d) 
       { 
          var arg = Array.prototype.slice.call(arguments,1); 
          alert(arg); 
       } 
       test("a","b","c","d"); //b,c,d
    
    • Первый параметр — контекст (то есть значение контекста), который используется для замены this в объектной функции
    • Второй параметр — это параметр, передаваемый объектной функции.

    Array.prototype.slice.call(arguments)в состоянии иметьlengthобъекты свойств в массивы, за исключениемIEНабор узлов ниже (поскольку объект dom под ie реализован в виде объекта com, а объект js и объект com не могут быть преобразованы)

6.2 Использование функций высшего порядка

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

7. Докажите интервьюеру, что ES6 также

Когда вы пишете код вручную, подумайте о том, как его можно реализовать в сжатой форме с помощью ES6. (Здесь вы можете взглянуть на операторы расширения ES6..., наборы коллекций, функции стрелок и другие часто используемые точки знаний ES6, прикрепить адрес книги учителя ES6 Руана Ифэна:es6.ruanyifeng.com/)

8. Упражнение

В Node.js есть модуль queryString, который может преобразовывать параметры за адресом хоста urlStr в объекты.

let urlStr = 'http://www.inode.club?name=koala&study=js&study=node';

Результат преобразования следующий:

{ name: 'koala', study: [ 'js', 'node' ] }

Код

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

let urlStr = 'http://www.inode.club?name=koala&study=js&study=node'
// 参数转成对象
function queryString(request){
    let params = request.split('?')[1];
    let param = params.split('&');
    let obj = {};
    for (let i = 0;i<param.length;i++){
        let paramsA = param[i].split('=');
        let key = paramsA[0];
        let value = paramsA[1];
        if(obj[key]){
            obj[key] = Array.isArray(obj[key])?obj[key]:[obj[key]];
            obj[key].push(value);
        }else{
            obj[key] = value;
        }
    }
    return obj;
}
console.log(queryString(urlStr));

Суммировать

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

Подписывайтесь на меня

  • Добро пожаловать, чтобы добавить меня в WeChat [ coder_qi ], привлечь вас Node.js в техническую группу, общаться и учиться в течение длительного времени...
  • Добро пожаловать, чтобы обратить внимание на «Руководство по развитию программиста на севере», общедоступную учетную запись, которая поможет вам расти с душой...

Справочная документация

ES6 Руан Ифэн

Все API строк JavaScript полностью расшифрованы

Весь API-анализ объектов JavaScript

Оригинальные статьи серии Node

Глубокое понимание процессов и потоков в Node.js

Если вы хотите изучить Node.js, сначала необходимо понять поток.

Когда требуется, вы действительно понимаете разницу между экспортом и модулем.экспорт?

В статье об интерпретации исходного кода подробно рассматривается модуль Events.

Node.js расширенное расширенное изучение файлового модуля fs