jsliang Job Search Series - 45 - Резюме серии шаблонов проектирования

Поиск работы опрос

каталог

Чем отличается передок без закидывания от соленой рыбы?

содержание
каталог
2 Предисловие
Три объектно-ориентированных
3.1 Упаковка
3.2 Наследование
  3.2.1 Написание ES5
  3.2.2 Написание ES6
3.3 Полиморфизм
  3.3.1 Нотация ES5
  3.3.2 Написание ES6
Четыре принципа дизайна
Пять заводских режимов
5.1 Написание ES5
5.2 Написание ES6
5.3 Резюме
Шесть одноэлементных шаблонов
6.1 Нотация ES5
6.2 Написание ES6
Режим семи агентов и режим посредника
7.1 Прокси-режим
7.2 Паттерн посредника
7.3 Резюме
Восемь моделей публикации-подписки
8.1 Пример шаблона наблюдателя
8.2 Object.defineProperty и прокси
8.3 Резюме
9 ссылок

2 Предисловие

Назад к содержанию

Паттерны проектирования — это наука, в ней насчитывается более 22 типов паттернов проектирования.

Немного грусти: хотя вы учитесь, вы забываете вернуться через несколько месяцев, чтобы посмотреть, понимаете ли вы.

На фронтенд-интервью общие шаблоны проектирования, на которые вы можете ответить, следующие:

Шаблоны проектирования описывать пример
одноэлементный шаблон Можно построить только один уникальный экземпляр класса Магазин для Redux/Vuex
заводской узор Инкапсуляция логики создания объекта jQuery$(selector)
Шаблон наблюдателя Когда объект изменяется, его зависимые объекты автоматически уведомляются Редуксsubsrcibe, Двусторонняя привязка Vue
Шаблон декоратора Обертка класса для динамического расширения функциональности класса Компоненты высшего порядка React, декораторы ES7
режим адаптера Совместимость со старыми и новыми интерфейсами, упаковка классов Обертывание старых API
прокси-режим контролировать доступ к объектам Брокер событий, ES6Proxy

Конечно, если вы знаете другие вещи, будет лучше~

Три объектно-ориентированных

Назад к содержанию

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

Что такое объектно-ориентированный, мы можем сравнить его с процессно-ориентированным:

  • Процесс-ориентированный процесс: Сосредоточьтесь на каждом аспекте процесса
    • Съешьте яичный жареный рис (версия для одной собаки): купите яйцо → купите рис → приготовленный на пару рис → яичница-болтунья → жареный рис → смешайте → перемешайте → жареный рис с яйцом
  • объектно-ориентированный: заинтересован в том, чтобы заставить объекты что-то делать
    • Ешьте яичный жареный рис (версия для пары): найдите партнера, приготовьте яичный жареный рис, вы едите яичный жареный рис

Реальность может не разбить тебе сердце, ноjsliangМогу.

jsliangЯ тоже холост, так что я сначала себя ткну, прежде чем колоть тебя, не паникуй, мы будем тыкать наши сердца вместе

Объектно-ориентированное программирование (ООП) — это своего рода идея развития программирования.

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

  1. Реальные потребности (строительство здания)
  2. Какие объекты необходимы (дизайнеры, портье, строители стен, плотники, гиды по магазинам…)
  3. Отделение труда и сотрудничества
  4. Завершение проекта

Это как если вы хотите завершить проект, вы можете настроить Webpack + Babel и использовать React и Ant Design.

Итак, из чего состоит Webpack, и вы можете разделить его и заполнить его по одномуloaderа такжеplugin, который, наконец, состоит из небольших компонентов в проект.

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

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

3.1 Упаковка

Назад к содержанию

Допустим, нам нужно определить тип цели:

ориентированное на процесс письмо

// 今天 A 找你判断下类型
const A = 'jsliang';
const AType = Object.prototype.toString.call(A);
console.log(AType); // [object String]

// 明天 B 找你判断下类型
const B = 25;
const BType = Object.prototype.toString.call(B);
console.log(BType); // [object Number]

// 后天 C 找你判断下类型
const C = { obj: 'girl' };
const CType = Object.prototype.toString.call(C);
console.log(CType); // [object Object]

Это похоже на то, как родственник А просит вас выполнить поручение сегодня, родственник Б просит вас выполнить поручение завтра, а родственник С просит вас выполнить поручение послезавтра, но они хотят от вас поискать определенные звезды.

Раздражает, почему другие родственники вводят свидания вслепую, а ваши родственники знакомят со знаменитостями.

Итак, вы придумали способ:

объектно-ориентированное письмо

// 判断类型
const getType = (obj) => Object.prototype.toString.call(obj);

// 今天 A 找你判断下类型
const A = 'jsliang';
console.log(getType(A)); // [object String]

// 明天 B 找你判断下类型
const B = 25;
console.log(getType(B)); // [object Number]

// 后天 C 找你判断下类型
const C = { obj: 'girl' };
console.log(getType(C)); // [object Object]

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

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

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

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

3.2 Наследование

Назад к содержанию

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

Да, это наследование похоже на наследование, которое вы думаете, за исключением того, что есть методFather,ПотомChildrenнаследоватьFatherСодержание аккаунта.

Обратите внимание, что именно на счетах, т.е.FatherСтатические свойства и статические методы не будут наследоваться, точно так же, как вы наследуете активы, вам не нужно наследовать вредные привычки ваших родителей (курение и употребление алкоголя).

Трясти бесполезно, давайте посмотрим на код.

3.2.1 Написание ES5

Назад к содержанию

Если ES5 пишет наследование, вот способ наследования от руки, используяПаразитическая композиционная наследственность.

const Father = function (name, like) {
  this.name = name;
  this.like = like;
  this.money = 10000000;
};

Father.prototype.company = function() {
  console.log(`${this.name} 有 ${this.money} 元`);
}

const Children = function (name, like) {
  Father.call(this);
  this.name = name;
  this.like = like;
}

Children.prototype = Object.create(Father.prototype);
Children.prototype.constructor = Children;

const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children {name: "jsliang", like: "学习", money: 10000000}
jsliang.company(); // jsliang 有 10000000 元

Это тестовый сайт для интервью, который должен проверить, можете ли вы написать наследование от руки.

Конечно, есть и другие способы наследования, этоjsliangНашел более полный метод наследования.

3.2.2 Написание ES6

Назад к содержанию

class Father {
  constructor(name, like) {
    this.name = name;
    this.like = like;
    this.money = 10000000;
  }
  company() {
    console.log(`${this.name} 有 ${this.money} 元`);
  }
  // 静态方法并不会继承,并且可以通过类名调用
  static smoke() {
    console.log(`${this.name} 喜欢抽烟`);
  }
}

Father.smoke(); // Father 喜欢抽烟

class Children extends Father {
  constructor(name, like) {
    super();
    this.name = name;
    this.like = like;
  }
}

const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children {name: "jsliang", like: "学习", money: 10000000}
jsliang.company(); // jsliang 有 10000000 元
jsliang.smoke(); // TypeError: jsliang.smoke is not a function

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

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

3.3 Полиморфизм

Назад к содержанию

Полиморфизм можно просто понимать как наследование и собственное понимание этого.

Полиморфизм воплощается в перегрузке и переопределении методов:

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

Далее мы приходим к полиморфизмупереопределение методаНотация ES5 и ES6.

3.3.1 Нотация ES5

Назад к содержанию

const Father = function (name, like) {
  this.name = name;
  this.like = like;
  this.money = 10000000;
};

Father.prototype.company = function() {
  console.log(`${this.name} 有 ${this.money} 元`);
}

const Children = function (name, like) {
  Father.call(this);
  this.name = name;
  this.like = like;
  this.money = 10000;
}

Children.prototype = Object.create(Father.prototype);
Children.prototype.constructor = Children;
Children.prototype.company = function() {
  console.log(`${this.name} 有 ${this.money} 元`);
}

const father = new Father('jsliang 的老爸', '学习');
console.log(father); // Father { name: 'jsliang 的老爸', like: '学习', money: 10000000 }
father.company(); // jsliang 的老爸 有 10000000 元

const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children { name: 'jsliang', like: '学习', money: 10000 }
jsliang.company(); // jsliang 有 10000 元

3.3.2 Написание ES6

Назад к содержанию

class Father {
  constructor(name, like) {
    this.name = name;
    this.like = like;
    this.money = 10000000;
  }
  company() {
    console.log(`${this.name} 有 ${this.money} 元`);
  }
}

class Children extends Father {
  constructor(name, like) {
    super();
    this.name = name;
    this.like = like;
    this.money = 10000;
  }
  company() {
    console.log(`${this.name} 有 ${this.money} 元`);
  }
}

const father = new Father('jsliang 的老爸', '抽烟');
console.log(father); // Father { name: 'jsliang 的老爸', like: '抽烟', money: 10000000 }
father.company(); // jsliang 的老爸 有 10000000 元

const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children { name: 'jsliang', like: '学习', money: 10000 }
jsliang.company(); // jsliang 有 10000 元

Конечно же, у «инженера» нет будущего, это всего лишь мечта.

Вам нужен лайк и звезда Github, область комментариев полна «в следующий раз».


Жесткая реклама, если вам нужно связаться с друзьямиjsliang, вы можете найти контактную информацию на главной странице GitHub:


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

Четыре принципа дизайна

Назад к содержанию

Существует шесть основных принципов шаблонов проектирования: принцип единой ответственности, принцип подстановки Лисков, принцип инверсии зависимостей, принцип разделения интерфейса, принцип Деметра, принцип открытости и закрытости.

Конечно, мы не «профессионалы», мы ориентированы на интервью, поэтому помните два принципа:

  • Принцип единой ответственности: класс отвечает только за соответствующие обязанности в одной функциональной области. Или: Что касается класса, то есть только одна причина для его изменения.
  • открытый закрытый принцип: основная идея заключается в том, что программные объекты (классы, модули, функции и т. д.) расширяемы, но не модифицируемы. Другими словами, он открыт для расширения и закрыт для модификации.

Давайте начнем с введения шаблонов проектирования один за другим.

Пять заводских режимов

Назад к содержанию

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

То же самое относится и к фабричному шаблону в шаблоне проектирования.

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

5.1 Написание ES5

Назад к содержанию

const Person = function() {
  const [name, age, sex] = [...arguments];
  this.name = name;
  this.age = age;
  this.sex = sex;
  this.sayName = () => {
    console.log(`我叫 ${this.name},性别 ${this.sex},今年 ${this.age}`);
  }
};

const p1 = new Person('jsliang', 25, '男');
const p2 = new Person('靓女', 25, '女');

p1.sayName(); // 我叫 jsliang,性别 男,今年 25
p2.sayName(); // 我叫 靓女,性别 女,今年 25

5.2 Написание ES6

Назад к содержанию

class Person {
  constructor(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
  }
  sayName() {
    console.log(`我叫 ${this.name},性别 ${this.sex},今年 ${this.age}`);
  }
}

const p1 = new Person('jsliang', 25, '男');
const p2 = new Person('靓女', 25, '女');

p1.sayName(); // 我叫 jsliang,性别 男,今年 25
p2.sayName(); // 我叫 靓女,性别 女,今年 25

5.3 Резюме

Назад к содержанию

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

Преимущества и недостатки фабричного шаблона следующие:

  • преимущество: Может решить много подобных проблем.
  • недостаток: Проблема распознавания объекта не может быть известна (тип объекта не известен)

Шесть одноэлементных шаблонов

Назад к содержанию

Одноэлементный режим означает, что класс может создать только уникальный экземпляр.Смысл одноэлементного режима заключается в совместном использовании и уникальности.В Redux/VuexStore, jQuery$Или корзина покупок и окно входа в бизнес-сценарий — все это приложения шаблона singleton.

6.1 Нотация ES5

Назад к содержанию

const Single = function (name, password) {
  this.name = name;
  this.password = password;
};

Single.prototype.login = (name, password) => {
  if (!this.only) {
    this.only = new Single(name, password);
  }
  return this.only;
};

let user1 = new Single().login('jsliang', '123456');
let user2 = new Single().login('zhazhaliang', '654321');

console.log(user1 === user2); // true
console.log(user1); // Single { name: 'jsliang', password: '123456' }
console.log(user2); // Single { name: 'jsliang', password: '123456' }

6.2 Написание ES6

Назад к содержанию

class SingletonLogin {
  constructor(name, password) {
    this.name = name;
    this.password = password;
  }
  static getInstance(name, password) {
    // 判断对象是否已经被创建,若创建则返回旧对象
    if (!this.instance) {
      this.instance = new SingletonLogin(name, password);
    }
    return this.instance;
  }
}

let obj1 = SingletonLogin.getInstance('jsliang', '123456')
let obj2 = SingletonLogin.getInstance('zhazhaliang', '654321')

console.log(obj1 === obj2)    // true
console.log(obj1)           // SingletonLogin { name: 'jsliang', password: '123456' }
console.log(obj2)           // SingletonLogin { name: 'jsliang', password: '123456' }

Режим семи агентов и режим посредника

Назад к содержанию

Ниже мы будем использовать шаблон прокси и шаблон медиатора:

  • прокси-режим: Агентская модель делает упор на индивидуальность. Исходный класс (исходное тело метода) инкапсулирован, и клиенту нужно только взаимодействовать с прокси, а прокси является заменой для исходного класса. Короче говоря, один объект представляет другой объект.
  • модель посредничества: промежуточная модель подчеркивает независимость друг от друга. Определите промежуточный объект для инкапсуляции взаимодействия между объектами серии. Медиаторы отделяют объекты друг от друга без явной ссылки друг на друга и могут независимо изменять их взаимодействие.

Хорошо, давайте разберемся с режимом прокси и режимом посредника через код~

7.1 Прокси-режим

Назад к содержанию

Шаблон кода:

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

// 心动女孩
const Girl = function() {
  this.name = '心动女孩';
  this.get = (person, gift) => {
    console.log(`${person} 送给 ${this.name} ${gift}`);
  };
}

// jsliang
const JSLiang = function() {
  this.name = 'jsliang';
  this.send = () => {
    return '99 朵玫瑰';
  }
}

// 好哥们
const Friend = function(getUser) {
  this.getUser = new getUser();
  this.jsliang = new JSLiang();
  this.run = () => {
    this.getUser.get(this.jsliang.name, this.jsliang.send());
  }
};

// 好哥们帮忙给不同妹子送礼物
const friend = new Friend(Girl);
friend.run(); // jsliang 送给 心动女孩 99 朵玫瑰

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

Сценарии, применимые в режиме агента:

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

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>代理模式</title>
</head>

<body>
  <div class="animation">动画元素</div>

  <script>
    window.onload = function () {
      var myImage = (function () {
        var imgNode = document.createElement("img");
        document.body.appendChild(imgNode);
        return {
          setSrc: function (src) {
            imgNode.src = src;
          }
        }
      })();
      // 代理模式
      var ProxyImage = (function () {
        var img = new Image();
        img.onload = function () {
          myImage.setSrc(this.src);
        };
        return {
          setSrc: function (src) {
            myImage.setSrc("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603709264332&di=f6f8e48c1c88bf640aac9899df98a97c&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fq_mini%2Cc_zoom%2Cw_640%2Fimages%2F20171107%2F643ceb1031394c5887d3509b31878c52.gif");
            setTimeout(() => {
              img.src = src;
            }, 3000);
          }
        }
      })();
      // 调用方式
      ProxyImage.setSrc("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3592308877,3684082784&fm=26&gp=0.jpg");
    };
  </script>
</body>

</html>

7.2 Паттерн посредника

Назад к содержанию

Так что же такое модель посредника?

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

// 心动女孩
const Girl = function() {
  this.name = '心动女孩';
  this.get = (person, gift) => {
    console.log(`${person} 送给 ${this.name} ${gift}`);
  };
}

// jsliang
const JSLiang = function() {
  this.name = 'jsliang';
  this.send = () => {
    return '99 朵玫瑰';
  }
}

// 快递公司
const Express = function(postUser, getUser) {
  this.postUser = new postUser();
  this.getUser = new getUser();
  this.run = () => {
    this.getUser.get(this.postUser.name, this.postUser.send());
  }
};

// 快递员
const courier = new Express(JSLiang, Girl);
courier.run(); // jsliang 送给 心动女孩 99 朵玫瑰

Это просто, скажемjsliangЕсли девушка, которая вам нравится, находится не в Гуанчжоу, то вам нужен кто-то еще, чтобы «помочь» отправить подарки девушкам из других мест.

И эта модель является посреднической моделью, которая передает информацию в качестве посредника.

Преимущества режима прокси можно увидеть из этого:

  1. Прокси-объекты можно создавать вместо онтологии и делать их доступными удаленно.
  2. Можно отложить создание экземпляра онтологии до тех пор, пока он действительно не понадобится.

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

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

Применимые сценарии модели посредника:

var goods = {
  // 手机库存
  "red|32G": 3,
  "red|64G": 1,
  "blue|32G": 7,
  "blue|32G": 6,
};

// 中介者
var mediator = (function () {
  var colorSelect = document.getElementById("colorSelect");
  var memorySelect = document.getElementById("memorySelect");
  var numSelect = document.getElementById("numSelect");
  return {
    changed: function (obj) {
      switch (obj) {
        case colorSelect:
          // TODO
          break;
        case memorySelect:
          // TODO
          break;
        case numSelect:
          // TODO
          break;
      }
    },
  };
})();
colorSelect.onchange = function () {
  mediator.changed(this);
};
memorySelect.onchange = function () {
  mediator.changed(this);
};
numSelect.onchange = function () {
  mediator.changed(this);
};

7.3 Резюме

Назад к содержанию

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

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

Если у вас будет возможность в будущем, обратите на это внимание, а можно ли спросить на собеседовании? Я не знаю здесь, потому что это не горячая точка, вы можете это понять~

Восемь моделей публикации-подписки

Назад к содержанию

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

Запутались после прочтения определения?

Реальная модель публикации-подписки, напримерjsliangЯ увидел пару обуви в Интернете, но их не было в наличии, поэтому я нажал (подписался) на уведомление продавца об отправке. После того, как товар будет у продавца, уведомление увидят все покупатели, которые нажмут (подпишутся) на уведомление об отправке.

Преимущества и недостатки модели публикации-подписки:

  • преимущество
  1. Поддерживается простая широковещательная связь. Когда состояние объекта изменяется, подписанные объекты будут автоматически уведомлены, как в приведенном выше примере.
  2. Связь между издателями и подписчиками снижается. Я продавец и мне все равно сколько человек подписалось, мне просто нужно изменить количество товара по мере поступления.
  • недостаток
  1. Отнимающая много времени память. Создание подписчиков занимает определенное количество времени и памяти
  2. Чрезмерное использование не годится для обслуживания.

Хорошо, так много сказано, давайте приведем небольшой пример кода, а затем поговорим о Vue во Vue.Object.definePropertyа такжеProxyиспользовать.

8.1 Пример шаблона наблюдателя

Назад к содержанию

// 定义发布者
const seller = {};

// 缓存列表:存放订阅者的回调函数
seller.buyerList = [];

// 订阅方法
seller.listen = (user, fn) => {
  // 如果有人订阅了,那就将它存放到缓存列表中
  seller.buyerList.push(fn);
  console.log(`亲爱的 ${user},你已经订阅了新鞋发布`);
}

// 发布信息
seller.trigger = () => {
  const buyerList = seller.buyerList;
  for (let i in buyerList) {
    if (buyerList.hasOwnProperty(i)) {
      buyerList[i].call(this);
    }
  }
}

const buyer1 = seller.listen('jsliang', () => console.log('颜色是黑色,尺码是 43 码')); // 亲爱的 jsliang,你已经订阅了新鞋发布
const buyer2 = seller.listen('zhazhaliang', () => console.log('颜色是红色,尺码是 44 码')); // 亲爱的 zhazhaliang,你已经订阅了新鞋发布

// 假设 2 秒后到货
setTimeout(() => {
  seller.trigger();
}, 2000);

// 颜色是黑色,尺码是 43 码
// 颜色是红色,尺码是 44 码

Таким образом реализуется простая модель публикации-подписки: если у продавца разные товары, как два пользователя могут обратить внимание на два разных товара? Друзья могут думать и думать.

8.2 Object.defineProperty и прокси

Назад к содержанию

В Vue 2.0 мы прошлиObject.definePropertyДля наблюдения за данными:

const person = {
  name: 'jsliang',
  age: 25,
};

Object.keys(person).forEach((key) => {
  Object.defineProperty(person, key, {
    enumerable: true,
    configurable: true,
    get: () => {
      console.log('get');
    },
    set: (newName) => {
      console.log(newName);
    },
  });
});

person.name = 'zhazhaliang'; // zhazhaliang
console.log(person); // { name: [Getter/Setter], age: [Getter/Setter] }

в:

  • enumerable: может ли быть передано свойство объектаfor-inцикл,falseне зацикливается, значение по умолчанию равноtrue.
  • configurable: Можете ли вы использовать ·, если вам нужно изменить характеристики атрибута или вы можете изменить атрибут доступа,falseне переопределяется, значение по умолчанию равноtrue.

Так что давайте посмотрим.Proxy:

const queuedObserver = new Set();

const observe = fn => queuedObserver.add(fn);
const observeable = obj => new Proxy(obj, {set});

const set = function(target, key, value, receiver) {
  const result = Reflect.set(target, key, value, receiver);
  queuedObserver.forEach(observer => observer());
  return result;
};

const person = observeable({
  name: 'jsliang',
  age: 25,
});

const print = () => {
  console.log(`姓名:${person.name},年龄:${person.age}`);
}
observe(print);

person.name = 'zhazhaliang'; // 姓名:zhazhaliang,年龄:25

Так почему же Vue 3.0 переключился наProxyШерстяная ткань?

Обратите внимание на лекцию, это вопрос интервью~

Object.definePropertyнедостаток:

  1. Не могу отслеживать изменения массива
  2. Необходимо перебрать каждое свойство объекта

а такжеProxyЦелью является объект, который сохраняет обход свойств.

Что касается более глубокого понимания, типа как тапнуть на странице, чтобы привязать страницу и данные, то тут дрожать не надо, а заинтересованные друзья могут почитатьjsliangДругая библиотека:

8.3 Резюме

Назад к содержанию

Что нужно исправить, так это то,ES6 ProxyОн относится к режиму прокси в режиме.

В повседневной работе распространенными моделями поведения наблюдателей являются:

  • Promise
  • узлаEventEmitterпрослушиватель событий
  • ВьюWatchхук цикла объявления

9 ссылок

Назад к содержанию

В этой серии ссылок 14 статей.


репозиторий документации jsliang предоставляетсяЛян ЦзюньронгиспользоватьCreative Commons Attribution-NonCommercial-ShareAlike 4.0 Международная лицензияЛицензия.
на основеGitHub.com/l ian Jun Ron…Создание работ выше.
Права на использование, отличные от разрешенных в настоящем Лицензионном соглашении, могут быть получены отCreative Commons.org/licenses/не…получено в.