JavaScript: несколько распространенных ошибок на собеседованиях

интервью JavaScript

1. Введение

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

2. Объектно-ориентированное программирование

Что касается объектно-ориентированного и процессно-ориентированного, я лично считаю, что они не абсолютно независимы, а взаимно дополняют друг друга. Что касается того, когда использовать объектно-ориентированный, когда использовать процессно-ориентированный, конкретные ситуации, конкретный анализ.

для объектно-ориентированного программирования. На Zhihu есть хвалебный ответ:

Объектно-ориентированный: dog.eat(дерьмо)
Ориентирован на процесс: есть (собака, дерьмо).

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

Требования: Определение'Ожидание, чтобы съесть горячий горшок

Объектно-ориентированное мышление это:Ожидание Действие (съесть горячую кастрюлю)

Процессуальное мышление – это:Действие (ожидание, поедание горячего горшка)

Реализация кода:

//面向对象
//定义人(姓名)
let People=function(name){
    this.name=name;
}
//动作
People.prototype={
    eat:function(someThing){
        console.log(`${this.name}吃${someThing}`);
    }
}
//守候是个人,所以要创建一个人(new一次People)
let shouhou=new People('守候','男',24);
shouhou.eat('火锅');

//面向过程
let eat=function(who,someThing){
    console.log(`${who}吃${someThing}`);
}
eat('守候','火锅');

Результаты те же, все выводят «ожидание, чтобы съесть горячую кастрюлю». Но на случай, если я сейчас полон и готов писать код. Как этого добиться? см. код

//面向对象
shouhou.coding=function(){
    console.log(this.name+'写代码');
}
shouhou.coding();
//面向过程
let coding=function(who){
    console.log(who+'写代码');
}
coding('守候');

Тот же результат: «ожидание написания кода»

Но нетрудно обнаружить, что объектно-ориентированный язык является более гибким, повторно используемым и расширяемым. Потому что объектно-ориентированный — это выполнение определенных действий над объектами (в примере: «ожидание»). Эти действия могут быть расширены пользователем.
А процессно-ориентированный — это определить множество действий, указать, кто будет выполнять действие.

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

3.this

При разработке с помощью JavaScript многие разработчики будут более или менееthisУказатели сбивают с толку, но на самом деле примерноthisУкажите, запомните самое основное предложение:Какой объект вызывает функцию и на какой объект это указывает внутри функции.

Давайте обсудим следующие ситуации

3-1.Обычный вызов функции

Особой случайности в данном случае нет, он указывает на глобальный объект - окно.

let username='守候'
function fn(){
    alert(this.username);//undefined
}
fn();

Может все запутаются, почему бы и не вывести守候, но при ближайшем рассмотрении то, как я заявляю,let,нетwindowобъект
Если вывод ожидает, напишите так

var username='守候'
function fn(){
    alert(this.username);//守候
}
fu();
//---------------
window.username='守候'
function fn(){
    alert(this.username);//守候
}
fn();
//可以理解为
//window.fn();

3-2 Вызов функции объекта

Я думаю, это нетрудно понять, это вызов функции, где это указывает на

window.b=2222
let obj={
    a:111,
    fn:function(){
        alert(this.a);//111
        alert(this.b);//undefined
    }
}
obj.fn();

Очевидно, что в первый раз это выходobj.a, то есть 111. И второй раз,objнетbэто свойство, поэтому выводundefined,так какthisнаправлениеobj.

Но обратите внимание на следующее

let obj1={
    a:222
};
let obj2={
    a:111,
    fn:function(){
        alert(this.a);
    }
}
obj1.fn=obj2.fn;
obj1.fn();//222

Это убеждение нетрудно понять, хотяobj1.fnОтobj2.fnЗадание приходит, но звонящийobj1,такthisнаправлениеobj1.

3-3.Вызов конструктора

let TestClass=function(){
    this.name='111';
}
let subClass=new TestClass();
subClass.name='守候';
console.log(subClass.name);//守候
let subClass1=new TestClass();
console.log(subClass1.name)//111

Это не сложно понять, запомните(четыре шага нового)Почти готово!

А вот яма есть, хотя она вообще не появляется, но упомянуть надо.

Возврат объекта в конструкторе вернет объект напрямую, а не объект, созданный после выполнения конструктора.

3-4.подать заявку и позвонить

Применить и вызвать просто изменить this входящей функции.

let obj1={
    a:222
};
let obj2={
    a:111,
    fn:function(){
        alert(this.a);
    }
}
obj2.fn.call(obj1);

Хотя в это времяobj2метод вызывается, но с использованиемcall, динамическиthisуказать наobj1. эквивалентен этомуobj2.fnЭта среда выполненияobj1.applyиcallПодробности указаны ниже.

3-5 Вызов стрелочной функции

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

один пример

let obj={
    a:222,
    fn:function(){    
        setTimeout(function(){console.log(this.a)})
    }
};
obj.fn();//undefined

Хотя найти не сложноfn()внутриthisуказывает наobjоднако перейти кsetTimeoutобычная функция,thisуказать даwindow,windowнет нижеa, поэтому этот вывод undefined.

переключиться на функцию стрелки

let obj={
    a:222,
    fn:function(){    
        setTimeout(()=>{console.log(this.a)});
    }
};
obj.fn();//222

На этот раз выход222потому что, чтобыsetTimeoutявляется стрелочной функцией, и тогда в ней нет стрелочной функцииthis, поэтому найдите верхнюю область видимости, в этом примереsetTimeoutВерхняя областьfn. иfnвнутриthisнаправлениеobj,такsetTimeoutвнутри стрелочной функцииthis,направлениеobj. поэтому вывод222.

4.звоните и оставляйте заявку

callиapplyФункционал точно такой же, разница только в параметрах.
callПолученные параметры не фиксированы, первый параметр это тело функцииthisУказатель на второй параметр — это параметры, передаваемые по очереди.
apply получает два параметра, первый параметр также является телом функцииthisуказывает на. Второй параметр — это объект коллекции (массив или подобный массиву)

let fn=function(a,b,c){
console.log(a,b,c);
}
let arr=[1,2,3];

Как в примере выше

let obj1={
    a:222
};
let obj2={
    a:111,
    fn:function(){
        alert(this.a);
    }
}
obj2.fn.call(obj1);

callиapplyДва основных варианта использования

1. Изменитьthisуказывая на (поставитьthisотobj2указать наobj1)

2. Метод заимствования (obj1нетfn, просто позаимствовалobj2метод)

5. Закрытие

Закрытие может всех сбить с толку, но концепция, которую нужно победить! Вот простой пример

let add=(function(){
let now=0;
return {
 doAdd:function(){
    now++;
    console.log(now);
}
}
})()

Потом несколько раз!

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

Затем назначьте этот объектadd. так какaddВ нем есть функции, которые зависят отnow эта переменная. такnowНе будет уничтожен, переработан. Это одно из применений замыканий (продолжение переменных циклов). так какnowОн недоступен извне, что является еще одним использованием замыканий (создание локальных переменных, защита локальных переменных от доступа и изменения).

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

6. Резюме

При изучении паттернов проектирования это те точки знаний, с которыми я столкнулся.Эти точки знаний также являются контрольными точками, которые я нахожусь в групповом чате и сообществе, из-за чего люди попадают во многие ямы. Можно сказать, что эти знания обычно используются при разработке и часто проверяются на собеседованиях, поэтому рекомендуется изучить их более подробно. Вышеупомянутое также просто пройти. Не слишком глубоко. Если у вас есть какие-либо предложения по статье, пожалуйста, дайте указатели.

------------------------- Великолепная разделительная линия --------------------
Хотите узнать больше, обратите внимание на мой публичный аккаунт WeChat: В ожидании книжного магазина

clipboard.png