Gutenberg 带来的 WordPress 生态系统的一个关键变化是对 JavaScript 的大量依赖。值得庆幸的是,WordPress 团队通过利用现代 JavaScript 堆栈(社区中通常称为 ES6)真正将他们的 JavaScript 框架推向了现在和未来。这也是我们在本系列中提及它的方式,以避免混淆。
让我们深入了解一下这个 ES6 世界,因为它最终将帮助我们理解如何构建和构建自定义的 Gutenberg 块。
文章系列
- 系列介绍
- 什么是 Gutenberg?
- 使用 create-guten-block 的入门指南
- 现代 JavaScript 语法 (本文)
- React 101
- 设置自定义 webpack
- 自定义“卡片”块
什么是 ES6?
ES6 是“EcmaScript 6”的缩写,它是 EcmaScript 的第 6 版。它的正式名称是 ES2015,您可能也听说过。EcmaScript 后来经历了许多迭代,但现代 JavaScript 通常仍然被称为 ES6。正如您可能猜到的,迭代已经继续进行,包括 ES2016、ES2017 等等。我实际上在 ShopTalk 节目中提出了一个问题,关于我们如何命名现代 JavaScript,我的结论是……ES6。
我将介绍一些在 Gutenberg 上下文中很有用的 ES6 的关键特性。
函数
函数在 ES6 中得到了很大的更新。我想重点关注的两个变化是**箭头函数**和**类方法**。
在类中,您实际上不再需要在 ES6 中编写 function
这个词了。这可能会让人感到困惑,所以请查看以下示例
class Foo {
// This is your 'bar' function
bar() {
return 'hello';
}
}
您可以像这样调用 bar()
const fooInstance = new Foo();
const hi = fooInstance.bar();
这在现代 JavaScript 的世界中很常见,所以澄清一下是很有必要的。
bar()
方法的定义方式如下:Foo.prototype.bar = function() { ... }
。React 充分利用了 ES6 类,但值得注意的是,ES6 类本质上是语法糖,并且受到一些人的强烈质疑。如果您想了解更多详细信息,请查看MDN 文档和2ality 上的这篇文章。好的,让我们继续讨论箭头函数。🚀
箭头函数为我们提供了一种紧凑的语法,通常用作表达式的单行代码。它还用于维护 this
的值,因为箭头函数不会像 setInterval
或事件处理程序那样重新绑定 this
。
以下是一个作为表达式的箭头函数示例
// Define an array of fruit objects
const fruit = [
{
name: 'Apple',
color: 'red'
},
{
name: 'Banana',
color: 'yellow'
},
{
name: 'Pear',
color: 'green'
}
];
// Select only red fruit from that collection
const redFruit = fruit.filter(fruitItem => fruitItem.color === 'red');
// Output should be something like Object { name: "Apple", color: "red" }
console.log(redFruit[0]);
如您所见,由于只有一个参数并且函数用作表达式,因此我们可以删除方括号和圆括号。这使我们能够真正压缩代码并提高可读性。
让我们看看如何在之前的 Foo
类中将箭头函数用作事件处理程序
class Foo {
// This is your 'bar' function
bar() {
let buttonInstance = document.querySelector('button');
buttonInstance.addEventListener('click', evt => {
console.log(this);
});
}
}
// Run the handler
const fooInstance = new Foo();
fooInstance.bar();
单击按钮时,输出应为 Foo { }
,因为 this
是 Foo
的实例。如果我们用以下内容替换该示例
class Foo {
// This is your 'bar' function
bar() {
let buttonInstance = document.querySelector('button');
buttonInstance.addEventListener('click', function(evt) {
console.log(this);
});
}
}
// Run the handler
const fooInstance = new Foo();
fooInstance.bar();
单击按钮时,输出将为 <button>
,因为该 function
已将 this
绑定到被单击的 <button>
。
您可以阅读更多关于箭头函数的信息,作者是 Wes Bos,他写了一篇关于它们的精彩文章。
const、let 和 var
您可能已经注意到,我在上面的示例中使用了 const
和 let
。这些也是 ES6 的一部分,我将快速解释每个的作用。
如果某个值绝对恒定并且不会通过重新赋值或重新声明而改变,请使用 const
。这通常用于导入某些内容或声明不变的属性,例如 DOM 元素的集合。
如果您有一个变量,希望它只能在其定义的块中访问,则使用 let
。这可能难以理解,所以请查看以下小示例
function foo() {
if (1 < 2) {
let bar = 'always true';
// Outputs: 'always true'
console.log(bar);
}
// Outputs 'ReferenceError: bar is not defined'
console.log(bar);
}
// Run the function so we can see our logs
foo();
这是一种很好地控制变量并使其在某种意义上可丢弃的方法。
最后,var
是我们熟悉和喜爱的旧朋友。不幸的是,在 const
和 let
之间,随着时间的推移,我们的朋友变得越来越冗余。使用 var
绝对是可以接受的,所以不要灰心——您在本文档的其余部分中不会经常看到它!
解构赋值
解构允许您在将对象键赋值给本地变量时提取它们。所以,假设您有以下对象
const foo = {
people: [
{
name: 'Bar',
age: 30
},
{
name: 'Baz',
age: 28
}
],
anotherKey: 'some stuff',
heyAFunction() {
return 'Watermelons are really refreshing in the summer'
}
};
传统上,您将使用 foo.people
提取 people
。使用解构,您可以这样做
let { people } = foo;
这会从 foo 对象中提取 people
数组,因此我们可以删除 foo.
前缀并按原样使用它:people
。这也意味着 anotherKey
和 heyAFunction
被忽略了,因为我们现在不需要它们。当您处理大型复杂对象时,能够选择性地提取内容非常有用。
您还可以利用解构将对象分解为局部变量以提高代码可读性。让我们更新上面的代码段
let { people } = foo;
let { heyAFunction } = foo;
现在我们从同一个对象中获得了这两个单独的元素,同时仍然忽略 anotherKey
。如果您运行 console.log(people)
,它将显示自身是一个数组;如果您运行 console.log(heyAFunction)
,您猜对了,它将显示自身是一个函数。
JSX
最常出现在 React JS 上下文中:JSX 是 JavaScript 的一种类似 XML 的扩展,旨在由预处理器编译成普通的 JavaScript 代码。从本质上讲,它使我们能够在 JavaScript 中编写 HTML(ish)代码,只要我们对其进行预处理。它通常与 React JS 等框架相关联,但也用于 Gutenberg 块开发。
让我们从一个示例开始
const hello = <h1 className="heading">Hello, Pal</h1>;
很酷,对吧?不需要模板系统、转义或连接。只要您返回单个元素(可以有多个子元素),就可以了。因此,让我们展示一些更复杂的内容,以及一个 React 渲染函数
class MyComponent extends React.Component {
/* Other parts redacted for brevity */
render() {
return (
<article>
<h2 className="heading">{ this.props.heading }</h2>
<p className="lead">{ this.props.summary }</p>
</article>
);
}
};
您可以在上面看到,我们可以在任何我们想要的地方插入表达式。元素属性也是如此,因此我们可以有类似这样的内容
<h2 className={ this.props.headingClass }>
{ this.props.heading }
</h2>
您可能在想,“这些随机的花括号在做什么?”
答案是这是一个表达式,您将在 JSX 中看到很多这样的内容。从本质上讲,它是在 JavaScript 中进行的小型内联执行,其行为与 PHP echo
非常相似。
您可能还会注意到它使用的是 className
而不是 class
。虽然它看起来像 HTML/XML,但它仍然是 JavaScript,因此自然会避免保留字。属性也使用驼峰命名法,所以要注意这一点。这是一个关于为什么是这样的有用的答案。
正如您在本系列的后续内容中将看到的,JSX 非常强大。它是我们堆栈中的一个很棒的工具,并且通常理解它非常有用。
<InspectorControls />
,然后对 class InspectorControls
执行“在文件夹中查找”,您将看到类似 Andy 在此处的示例的内容!如果您找不到它,则 JSX 必须注册为函数组件,并且应该通过搜索 function InspectorControls
来查找。
总结
我们快速浏览了 ES6 的一些有用特性。还有很多东西需要学习,但我希望将你的注意力集中在我们将在本教程系列中使用的内容上。我强烈建议你通过 Wes Bos 的课程进一步学习,JavaScript 30 和 ES6.io。
接下来,我们将构建一个迷你 React 组件!
文章系列
- 系列介绍
- 什么是 Gutenberg?
- 使用 create-guten-block 的入门指南
- 现代 JavaScript 语法 (本文)
- React 101
- 设置自定义 webpack
- 自定义“卡片”块
如果你更喜欢采用全面的方法来学习 ES6,我推荐 Axel Rauschmayer 编写的免费在线书籍 Exploring ES6。而且它一直都在,我一直在用它作为参考。
以防万一有人在这里绊倒,IE 不支持箭头函数语法。你需要像普通函数一样写出来。
显然你会用 Bable 编译它。