Изучение JavaScript с помощью ChatGPT-4 было только что выпущено, и оно представляет собой значительные улучшения по сравнению с ChatGPT на базе GPT-3.5.5. Среди улучшений — улучшенная способность поддерживать согласованность в течение более длительных сеансов и более крупных подсказок.

GPT-4 был только что выпущен, и он представляет собой значительное улучшение по сравнению с ChatGPT на основе GPT-3.5. Среди улучшений — улучшенная способность поддерживать согласованность в течение более длительных сеансов и более крупных подсказок.

Я потратил годы на создание EricElliottJS.com, чтобы научить разработчиков важным концепциям для разработчиков JavaScript. Мне было любопытно, насколько хорошо я могу использовать такие инструменты, как ChatGPT, для ускорения обучения и обучения разработчиков программного обеспечения, поэтому я решил проверить его новые возможности.

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

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

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

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

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

И вот результат:

ChatGPT:

Здравствуйте и добро пожаловать на курс JavaScript! Я рад помочь вам изучить и расширить свои навыки JavaScript. Прежде чем мы начнем, я рекомендую настроить VSCode с расширением Quokka, которое предоставит вам интерактивную обратную связь с консолью JavaScript.

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

Начнем с первой темы: переменные и типы данных.

Вопрос 1. В чем разница между const, let и var при объявлении переменной?

Не стесняйтесь запускать следующий код в среде VSCode с поддержкой Quokka:

const constVar = 'constant';
let letVar = 'let';
var varVar = 'var';
// Observe the behavior when you try to reassign each variable:
constVar = 'newConstant';
letVar = 'newLet';
varVar = 'newVar';

Что происходит, когда вы пытаетесь переназначить значения трех переменных?

Студент:
Переназначение const вызвало ошибку: Assignment to constant variable. Переназначения let и var не выполнялись из-за ошибки.

ChatGPT:
Верно! Переменные const нельзя переназначать, а переменные let и var можно. Ошибка, с которой вы столкнулись, ожидается при попытке переназначить переменную const.

Теперь давайте перейдем к следующей теме: Функции.

Вопрос 2: Напишите функцию add, которая принимает два числа в качестве аргументов и возвращает их сумму.

Вот шаблон для начала:

function add(a, b) {
  // Your code here
}
// Test your function with these inputs:
console.log(add(5, 3)); // Expected output: 8
console.log(add(-2, 10)); // Expected output: 8

Предоставьте свое решение и запустите тесты, чтобы подтвердить свою реализацию.

Ученик:

function add(a, b) {
  return a + b;
}
console.log(add(5, 3)); // Actual output: 8
console.log(add(-2, 10)); // Actual output: 8

ChatGPT:

Большой! Ваша функция add выглядит правильно.

Теперь давайте перейдем к следующей теме: Массивы.

Вопрос 3: Напишите функцию с именем findMax, которая принимает массив чисел и возвращает максимальное число в массиве.

Вот шаблон для начала:

function findMax(numbers) {
  // Your code here
}
// Test your function with these inputs:
console.log(findMax([1, 5, 9, 3])); // Expected output: 9
console.log(findMax([-2, -5, -1, -8])); // Expected output: -1

Предоставьте свое решение и запустите тесты, чтобы подтвердить свою реализацию.

Ученик:

function findMax(numbers) {
  return Math.max(…numbers);
}
// Test your function with these inputs:
console.log(findMax([1, 5, 9, 3])); // Actual output: 9
console.log(findMax([-2, -5, -1, -8])); // Actual output: -1

ChatGPT:

Отличный! Ваша функция findMax выглядит правильно, и вы использовали оператор распространения с Math.max(), чтобы найти максимальное значение в массиве.

Теперь давайте перейдем к следующей теме: Объекты.

Вопрос 4: Напишите функцию с именем createPerson, которая принимает два аргумента, name и age, и возвращает объект со свойствами name и age, установленными в предоставленные значения.

Вот шаблон для начала:

function createPerson(name, age) {
  // Your code here
}
// Test your function with these inputs:
console.log(createPerson('Alice', 30)); // Expected output: { name: 'Alice', age: 30 }
console.log(createPerson('Bob', 42)); // Expected output: { name: 'Bob', age: 42 }

Предоставьте свое решение и запустите тесты, чтобы подтвердить свою реализацию.

Ученик:

function createPerson(name, age) {
  return {name, age};
}
// Test your function with these inputs:
console.log(createPerson('Alice', 30)); // Actual output: { name: 'Alice', age: 30 }
console.log(createPerson('Bob', 42)); // Actual output: { name: 'Bob', age: 42 }

ChatGPT:

Отличная работа! Ваша функция createPerson верна, и вы использовали сокращенные имена свойств в возвращаемом объекте.

Вы продемонстрировали хорошее понимание переменных, типов данных, функций, массивов и объектов. Теперь давайте углубимся в более сложные концепции JavaScript.

Тема: Асинхронный JavaScript

Вопрос 5: Напишите функцию с именем wait, которая принимает в качестве аргумента количество миллисекунд и возвращает промис, который разрешается через указанное количество миллисекунд.

Вот шаблон для начала:

function wait(milliseconds) {
  // Your code here
}
// Test your function with these inputs:
wait(1000).then(() => console.log('1 second has passed'));
wait(2000).then(() => console.log('2 seconds have passed'));

Предоставьте свое решение и запустите тесты, чтобы подтвердить свою реализацию.

Ученик:

function wait(milliseconds) {
  return new Promise((resolve) => {
    setTimeout(() => { resolve(); }, milliseconds);
  });
}
// Test your function with these inputs:
wait(1000).then(() => console.log('1 second has passed'));
wait(2000).then(() => console.log('2 seconds have passed'));

Испытания проходят.

ChatGPT:

Отличная работа! Ваша функция wait правильно возвращает обещание, которое разрешается через указанное количество миллисекунд с использованием setTimeout.

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

Вопрос 6: Напишите функцию sumOfSquares, которая принимает массив чисел и возвращает сумму квадратов каждого числа. Используйте метод reduce в своей реализации.

Вот шаблон для начала:

function sumOfSquares(numbers) {
  // Your code here
}
// Test your function with these inputs:
console.log(sumOfSquares([1, 2, 3])); // Expected output: 14
console.log(sumOfSquares([4, 5, 6])); // Expected output: 77

Предоставьте свое решение и запустите тесты, чтобы подтвердить свою реализацию.

Ученик:

function sumOfSquares(numbers) {
  return numbers.reduce((acc, num) => acc + num * num, 0);
}
// Test your function with these inputs:
console.log(sumOfSquares([1, 2, 3])); // Actual output: 14
console.log(sumOfSquares([4, 5, 6])); // Actual output: 77

ChatGPT:

Отличная работа! Ваша функция sumOfSquares верна, и вы использовали метод reduce для вычисления суммы квадратов каждого числа в массиве.

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

Ученик:

Я слышал, что каждому разработчику React нужно хорошо понимать состав функций, чтобы максимально эффективно использовать архитектуру своего приложения React. Так ли это, и вы можете научить меня этому?

ChatGPT:

Да, это правда! Хорошее понимание композиции функций полезно не только для разработчиков React, но и для разработчиков JavaScript в целом. Композиция функций — это метод, при котором вы создаете новую функцию, объединяя две или более функций. Это помогает в создании более модульного, повторно используемого и поддерживаемого кода.

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

Предположим, у нас есть две функции, double и square:

function double(x) {
  return x * 2;
}
function square(x) {
  return x * x;
}

Теперь давайте создадим функцию doubleAndSquare, которая сначала удваивает число, а затем возводит результат в квадрат:

function doubleAndSquare(x) {
  return square(double(x));
}
console.log(doubleAndSquare(2)); // Expected output: 16

В этом примере мы составили функции double и square, чтобы создать функцию doubleAndSquare.

Однако это всего лишь простой пример. В более сложных сценариях вы можете использовать библиотеки, такие как Ramda или Lodash, для более элегантной композиции функций.

Давайте попрактикуемся в композиции функций с новой задачей.

Вопрос 7: Напишите функцию с именем addOneAndSquare, которая берет число, прибавляет к нему 1, а затем возводит результат в квадрат. Используйте композицию функций для создания новой функции.

Вот шаблон для начала:

function addOne(x) {
  return x + 1;
}
function addOneAndSquare(x) {
  // Your code here
}

Предоставьте свое решение и запустите тесты, чтобы подтвердить свою реализацию.

Ученик:

function addOneAndSquare(x) {
  return square(addOne(x));
}
// Test your function with these inputs:
console.log(addOneAndSquare(2)); // Actual output: 9
console.log(addOneAndSquare(4)); // Actual output: 25

ChatGPT:

Отличная работа! Ваша функция addOneAndSquare верна, и вы использовали композицию функций, объединив функции addOne и square.

Композиция функций — это мощный метод, который может помочь вам создать более модульный и удобный для сопровождения код, особенно в больших приложениях, таких как проекты React. Продолжайте практиковаться и изучать композицию функций, и она станет ценным инструментом в вашем наборе инструментов JavaScript.

Примечание редактора. К счастью, похоже, у меня все еще есть гарантия занятости. ChatGPT собирался оставить тему там, вместо того, чтобы глубже исследовать композицию. Учитывая, что эта тема является фундаментальной для разработки программного обеспечения (вся разработка программного обеспечения — это процесс разбиения сложных проблем на более простые и компоновки этих решений для формирования приложений), было бы лучше, если бы она была более глубокой. Как учитель, кажется, что ChatGPT лучше обучает новичков, чем экспертов по сложным темам.

Ученик:

Разве мы не должны научиться создавать `compose` и `pipe`?

ChatGPT:

Да, ты прав! Создание собственных функций compose и pipe — отличный способ лучше понять состав функций. Эти служебные функции позволяют объединить несколько функций более элегантным и удобочитаемым образом.

Начнем с compose. Функция compose принимает несколько функций в качестве аргументов и возвращает новую функцию, которая применяет эти функции справа налево.

Вот реализация функции compose:

function compose(...fns) {
  return (x) => {
    return fns.reduceRight((acc, fn) => {
      return fn(acc);
    }, x);
  };
}

Теперь давайте создадим функцию pipe, которая похожа на compose, но применяет функции слева направо:

function pipe(...fns) {
  return (x) => {
    return fns.reduce((acc, fn) => {
      return fn(acc);
    }, x);
  };
}

Теперь давайте перепишем функцию addOneAndSquare, используя функцию compose:

const addOneAndSquare = compose(square, addOne);
console.log(addOneAndSquare(2)); // Output: 9
console.log(addOneAndSquare(4)); // Output: 25

И используя функцию pipe:

const addOneAndSquarePipe = pipe(addOne, square);
console.log(addOneAndSquarePipe(2)); // Output: 9
console.log(addOneAndSquarePipe(4)); // Output: 25

Как видите, и compose, и pipe делают композицию функций более читаемой и позволяют легко объединять несколько функций в цепочку.

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

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

Ученик:

ХОРОШО. Я думаю, мы могли бы упростить их, верно?

const compose = (…fns) => x => fns.reduceRight((y, f) => f(y), x);

ChatGPT:

Да, вы абсолютно правы! Ваша реализация функции compose более лаконична и использует стрелочные функции. Вот упрощенная версия, которую вы предоставили:

const compose = (...fns) => (x) => fns.reduceRight((y, f) => f(y), x);

Точно так же можно упростить функцию pipe:

const pipe = (...fns) => (x) => fns.reduce((y, f) => f(y), x);

Обе эти упрощенные версии более лаконичны и по-прежнему обеспечивают одинаковую функциональность. Хорошая работа!

Примечание. Одна из замечательных особенностей ChatGPT как учебного пособия заключается в том, что вы можете в интерактивном режиме задавать ему вопросы, и на эти вопросы часто даются правильные ответы (по крайней мере, когда вы говорите об общем JavaScript). концепции).

Ученик:

Какое это имеет отношение к сокращению шаблонов в приложениях React?

ChatGPT:

Композиция функций, включая compose и pipe, может помочь сократить количество шаблонов в приложениях React, позволяя создавать многократно используемые компоненты высшего порядка (HOC) и служебные функции. Они могут инкапсулировать общее поведение и логику, делая ваш код более модульным и удобным в сопровождении.

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

Вот пример простого HOC, который проверяет, аутентифицирован ли пользователь:

function withAuthentication(WrappedComponent) {
  return function (props) {
    if (props.isAuthenticated) {
      return <WrappedComponent {...props} />;
    } else {
      return <div>Please log in to access this component.</div>;
    }
  };
}

Теперь предположим, что у вас есть два компонента, Dashboard и Profile, и вы хотите убедиться, что пользователь аутентифицирован перед доступом к ним. Вы можете использовать функцию compose для применения withAuthentication HOC:

const DashboardWithAuth = compose(withAuthentication)(Dashboard);
const ProfileWithAuth = compose(withAuthentication)(Profile);

В этом примере мы использовали compose для создания новых компонентов, включающих логику аутентификации. Повторно используя withAuthentication HOC, мы сократили количество шаблонов в нашем приложении React.

Композиция функций также может помочь вам создавать многократно используемые служебные функции, которые можно применять к реквизитам или состоянию ваших компонентов, что еще больше сокращает шаблоны и продвигает поддерживаемый код. Имейте в виду, что вы всегда можете использовать такие библиотеки, как Ramda или Lodash/fp, чтобы сделать композицию функций более удобной и выразительной.

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

Примечание. Но именно в этом ответе иллюзия рушится. ChatGPT допустил ошибку.

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

Студент => Мастер:

Похоже, вы допустили ошибку. В приведенном выше примере вы вызвали функцию compose, но на самом деле не выполняли с ней никакой композиции функций. compose(withAuthentication)(Dashboard); эквивалентен более короткому withAuthentication(Dashboard);.

Compose полезен, когда вы хотите составить несколько сквозных задач, таких как аутентификация И макет, И ведение журнала, например: compose(withAuthentication, withLayout, withLogging)(Dashboard);, и это также можно дополнительно абстрагировать и упростить, создав withProviders hoc с помощью compose, а затем обернув эту единственную оболочку вокруг компонентов вашей страницы.

ChatGPT:

Вы правы, и я прошу прощения за путаницу. В приведенном мной примере был только один компонент более высокого порядка, поэтому использование compose было излишним. Ваше объяснение использования compose с несколькими компонентами более высокого порядка верно.

Вот пример составления нескольких HOC с использованием compose:

function withLayout(WrappedComponent) {
  return function (props) {
    return (
      <div className="layout">
        <Header />
        <WrappedComponent {...props} />
        <Footer />
      </div>
    );
  };
}
function withLogging(WrappedComponent) {
  return function (props) {
    console.log(`Rendering ${WrappedComponent.name} component`);
    return <WrappedComponent {...props} />;
  };
}
const withProviders = compose(withAuthentication, withLayout, withLogging);
const DashboardWithProviders = withProviders(Dashboard);
const ProfileWithProviders = withProviders(Profile);

В этом примере мы создаем HOC withProviders, используя compose, и применяем его к компонентам Dashboard и Profile. Такой подход позволяет объединить несколько HOC более элегантным и удобочитаемым способом, упрощая управление сквозными задачами.

Спасибо, что указали на ошибку, и я надеюсь, что этот пример лучше демонстрирует преимущества использования композиции функций в приложениях React.

Заключение

Студент => Мастер:

Как вы думаете, что вы сделали как учитель? Считаете ли вы, что ваша работа с этим обучающим заданием была значительно лучше, чем у ChatGPT-3.5? Что вы могли бы улучшить в качестве преподавателя JavaScript?

ChatGPT:

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

Сравнивая мою производительность с ChatGPT-3.5, я хотел бы думать, что добился прогресса в понимании контекста, создании соответствующих примеров и предоставлении более четких объяснений. Тем не менее, я допустил ошибку в одном примере, который подчеркивает важность постоянного совершенствования своих знаний и понимания.

Чтобы стать инструктором по JavaScript, я мог бы:

  1. Будьте внимательнее к контексту и следите за тем, чтобы все примеры были точными и относились к теме.
  2. Предоставьте более четкие объяснения и аналогии, которые помогут учащимся связать новые понятия с их существующими знаниями.
  3. Поощряйте студентов задавать вопросы и предлагайте больше возможностей для практической работы.
  4. Лучше адаптируйтесь к индивидуальным потребностям каждого учащегося, адаптируя содержание и темп уроков.

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

Студент => Мастер:

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

Когда я впервые протестировал GPT-3 летом 2020 года, он очень часто допускал ошибки при написании функций JavaScript и редко правильно предсказывал ожидаемые ответы.

Он также не мог следить за потоками разговоров за пределами небольшого контекстного окна токена 4k. Вы придерживались подсказки формата обучения с первого сообщения на протяжении большей части разговора (намного больше 4 000 токенов).

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

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

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

ChatGPT:

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

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