惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
爱范儿
爱范儿
Y
Y Combinator Blog
T
Tor Project blog
V
Visual Studio Blog
U
Unit 42
B
Blog RSS Feed
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
G
Google Developers Blog
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog
T
The Blog of Author Tim Ferriss
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
F
Fortinet All Blogs
人人都是产品经理
人人都是产品经理
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
博客园_首页
罗磊的独立博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
P
Proofpoint News Feed
Jina AI
Jina AI
博客园 - 【当耐特】
S
Security @ Cisco Blogs
I
Intezer
MyScale Blog
MyScale Blog
Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy & Cybersecurity Law Blog
腾讯CDC
T
Tenable Blog
A
Arctic Wolf
T
Threat Research - Cisco Blogs
S
Securelist
Know Your Adversary
Know Your Adversary
Spread Privacy
Spread Privacy
C
Check Point Blog
NISL@THU
NISL@THU
Microsoft Security Blog
Microsoft Security Blog
V
Vulnerabilities – Threatpost

szhshp 的第三边境研究所

假设, AI 把我代替的那一刻真的到来 | szhshp 的第三边境研究所 小傻瓜都能懂的 AstrBot QQ 机器人集成 MCP 功能实战指南 | szhshp 的第三边境研究所 《智人之上: 从石器时代到 AI 时代的信息网络简史》阅读笔记 | szhshp 的第三边境研究所 iPadOS 26 无法设置空间场景图片壁纸的解决方法 | szhshp 的第三边境研究所 《一路云海》(终) | szhshp 的第三边境研究所 《一路云海》(四): 如何不按套路旅行 | szhshp 的第三边境研究所 《一路云海》(三): In Ya Mellow Tone | szhshp 的第三边境研究所 《一路云海》(二): 关西世博参观纪实 | szhshp 的第三边境研究所 《一路云海》(一): 新的征程 | szhshp 的第三边境研究所 2025 大阪世博会 [ 3 天前-先到先得 ] 阶段 场馆预约必中独家攻略 | szhshp 的第三边境研究所 Hackathon 随想 | szhshp 的第三边境研究所 一杯双皮奶 | szhshp 的第三边境研究所 Armbian + CasaOS + NAS 配置指南 | szhshp 的第三边境研究所 Docker 构建镜像报错: error getting credentials - err: exit status 1, out: `` | szhshp 的第三边境研究所 Disqus RIP! 论过高的维护成本如何治疗固执的坏习惯 | szhshp 的第三边境研究所 炸弹猫桌游变体规则 | szhshp 的第三边境研究所 《小岛经济学》阅读笔记 | szhshp 的第三边境研究所 《金钱心理学》阅读笔记 | szhshp 的第三边境研究所 为知笔记 RIP: 迁移剩余的笔记 | szhshp 的第三边境研究所 2025 博客第十年展望 - 再见我的过去 | szhshp 的第三边境研究所 我在独立游戏里面致敬的作品 | szhshp 的第三边境研究所 《How to make thing faster》阅读笔记 | szhshp 的第三边境研究所 《The Art of Clean Code》阅读笔记 | szhshp 的第三边境研究所 《Clean Architecture: A Craftsman Guide to Software Structure and Design》阅读笔记 | szhshp 的第三边境研究所 《How AI Works》阅读笔记 | szhshp 的第三边境研究所 游戏策划废案 - Project Uranus | szhshp 的第三边境研究所 游戏策划废案 - Project X | szhshp 的第三边境研究所 人生第一款独立游戏开发复盘 | szhshp 的第三边境研究所 Trap of Life | szhshp 的第三边境研究所 如果我用手搓了个暗物质雏形 | szhshp 的第三边境研究所 《Rust Programming Language》- EX - Cheatsheet | szhshp 的第三边境研究所 新的播放器上线了 | szhshp 的第三边境研究所 Cypress - End-to-End Testing: OKTA Authentication with MFA | szhshp 的第三边境研究所 VSC x VIM - 反正多学几个快捷键没有坏处 | szhshp 的第三边境研究所 两小时 Docker 速成 - Getting Started | szhshp 的第三边境研究所 《The Joy of Javascript》- 5 - Data | szhshp 的第三边境研究所 《The Joy of Javascript》- 4 - Meta Programming | szhshp 的第三边境研究所 《The Joy of Javascript》- 3 - ADT(Algebraic Data Type) | szhshp 的第三边境研究所 Web-Automation Testing | szhshp 的第三边境研究所 《The Joy of Javascript》- 2 - Functor/Monad | szhshp 的第三边境研究所 EvalError: Possible side-effect in debug-evaluate | szhshp 的第三边境研究所 前端 QA 工具链指南 - husky,commitlint,commitizen,eslint,typescript,express | szhshp 的第三边境研究所 效率工具 & 软件推荐 | szhshp 的第三边境研究所 站点开源 Project Titan | szhshp 的第三边境研究所 cmd/powershell-命令速查-Cheatsheet | szhshp 的第三边境研究所 Git-命令速查与相关问题解决-Cheatsheet & Troubleshooting | szhshp 的第三边境研究所 Tailwind.css not included in NextJS Production | szhshp 的第三边境研究所 Github GraphQL API - Data Integration | szhshp 的第三边境研究所 尝试 Windows Terminal + z.lua | szhshp 的第三边境研究所 StrokePlus.net - Powerful Hotkey Boost | szhshp 的第三边境研究所 优雅地 Hack 一台黑苹果 | szhshp 的第三边境研究所 一杯关东煮 | szhshp 的第三边境研究所 Gitee x PicGo 管理图床 | szhshp 的第三边境研究所 Create Your Own Redux (Typescript) | szhshp 的第三边境研究所 Getting Started: Ionic + Capacitor + React + Typescript + Android | szhshp 的第三边境研究所 GraphQL: File Upload & Troubleshooting | szhshp 的第三边境研究所 吉祥航空随心飞刷票工具循环查票工具 | szhshp 的第三边境研究所 NVM Windows Portable Installation | szhshp 的第三边境研究所 NextJS x Typescript - Integration & Troubleshooting | szhshp 的第三边境研究所 全站点升级 - Project Titan | szhshp 的第三边境研究所 AWS-EC2-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 Workbox-Getting Started | szhshp 的第三边境研究所 《时间简史》阅读笔记 | szhshp 的第三边境研究所 《时间的秩序》阅读笔记 | szhshp 的第三边境研究所 ESLint-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 站点索引 | szhshp 的第三边境研究所 个人知识库搭建 - Hexo 实现 Github/Coding 持续集成 | szhshp 的第三边境研究所 BMOB-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 React + Typescript: 开启 HMR/Hot Loader | szhshp 的第三边境研究所 Yarn & NPM | szhshp 的第三边境研究所 ESLint: Typescript + React + TSX 集成 | szhshp 的第三边境研究所 《10101》EP15:过年 2020 | szhshp 的第三边境研究所 Cmder-Usage | szhshp 的第三边境研究所 Redux-DOM not refreshed | szhshp 的第三边境研究所 React Semantic UI-CheatSheet | szhshp 的第三边境研究所 Typescript: Getting Started | szhshp 的第三边境研究所 Flutter-Getting Started | szhshp 的第三边境研究所 Typescript: Access window object with type check | szhshp 的第三边境研究所 VSC Extension Development-Create A Code Formatter Extension | szhshp 的第三边境研究所 OneNote Extension-Main API | szhshp 的第三边境研究所 TortoiseGit Win10 Icon not showing correctly | szhshp 的第三边境研究所 Mongoose: aggregate() 方法实现聚合函数 | szhshp 的第三边境研究所 React In Depth - React 源码解析 - render() & Fiber | szhshp 的第三边境研究所 MongoDB x Mongoose: 实现类似 Join 的功能 | szhshp 的第三边境研究所 Disqus 评论框改造工程-实现 Disqus 代理的 Serverless 服务 | szhshp 的第三边境研究所 GUI, CLI, Terminal, Shell, TTY, Console, Bash | szhshp 的第三边境研究所 Jest Async Best Practise: No Nested Async | szhshp 的第三边境研究所 关系型数据库与非关系型数据库优缺点分析 | szhshp 的第三边境研究所 New Edge & Chromium Error - Package is invalid: 'CRX_VERSION_NUMBER_INVALID' | szhshp 的第三边境研究所 选择 GraphQL 的 N 个理由 | szhshp 的第三边境研究所 StrokePlus - 鼠标手势神器的代码编写技巧 | szhshp 的第三边境研究所 嗨,好久不见 | szhshp 的第三边境研究所 Vue + ElementUI 集成 Vue Router | szhshp 的第三边境研究所 IE8 - Unknown Runtime Error Using innerHTML & Ajax | szhshp 的第三边境研究所 React: Handling Events | szhshp 的第三边境研究所 React-Navigation Integration with Redux | szhshp 的第三边境研究所 React: States is tricky | szhshp 的第三边境研究所 《10101》EP14:小剧场 | szhshp 的第三边境研究所 ColdFusion - Basic - arguments in cffunction | szhshp 的第三边境研究所 ColdFusion - Basic - cfset | szhshp 的第三边境研究所
《The Joy of Javascript》- 1 - Object/Function | szhshp 的第三边境研究所
2022-06-18 · via szhshp 的第三边境研究所

Meta

目录

关于此书 - 从此我给别人面试可以出究极难度的题目了 😏

请支持正版书籍 Amazon 购买链接

相关文章

一本书里面内容较多, 因此分成了多篇 Post, 可以从此处看到相关文章:

Object

通过使用 mixin 实现对象继承

Mixin 模式的优势:

  1. 支持多继承
  2. 可以对现有的对象添加独立的方法, 这些方法可以在多个对象里面复用

Mixin 实现多继承

const TerrestrialAnimal = {
  walk() {},
  breathe() {
    console.log("Using my lungs to breathe");
  },
};

const AquaticAnimal = {
  swim() { },
  breathe() {
    console.log("Using my gills to breathe");
  },
};

const Amphibian = (name) =>
  Object.assign(
    {
      name,
    },
    AquaticAnimal, /* Using my gills to breathe */
    TerrestrialAnimal  /* Using my lungs to breathe */
  );

const frog = Amphibian("Frog");

frog.walk();
frog.swim();
frog.breathe(); /* Using my lungs to breathe */

OLOO(Objects-linked-to-other-objects) 模式对象扩展

/* HasHash 返回一个含有 calculateHash 方法的对象 */
const HasHash = (keys) => ({ /* keys 接受一个字符串数组 */
  calculateHash() {
    const data = keys.map((f) => this[f]).join(""); /* 注意此处会获取 this 里面的属性 */
    let hash = 0,
      i = 0;
    while (i < data.length) {
      hash = ((hash << 5) - hash + data.charCodeAt(i++)) << 0;
    }
    return hash ** 2;
  },
});

const Transaction = {
  init(sender, recipient, funds = 0.0) {
    this.sender = sender;
    this.recipient = recipient;
    this.funds = Number(funds);
    return this;
  },
  displayTransaction() {
    return `Transaction from ${this.sender} to ${this.recipient} for ${this.funds}`;
  },
};



/* 核心代码, 通过 Object.create 创建一个对象并绑定 this, 同时使用 Object.assign 对对象进行扩展 */
const HashTransaction = Object.assign(
  Object.create(Transaction),  
  HasHash(["sender", "recipient", "funds"])
);




const t = HashTransaction.init("Alice", "Bob", 100.0);
console.log(t.calculateHash());  // 620300900133850900
console.log(t.displayTransaction()); // Transaction from Alice to Bob for 100

Class 模式对象扩展

const DEFAULT_ALGO_SHA256 = 'SHA256';
const DEFAULT_ENCODING_HEX = 'hex';

const HasHash = (
  keys,
  options = {
    algorithm: DEFAULT_ALGO_SHA256,
    encoding: DEFAULT_ENCODING_HEX
  }
) => ({
  calculateHash() {
    const data = keys.map(f => this[f]).join('');
    let hash = 0, i = 0;
    while (i < data.length) {
      hash = ((hash << 5) - hash + data.charCodeAt(i++)) << 0;
    }
    return hash ** 2;
  }
})

class Transaction {
  transactionId = '';
  timestamp = Date.now();
  #feePercent = 0.6;
  constructor(sender, recipient, funds = 0.0, description = 'Generic') {
    this.sender = sender;
    this.recipient = recipient;
    this.funds = Number(funds);
    this.description = description;
    this.transactionId = this.calculateHash();  /* 特别注意这个地方调用了 calculateHash, 并且 calculateHash 不是 Transaction 自带的方法 */
  }
  displayTransaction() {
    return `Transaction ${this.description} from ${this.sender} to 
 ${this.recipient} for ${this.funds}`;
  }
  get netTotal() {
    return Transaction.#precisionRound(
      this.funds * this.#feePercent, 2);
  }
  static #precisionRound(number, precision) {
    const factor = Math.pow(10, precision);
    return Math.round(number * factor) / factor;
  }
}


/* 在扩展前直接实例化会报错: TypeError: this.calculateHash is not a function, 因为 Transaction 自身还没有这个方法 */
// const t1 = new Transaction('Mike', 'Jack', 10.0, 'Generic');  




/* 核心代码 */
/* 通过 Object.assign 将 HasHash Mixin 扩展到 Transaction 里面 */
Object.assign(
  Transaction.prototype,
  HasHash(['timestamp', 'sender', 'recipient', 'funds']),
  // HasSignature(['sender', 'recipient', 'funds']),
  // HasValidation()
)




/* 此时进行实例化就可以调用 HasHash 返回的 calculateHash 方法 */
const t2 = new Transaction('Mike', 'Jack', 10.0, 'Generic');
console.log(t2.transactionId); 

Function

函数式编程和 OOP 的比较 | FP vs OOP | Differences between FP and OOP

Functional ProgrammingOOP
Does not exist StateExists State
Uses Immutable dataUses Mutable data
It follows Declarative Programming ModelIt follows Imperative Programming Model
Stateless Programming ModelStateful Programming Model
Main Fcous on: “What you are doing”Main focus on “How you are doing”
Good for Parallel (Concurrency) ProgrammingPoor for Parallel (Concurrency) Programming
Good for BigData processing and analysisNOT Good for BigData processing and analysis
Supports pure EncaspulationIt breaks Encaspulation concept
Functions with No-Side EffectsMethods with Side Effects
Functions are first-class citizensObjects are first-class citizens
Primary Manipulation Unit is “Function”Primary Manipulation Unit is Objects(Instances of Classes)
Flow Controls: Function calls, Function Calls with RecursionFlow Controls: Loops, Conditional Statements
It uses “Recursion”concept to iterate Collection Data.It uses “Loop”concept to iterate Collection Data. For example:-For-each loop in Java
Order of execution is less importance.Order of execution is must and very important.
Supports both “Abstraction over Data”and “Abstraction over Behavior”.Supports only “Abstraction over Data”.
We use FP when we have few Things with more operations.We use OOP when we have few Operations with more Things. For example: Things are classes and Operations are Methods in Java.
功能编程面向对象
不存在状态存在状态
使用不可变数据使用可变数据
它遵循声明式编程模型它遵循命令式编程模型
无状态编程模型有状态编程模型
主要观点: “你在做什么”主要关注”你的表现”
适合并行 (并发) 编程并行 (并发) 编程能力差
适用于 BigData 处理和分析不适合 BigData 处理和分析
支持纯封装它打破了包容性概念
无副作用的功能副作用方法
职能是一等公民对象是一等公民
主要操作单元是”功能”主要操作单位是对象 (类的实例)
流控制: 函数调用, 带递归的函数调用流控制: 循环, 条件语句
它使用”递归”概念来迭代收集数据.它使用”循环”概念来循环收集数据. 例如: Java 中的 for-for 循环
执行顺序不太重要.执行顺序是必须且非常重要的.
支持”基于数据的抽象”和”基于行为的抽象”.仅支持”基于数据的抽象”.
当我们的事物很少且需要更多操作时, 我们将使用 FP.当我们很少进行具有更多事物的操作时, 我们将使用 OOP. 例如: 在 Java 中, 事物是类, 而操作是 Java 中的方法.

Functional Programming Example | 函数式编程示例

一个命令式编程的例子:

const arr = ['john-reese', 'harold-finch', 'sameen-shaw'];
const newArr = [];
for (let i = 0, len = arr.length; i < len ; i++) {
  let name = arr[i];
  let names = name.split('-');
  let newName = [];
  for (let j = 0, naemLen = names.length; j < naemLen; j++) {
  let nameItem = names[j][0].toUpperCase() + names[j].slice(1);
  newName.push(nameItem);
  }
  newArr.push({ name : newName.join(' ') });
}
return newArr;

一个函数式编程的例子:

const capitalize = x => x[0].toUpperCase() + x.slice(1).toLowerCase();

const genObj = curry((key, x) => {
  let obj = {};
  obj[key] = x;
  return obj;
}) 

// 使用 compose 将多个方法进行结合
const capitalizeName = compose(join(' '), map(capitalize), split('-'));
const convert2Obj = compose(genObj('name'), capitalizeName)
const convertName = map(convert2Obj);

convertName(['john-reese', 'harold-finch', 'sameen-shaw'])

FP 核心专注于以下几个方法:

  1. compose
  2. curry

使用这些方法可以对函数进行合成和连锁调用

主流三方库已经有类似实现, 比如 lodash 的 _.curry , _.flow. 甚至这些库还支持使用 _.curryRight , _.flowRight 来进行从右向左的执行顺序

compose 方法实现

function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }
 
  if (funcs.length === 1) {
    return funcs[0]
  }
 
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
} 

使用方法:

const operate = compose(div2, mul3, add1, add1)
operate(0) // 相当于 div2(mul3(add1(add1(0)))) 
operate(2) // 相当于 div2(mul3(add1(add1(2))))

curry 方法的实现

export const curry = fn => (...args1) =>
  args1.length === fn.length
    ? fn(...args1)
    : (...args2) => {
      const args = [...args1, ...args2]
      return args.length >= fn.length ? fn(...args) : curry(fn)(...args)
    }

Summary

  • JavaScript offers many choices for building objects, including prototypal inheritance, constructor functions, and classes.
  • The phrase prototype inheritance is an oxymoron because the idea of a shared linked prototype object is contradictory to the class inheritance model, in which instances gain copies of the inherited data.
  • Constructor functions have been the standard mechanisms used to mimic the idea of classes in JavaScript.
  • Classes smooth over the details of the prototype configuration for newcomers or developers coming from other class-based languages and have become the preferred choice of JavaScript developers.
  • The class syntax can blur your understanding of JavaScript’s prototype inheritance mechanism. Classes are useful, but remember that JavaScript is different from other class-based languages you may have seen or used.