diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..6313b56c57
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text=auto eol=lf
diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md
index ec822e83a9..38ee795352 100644
--- a/1-js/01-getting-started/1-intro/article.md
+++ b/1-js/01-getting-started/1-intro/article.md
@@ -1,9 +1,14 @@
# JavaScript 简介
+<<<<<<< HEAD
我们一起来聊一下 JavaScript,用它能做什么,它有哪些特性,以及一些跟它配合使用的技术。
+=======
+Let's see what's so special about JavaScript, what we can achieve with it, and which other technologies play well with it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 什么是 JavaScript?
+<<<<<<< HEAD
**JavaScript** 最初的目的是为了“**赋予网页生命**”。
这种编程语言我们称之为**脚本**。它们可以写在 HTML 中,在页面加载的时候会自动执行。
@@ -31,6 +36,35 @@ JavaScript 在刚诞生的时候,它的名字叫 “LiveScript”。但是因
上面这些很容易记忆,因为经常出现在网上关于开发的文章中。我们也会这样用。例如:某个新的功能,如果 JavaScript 引擎 V8 是支持的,那么我们可以认为这个功能在 Chrome 和 Opera 中可以正常运行。
```smart header="引擎是如何工作的?"
+=======
+*JavaScript* was initially created to *"make web pages alive"*.
+
+The programs in this language are called *scripts*. They can be written right in a web page's HTML and run automatically as the page loads.
+
+Scripts are provided and executed as plain text. They don't need special preparation or compilation to run.
+
+In this aspect, JavaScript is very different from another language called [Java](https://en.wikipedia.org/wiki/Java_(programming_language)).
+
+```smart header="Why JavaScript?"
+When JavaScript was created, it initially had another name: "LiveScript". But Java was very popular at that time, so it was decided that positioning a new language as a "younger brother" of Java would help.
+
+But as it evolved, JavaScript became a fully independent language with its own specification called [ECMAScript](http://en.wikipedia.org/wiki/ECMAScript), and now it has no relation to Java at all.
+```
+
+Today, JavaScript can execute not only in the browser, but also on the server, or actually on any device that has a special program called [the JavaScript engine](https://en.wikipedia.org/wiki/JavaScript_engine).
+
+The browser has an embedded engine sometimes called a "JavaScript virtual machine".
+
+Different engines have different "codenames". For example:
+
+- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome and Opera.
+- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox.
+- ...There are other codenames like "Trident" and "Chakra" for different versions of IE, "ChakraCore" for Microsoft Edge, "Nitro" and "SquirrelFish" for Safari, etc.
+
+The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome and Opera.
+
+```smart header="How do engines work?"
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
引擎很复杂,但是基本原理很简单。
@@ -38,16 +72,28 @@ JavaScript 在刚诞生的时候,它的名字叫 “LiveScript”。但是因
2. 然后将脚本转化(“编译”)为机器语言。
3. 然后就可以在机器上飞速的运行。
+<<<<<<< HEAD
引擎会对流程中的每个阶段都进行优化。它甚至可以在运行时监视编译的脚本,分析数据流并根据这些对机器代码应用优化。最后,脚本会执行地非常快。
+=======
+The engine applies optimizations at each step of the process. It even watches the compiled script as it runs, analyzes the data that flows through it, and applies optimizations to the machine code based on that knowledge. When it's done, scripts run quite fast.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 浏览器中的 JavaScript 能做什么 ?
+<<<<<<< HEAD
现代的 JavaScript 是一种“安全”语言。它不提供对内存或 CPU 的底层访问,因为它最初是为浏览器创建的,不需要这些功能。
JavaScript 的能力依赖于它执行的环境。例如:[Node.js](https://wikipedia.org/wiki/Node.js) 允许 JavaScript 读写任意文件、执行网络请求等。
浏览器中的 JavaScript 可以完成所有和网页相关的操作、处理用户和 Web 服务器之间的交互。
+=======
+Modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or CPU, because it was initially created for browsers which do not require it.
+
+JavaScript's capabilities greatly depend on the environment it's running in. For instance, [Node.js](https://wikipedia.org/wiki/Node.js) supports functions that allow JavaScript to read/write arbitrary files, perform network requests, etc.
+
+In-browser JavaScript can do everything related to webpage manipulation, interaction with the user, and the webserver.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如,浏览器中的 JavaScript 可以完成下面这些事:
@@ -61,7 +107,11 @@ JavaScript 的能力依赖于它执行的环境。例如:[Node.js](https://wik
为了用户的(信息)安全,在浏览器中的 JavaScript 的能力是有限的。这样主要是为了阻止邪恶的网站获得或修改用户的私人数据。
+<<<<<<< HEAD
这些限制的例子有:
+=======
+Examples of such restrictions include:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
* 网页中的 JavaScript 不能读、写、复制及执行用户磁盘上的文件或程序。它没有直接访问操作系统的功能。
@@ -70,6 +120,7 @@ JavaScript 的能力依赖于它执行的环境。例如:[Node.js](https://wik
JavaScript 有很多方式和设备的照相机/麦克风交互,但是这些都需要提前获得用户的授权许可。所以,JavaScript 并不会偷偷地通过你的摄像头观察你,更不会把你的信息发送到[美国国家安全局](https://en.wikipedia.org/wiki/National_Security_Agency)。
- 不同的浏览器标签页之间基本彼此不相关。有时候,也会有一些关系。例如,通过 JavaScript 打开另外一个新的标签页。但即使在这种情况下,如果两个标签页打开的不是同一个网站(域名、协议或者端口任一不相同的网站),他们都不能够相互通信。
+<<<<<<< HEAD
这就是“同源策略”。为了解决不同标签页交互的问题,两个同源的网站必须**都**包含一些特殊的 JavaScript 代码,才能够实现数据交换。
这个限制也是为了用户的信息安全。例如,用户打开的 `http://anysite.com` 网页的 JavaScript 不能访问 `http://gmail.com`(另外一个标签页打开的网页)也不能从那里窃取信息。
@@ -78,22 +129,45 @@ JavaScript 的能力依赖于它执行的环境。例如:[Node.js](https://wik

浏览器环境外的 JavaScript 一般没有这些限制。例如服务端的 JavaScript 就没有这些限制。现代浏览器还允许通过 JavaScript 来安装浏览器插件或扩展,当然这也是在用户授权的前提下。
+=======
+ This is called the "Same Origin Policy". To work around that, *both pages* must agree for data exchange and contain a special JavaScript code that handles it. We'll cover that in the tutorial.
+
+ This limitation is, again, for the user's safety. A page from `http://anysite.com` which a user has opened must not be able to access another browser tab with the URL `http://gmail.com` and steal information from there.
+- JavaScript can easily communicate over the net to the server where the current page came from. But its ability to receive data from other sites/domains is crippled. Though possible, it requires explicit agreement (expressed in HTTP headers) from the remote side. Once again, that's a safety limitation.
+
+
+
+Such limits do not exist if JavaScript is used outside of the browser, for example on a server. Modern browsers also allow plugin/extensions which may ask for extended permissions.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## JavaScript 为什么与众不同?
至少有 **3** 件事值得一提:
```compare
+<<<<<<< HEAD
+ 和 HTML/CSS 完全的集成。
+ 使用简单的工具完成简单的任务。
+ 被所有的主流浏览器支持,并且默认开启。
+=======
++ Full integration with HTML/CSS.
++ Simple things are done simply.
++ Support by all major browsers and enabled by default.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
+JavaScript is the only browser technology that combines these three things.
+<<<<<<< HEAD
满足这三条的浏览器技术也只有 JavaScript 了。
这就是为什么 JavaScript 与众不同!这也是为什么它是创建浏览器界面的最普遍的工具。
当然,学习一项新技术的时候,最好先看一下它的前景。所以,接下来我们继续讨论包括新语言和浏览器功能在内的现代趋势。
+=======
+That's what makes JavaScript unique. That's why it's the most widespread tool for creating browser interfaces.
+
+While planning to learn a new technology, it's beneficial to check its perspectives. So let's move on to the modern trends affecting it, including new languages and browser abilities.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 比 JavaScript “好” 的语言
@@ -104,18 +178,36 @@ JavaScript 的能力依赖于它执行的环境。例如:[Node.js](https://wik
所以,最近出现了很多不同的语言,这些语言在浏览器中执行之前,都会被**编译**(转化)成 JavaScript。
+<<<<<<< HEAD
现代化的工具使得编译速度非常快速和透明,实际上允许开发人员使用另一种语言编写代码并将其自动转换为 JavaScript。
+=======
+Modern tools make the transpilation very fast and transparent, actually allowing developers to code in another language and auto-converting it "under the hood".
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这些语言的例子有:
+<<<<<<< HEAD
- [CoffeeScript](http://coffeescript.org/) 是 JavaScript 的语法糖,它语法简短,明确简洁。通常使用 Ruby 的人喜欢用。
- [TypeScript](http://www.typescriptlang.org/) 将注意力集中在增加严格的数据类型。这样就能简化开发,也能用于开发复杂的系统。TypeScript 是微软开发的。
- [Dart](https://www.dartlang.org/) 是一门独立的语言。它拥有自己的引擎用于在非浏览器环境中运行(如:在手机应用中运行)。最开始是 Google 提供的用于替代 JavaScript 的,但是现在,它和其他上述的语言一样,浏览器也要求它被编译成 JavaScript 。
当然,还有更多其他的语言。即使我们在使用这些语言,我们也需要知道 JavaScript。因为学习 JavaScript 可以让我们真正明白我们自己在做什么。
+=======
+- [CoffeeScript](http://coffeescript.org/) is a "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it.
+- [TypeScript](http://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft.
+- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps). It was initially offered by Google as a replacement for JavaScript, but as of now, browsers require it to be transpiled to JavaScript just like the ones above.
+
+There are more. Of course, even if we use one of these languages, we should also know JavaScript to really understand what we're doing.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 总结
+<<<<<<< HEAD
- JavaScript 最开始是为浏览器设计的一门语言,但是现在也可以在其它的环境中运行。
- 现在,JavaScript 是一门在浏览器中使用最广、并且能够很好集成 HTML/CSS 的语言。
- 有很多其他的语言可以编译成 JavaScript,这些语言还提供更多的功能。最好要了解一下这些语言,至少需要在掌握 JavaScript 之后简单地看一下。
+=======
+- JavaScript was initially created as a browser-only language, but is now used in many other environments as well.
+- Today, JavaScript has a unique position as the most widely-adopted browser language with full integration with HTML/CSS.
+- There are many languages that get "transpiled" to JavaScript and provide certain features. It is recommended to take a look at them, at least briefly, after mastering JavaScript.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/01-getting-started/1-intro/limitations.png b/1-js/01-getting-started/1-intro/limitations.png
index d5d315c5c1..3ef6b1e087 100644
Binary files a/1-js/01-getting-started/1-intro/limitations.png and b/1-js/01-getting-started/1-intro/limitations.png differ
diff --git a/1-js/01-getting-started/1-intro/limitations@2x.png b/1-js/01-getting-started/1-intro/limitations@2x.png
index 01483997da..7aa1c41ae4 100644
Binary files a/1-js/01-getting-started/1-intro/limitations@2x.png and b/1-js/01-getting-started/1-intro/limitations@2x.png differ
diff --git a/1-js/01-getting-started/2-code-editors/article.md b/1-js/01-getting-started/2-code-editors/article.md
index 64cea6a40b..4027264641 100644
--- a/1-js/01-getting-started/2-code-editors/article.md
+++ b/1-js/01-getting-started/2-code-editors/article.md
@@ -2,6 +2,7 @@
程序员接触时间最长的就是代码编辑器(后面简称编辑器)。
+<<<<<<< HEAD
编辑器主要分两种:IDE(集成开发环境)和轻量编辑器。很多人喜欢这两种各选一个。
## IDE
@@ -19,12 +20,36 @@ IDE 加载项目(通常包含多个文件),并且允许在不同文件之
除了 Visual Studio,以上这些 IDE 都是跨平台的。Visual Studio 无法在 Linux 上使用。
大多数 IDE 是收费的,但是他们都可以试用。这些费用对于一个合格的程序员的薪水来说,肯定算不了什么,所以去选一个对你来说最好的吧。
+=======
+There are two main types of code editors: IDEs and lightweight editors. Many people use one tool of each type.
+
+## IDE
+
+The term [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) (Integrated Development Environment) refers to a powerful editor with many features that usually operates on a "whole project." As the name suggests, it's not just an editor, but a full-scale "development environment."
+
+An IDE loads the project (which can be many files), allows navigation between files, provides autocompletion based on the whole project (not just the open file), and integrates with a version management system (like [git](https://git-scm.com/)), a testing environment, and other "project-level" stuff.
+
+If you haven't selected an IDE yet, consider the following options:
+
+- [WebStorm](http://www.jetbrains.com/webstorm/) for frontend development. The same company offers other editors for other languages (paid).
+- [Netbeans](http://netbeans.org/) (free).
+
+All of these IDEs are cross-platform.
+
+For Windows, there's also "Visual Studio", not to be confused with "Visual Studio Code." "Visual Studio" is a paid and mighty Windows-only editor, well-suited for the .NET platform. A free version of it is called [Visual Studio Community](https://www.visualstudio.com/vs/community/).
+
+Many IDEs are paid but have a trial period. Their cost is usually negligible compared to a qualified developer's salary, so just choose the best one for you.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 轻量编辑器
“轻量编辑器”没有 IDE 那么功能强大,但是他们一般很快、优雅而且简单。
+<<<<<<< HEAD
“轻量编辑器”主要用于立即打开编辑一个文件。
+=======
+They are mainly used to open and edit a file instantly.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
“轻量编辑器”和 IDE 有很大的区别。IDE 一般是项目中使用,就意味着一开始要加载很多数据,并且在使用的过程中会分析项目的结构和内容。如果我们只需要编辑一个文件,那么 “轻量编辑器” 会更快的帮我们打开文件。
@@ -32,11 +57,19 @@ IDE 加载项目(通常包含多个文件),并且允许在不同文件之
下面是一些流行的“轻量编辑器”:
+<<<<<<< HEAD
- [Visual Studio Code](https://code.visualstudio.com/)(跨平台、免费)。
- [Atom](https://atom.io/)(跨平台、免费)。
- [Sublime Text](http://www.sublimetext.com)(跨平台、共享软件)。
- [Notepad++](https://notepad-plus-plus.org/)(Windows、免费)。
- [Vim](http://www.vim.org/) 和 [Emacs](https://www.gnu.org/software/emacs/) 很棒,前提是如果你知道怎么用。
+=======
+- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free) also has many IDE-like features.
+- [Atom](https://atom.io/) (cross-platform, free).
+- [Sublime Text](http://www.sublimetext.com) (cross-platform, shareware).
+- [Notepad++](https://notepad-plus-plus.org/) (Windows, free).
+- [Vim](http://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool if you know how to use them.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 我的最爱
@@ -44,13 +77,26 @@ IDE 加载项目(通常包含多个文件),并且允许在不同文件之
我使用的编辑器:
+<<<<<<< HEAD
- 使用 [WebStorm](http://www.jetbrains.com/webstorm/) 写 JavaScript,如果项目涉及其他语言我切换到上面列出的其他 Jetbrains 产品之一。
- 轻量编辑器 —— [Sublime Text](http://www.sublimetext.com) 或 [Atom](https://atom.io/)。
+=======
+- As an IDE for JS -- [WebStorm](http://www.jetbrains.com/webstorm/) (I switch to one of the other JetBrains offerings when using other languages)
+- As a lightweight editor -- [Sublime Text](http://www.sublimetext.com) or [Atom](https://atom.io/).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 不要争吵
+<<<<<<< HEAD
上面列表中的编辑器都是我或我的朋友(他们都是我认为很优秀的开发人员)已经使用了很长时间并且很满意的。
+=======
+The editors in the lists above are those that either I or my friends whom I consider good developers have been using for a long time and are happy with.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
世上还有很多其他的很好的编辑器,你们可以选择一个自己最喜欢的。
+<<<<<<< HEAD
选择编辑器就像选择其他工具一样。要看你的项目,以及个人的习惯、喜好。
+=======
+The choice of an editor, like any other tool, is individual and depends on your projects, habits, and personal preferences.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/01-getting-started/3-devtools/article.md b/1-js/01-getting-started/3-devtools/article.md
index be0ea58fbf..b35beb8b09 100644
--- a/1-js/01-getting-started/3-devtools/article.md
+++ b/1-js/01-getting-started/3-devtools/article.md
@@ -1,5 +1,6 @@
# 开发者控制台
+<<<<<<< HEAD
代码是很容易出现错误的。你也很可能犯错误...... 哦,我在说什么?只要你是人,你一定会犯错误(在写代码的时候),除非你是[机器人](https://en.wikipedia.org/wiki/Bender_(Futurama))。
但在浏览器中,默认情况下用户是看不到错误的。所以,如果脚本中有错误,我们看不到是什么错误,更不能够修复。
@@ -9,6 +10,17 @@
通常,开发者倾向于使用 Chrome 或 Firefox 来开发,因为它们有最好的开发者工具。一些其他的浏览器也提供开发者工具,有时还具有一些特殊的功能,通常它们都是在追赶 Chrome 或 Firefox。所以大多数人都有 “最喜欢” 的浏览器,当遇到某个浏览器独有的问题的时候,人们就会切换到其他的浏览器。
开发者工具很强大,功能丰富。首先,我们要学习如何打开它们,查找错误和运行 JavaScript 命令。
+=======
+Code is prone to errors. You will quite likely make errors... Oh, what am I talking about? You are *absolutely* going to make errors, at least if you're a human, not a [robot](https://en.wikipedia.org/wiki/Bender_(Futurama)).
+
+But in the browser, users don't see errors by default. So, if something goes wrong in the script, we won't see what's broken and can't fix it.
+
+To see errors and get a lot of other useful information about scripts, "developer tools" have been embedded in browsers.
+
+Most developers lean towards Chrome or Firefox for development because those browsers have the best developer tools. Other browsers also provide developer tools, sometimes with special features, but are usually playing "catch-up" to Chrome or Firefox. So most developers have a "favorite" browser and switch to others if a problem is browser-specific.
+
+Developer tools are potent; they have many features. To start, we'll learn how to open them, look at errors, and run JavaScript commands.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## Google Chrome
@@ -24,6 +36,7 @@

+<<<<<<< HEAD
具体什么样,要看你的 Chrome 版本。它随着时间一直在变,但是都很类似。
- 上面这个,我们能看到红色的错误信息。这个场景中,脚本里有一个未知的 “lalala” 命令。
@@ -32,26 +45,65 @@
在错误信息的下方,有个 `>` 标志。它代表 “命令行”,在 “命令行” 中,我们可以输入 JavaScript 命令,按下 `key:Enter` 来执行(`key:Shift+Enter` 用来输入多行命令)。
现在,我们能看到错误就够了。稍后,在 章节中,我们会重新更加深入地讨论开发者工具。
+=======
+The exact look of developer tools depends on your version of Chrome. It changes from time to time but should be similar.
+
+- Here we can see the red-colored error message. In this case, the script contains an unknown "lalala" command.
+- On the right, there is a clickable link to the source `bug.html:12` with the line number where the error has occurred.
+
+Below the error message, there is a blue `>` symbol. It marks a "command line" where we can type JavaScript commands. Press `key:Enter` to run them (`key:Shift+Enter` to input multi-line commands).
+
+Now we can see errors, and that's enough for a start. We'll come back to developer tools later and cover debugging more in-depth in the chapter .
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## Firefox、Edge 和其他
+<<<<<<< HEAD
大多数其他的浏览器都是通过 `key:F12` 来打开开发者工具。
他们的外观和感觉都非常相似,一旦你学会了他们中的一个(可以先尝试 Chrome),其他的也就很快了。
+=======
+## Firefox, Edge, and others
+
+Most other browsers use `key:F12` to open developer tools.
+
+The look & feel of them is quite similar. Once you know how to use one of these tools (you can start with Chrome), you can easily switch to another.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## Safari
Safari(Mac 系统中浏览器,不支持 Windows 和 Linux 系统)有一点点不同。我们需要先开启 “开发菜单”。
+<<<<<<< HEAD
打开 “偏好设置”,选择“高级”选项。选中最下方的那个选择框。

现在,我们通过 `key:Cmd+Opt+C` 就能打开或关闭控制台了。另外注意,有一个名字为 “开发” 的顶部菜单出现了。它有很多命令和选项。
+=======
+Open Preferences and go to the "Advanced" pane. There's a checkbox at the bottom:
+
+
+
+Now `key:Cmd+Opt+C` can toggle the console. Also, note that the new top menu item named "Develop" has appeared. It has many commands and options.
+
+## Multi-line input
+
+Usually, when we put a line of code into the console, and then press `key:Enter`, it executes.
+
+To insert multiple lines, press `key:Shift+Enter`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 总结
+<<<<<<< HEAD
* 开发者工具允许我们查看错误、执行命令、检查变量等等。
* 在 Windows 系统中,可以通过 `key:F12` 开启开发者工具。Mac 系统下,Chrome 需要使用 `key:Cmd+Opt+J`,Safari 使用 `key:Cmd+Opt+C`(需要提前开启)。
现在我们的环境准备好了,下一章,我们将开始讨论 JavaScript。
+=======
+- Developer tools allow us to see errors, run commands, examine variables, and much more.
+- They can be opened with `key:F12` for most browsers on Windows. Chrome for Mac needs `key:Cmd+Opt+J`, Safari: `key:Cmd+Opt+C` (need to enable first).
+
+Now we have the environment ready. In the next section, we'll get down to JavaScript.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md
index 0727719bcc..b1192532dd 100644
--- a/1-js/02-first-steps/01-hello-world/article.md
+++ b/1-js/02-first-steps/01-hello-world/article.md
@@ -1,16 +1,30 @@
# Hello, world!
+<<<<<<< HEAD
你现在所阅读的这个教程是 JavaScript 的核心内容,这部分内容是平台无关的。接下来,你将会学习 Node.js 以及使用 Node.js 的其他平台。
但是,我们需要一个工作环境来运行代码,由于本书是在线的,所以浏览器是一个不错的选择。我们会尽可能少地使用浏览器特定的命令(比如 `alert`),所以如果你打算使用如 Node.js 的其他环境,你不必多花时间来关心这些特定指令。另一方面,浏览器的具体细节我们会在教程的[下一部分](/ui)介绍。
首先,让我们看看如何将脚本添加到网页上。对于服务器端环境,你只需要使用诸如 `"node my.js"` 的 Node.js 的命令行来执行它。
+=======
+This part of the tutorial is about core JavaScript, the language itself. Later on, you'll learn about Node.js and other platforms that use it.
+
+But we need a working environment to run our scripts and, since this book is online, the browser is a good choice. We'll keep the amount of browser-specific commands (like `alert`) to a minimum so that you don't spend time on them if you plan to concentrate on another environment (like Node.js). We'll focus on JavaScript in the browser in the [next part](/ui) of the tutorial.
+
+So first, let's see how we attach a script to a webpage. For server-side environments (like Node.js), you can execute the script with a command like `"node my.js"`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## "script" 标签
JavaScript 程序可以使用 `
```
+<<<<<<< HEAD
这些注释是给不支持 `
```
+<<<<<<< HEAD
这里,`/path/to/script.js` 是脚本文件的绝对路径(从站点根目录开始)。
也可以提供相对于当前页面的相对路径。比如,`src="script.js"` 意思是来自当前文件夹的 `"script.js"` 文件。
我们还可以提供一个完整的 URL 地址,例如:
+=======
+Here, `/path/to/script.js` is an absolute path to the script file (from the site root).
+
+You can also provide a relative path from the current page. For instance, `src="script.js"` would mean a file `"script.js"` in the current folder.
+
+We can give a full URL as well. For instance:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```html
@@ -94,6 +145,7 @@ JavaScript 程序可以使用 `
```
+<<<<<<< HEAD
我们必须选择,要么外部的`` 这种方式插入。
有关浏览器脚本以及它们和网页的关系,还有很多可学的。但是请记住,这部分教程主要是针对 JavaScript 语言的,所以我们不该分散自己的注意力。我们使用浏览器作为运行 JavaScript 的一种方式,非常便于我们在线阅读。
+=======
+- We can use a ``.
+
+
+There is much more to learn about browser scripts and their interaction with the webpage. But let's keep in mind that this part of the tutorial is devoted to the JavaScript language, so we shouldn't distract ourselves with browser-specific implementations of it. We'll be using the browser as a way to run JavaScript, which is very convenient for online reading, but only one of many.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/01-hello-world/hello-world-render.png b/1-js/02-first-steps/01-hello-world/hello-world-render.png
index ffe810697c..ba94e017d6 100644
Binary files a/1-js/02-first-steps/01-hello-world/hello-world-render.png and b/1-js/02-first-steps/01-hello-world/hello-world-render.png differ
diff --git a/1-js/02-first-steps/01-hello-world/hello-world-render@2x.png b/1-js/02-first-steps/01-hello-world/hello-world-render@2x.png
index c4411027ca..9b2d4479f6 100644
Binary files a/1-js/02-first-steps/01-hello-world/hello-world-render@2x.png and b/1-js/02-first-steps/01-hello-world/hello-world-render@2x.png differ
diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md
index 7b5c702fd7..47387ef906 100644
--- a/1-js/02-first-steps/02-structure/article.md
+++ b/1-js/02-first-steps/02-structure/article.md
@@ -1,22 +1,38 @@
# 代码结构
+<<<<<<< HEAD
第一件需要学习的事情就是构建代码块。
+=======
+The first thing we'll study is the building blocks of code.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 语句
语句是执行操作的语法结构和命令。
+<<<<<<< HEAD
我们已经见过语句 `alert('Hello, world!')`,可以用来显示消息。
我们可以在代码中编写任意数量的语句。语句之间可以使用分号分割。
例如,我们将 Hello World 这条信息一分为二:
+=======
+We've already seen a statement, `alert('Hello, world!')`, which shows the message "Hello, world!".
+
+We can have as many statements in our code as we want. Statements can be separated with a semicolon.
+
+For example, here we split "Hello World" into two alerts:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
alert('Hello'); alert('World');
```
+<<<<<<< HEAD
通常,每条语句在单独的一行书写 —— 这会提高代码的可读性。
+=======
+Usually, statements are written on separate lines to make the code more readable:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
alert('Hello');
@@ -34,11 +50,19 @@ alert('Hello')
alert('World')
```
+<<<<<<< HEAD
此处,JavaScript 将分行符解释成“隐式”的分号。这也被称为[自动分号插入](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion)。
**多数情况下,换行意味着一个分号。但是“多数情况”并不意味着“总是”!**
有很多换行并不是分号的例子,比如:
+=======
+Here, JavaScript interprets the line break as an "implicit" semicolon. This is called an [automatic semicolon insertion](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion).
+
+**In most cases, a newline implies a semicolon. But "in most cases" does not mean "always"!**
+
+There are cases when a newline does not mean a semicolon. For example:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
alert(3 +
@@ -46,7 +70,11 @@ alert(3 +
+ 2);
```
+<<<<<<< HEAD
代码输出 `6`,因为 JavaScript 并没有在这里插入分号。 显而易见的是,如果一行以加号 `"+"` 结尾,那么这是一个“不完整的表达式”,不需要分号。所以,这个例子得到了预期的结果。
+=======
+The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so the semicolon is not required. And in this case that works as intended.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
**但存在 JavaScript 无法假设分号是否真正被需要的情况。**
@@ -59,9 +87,15 @@ alert(3 +
[1, 2].forEach(alert)
```
+<<<<<<< HEAD
不需要考虑方括号 `[]` 和 `forEach` 的含义,我们接下来会学习它们,现在它们并不重要。让我们记住最终结果:先显示 `1`,然后显示 `2`。
现在我们在代码前面加入一个 `alert`,并且不用分号结束它。
+=======
+No need to think about the meaning of the brackets `[]` and `forEach` yet. We'll study them later. For now, just remember the result of the code: it shows `1` then `2`.
+
+Now, let's add an `alert` before the code and *not* finish it with a semicolon:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
alert("There will be an error")
@@ -69,7 +103,11 @@ alert("There will be an error")
[1, 2].forEach(alert)
```
+<<<<<<< HEAD
现在,如果我们运行代码,仅仅第一个 `alert` 显示了文本,接着我们收到了一个错误!
+=======
+Now if we run the code, only the first `alert` is shown and then we have an error!
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
但是,如果我们在第一个 `alert` 后加入一个分号,就工作正常了:
```js run
@@ -78,27 +116,49 @@ alert("All fine now");
[1, 2].forEach(alert)
```
+<<<<<<< HEAD
现在,我们能得到 "All fine now" ,然后是 `1` 和 `2`。
出现无分号变量的错误,是因为 JavaScript 并不在方括号 `[...]` 前添加一个隐式的分号。
所以,因为分号并不会自动插入,第一个例子被视为一条简单的语句,我们从引擎看到的是这样子的:
+=======
+Now we have the "All fine now" message followed by `1` and `2`.
+
+
+The error in the no-semicolon variant occurs because JavaScript does not assume a semicolon before square brackets `[...]`.
+
+So, because the semicolon is not auto-inserted, the code in the first example is treated as a single statement. Here's how the engine sees it:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
alert("There will be an error")[1, 2].forEach(alert)
```
+<<<<<<< HEAD
但它应该是两条语句,而不是一条。这种情况下的合并是不对的,所以才会造成错误。诸如此类,还有很多。
````
如果语句被换行分割,非常建议在语句之间添加分号。这个规则被社区广泛采纳。让我们再次强调 —— 大部分时候可以省略分号,但是最好是,尤其对于新手,加上它。
+=======
+But it should be two separate statements, not one. Such a merging in this case is just wrong, hence the error. This can happen in other situations.
+````
+
+We recommend putting semicolons between statements even if they are separated by newlines. This rule is widely adopted by the community. Let's note once again -- *it is possible* to leave out semicolons most of the time. But it's safer -- especially for a beginner -- to use them.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 注释
+<<<<<<< HEAD
随着时间推移,程序变得越来越复杂。为代码添加**注释**来描述发生了什么(What happens)和为什么(Why),变得非常有必要了。
注释可以在脚本的任何地方添加,它们并不会影响代码的执行,因为引擎会简单地忽略它们。
+=======
+As time goes on, programs become more and more complex. It becomes necessary to add *comments* which describe what the code does and why.
+
+Comments can be put into any place of a script. They don't affect its execution because the engine simply ignores them.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
**单行注释以两个正斜杠字符 `//` 开始。**
@@ -124,9 +184,15 @@ alert('Hello');
alert('World');
```
+<<<<<<< HEAD
注释的内容被忽略了,所以如果我们在 /* ... */ 中放入代码,并不会执行。
有时候,可以很方便地临时禁用代码:
+=======
+The content of comments is ignored, so if we put code inside /* ... */, it won't execute.
+
+Sometimes it can be handy to temporarily disable a part of code:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
/* 注释代码
@@ -135,8 +201,13 @@ alert('Hello');
alert('World');
```
+<<<<<<< HEAD
```smart header="使用热键!"
在大多数的编辑器中,一行代码可以使用 `key:Ctrl+/` 热键进行单行注释,诸如 `key:Ctrl+Shift+/` 的热键可以进行多行注释(选择代码,然后按下热键)。对于 Mac 电脑,应使用 `key:Cmd` 而不是 `key:Ctrl`。
+=======
+```smart header="Use hotkeys!"
+In most editors, a line of code can be commented out by pressing the `key:Ctrl+/` hotkey for a single-line comment and something like `key:Ctrl+Shift+/` -- for multiline comments (select a piece of code and press the hotkey). For Mac, try `key:Cmd` instead of `key:Ctrl`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
````warn header="不支持注释嵌套!"
@@ -154,6 +225,12 @@ alert( 'World' );
注释你的代码,请不要有任何迟疑。
+<<<<<<< HEAD
注释会增加代码总量,但这一点也不是问题。有很多工具可以在你部署到服务器之前缩减代码。这些工具会移除注释,所以注释不会出现在发布的脚本中。所以,注释对我们的生产没有任何负面影响。
在进一步的教程中,会有一章 的内容解释如何书写更好的注释。
+=======
+Comments increase the overall code footprint, but that's not a problem at all. There are many tools which minify code before publishing to a production server. They remove comments, so they don't appear in the working scripts. Therefore, comments do not have negative effects on production at all.
+
+Later in the tutorial there will be a chapter that also explains how to write better comments.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/03-strict-mode/article.md b/1-js/02-first-steps/03-strict-mode/article.md
index bb283c5cbd..cb82bf8ab7 100644
--- a/1-js/02-first-steps/03-strict-mode/article.md
+++ b/1-js/02-first-steps/03-strict-mode/article.md
@@ -1,5 +1,6 @@
# 新模式,"use strict"
+<<<<<<< HEAD
长久以来,JavaScript 不断发展且并未带来任何兼容性问题。新特性被加入该语言,旧的功能也没有改变。
这么做有利于兼容旧代码,但缺点是 JavaScript 创造者的任何错误和不完美的考虑也永远地保留在了语言中。
@@ -11,6 +12,19 @@
这个指令看上去是一个字符串 `"use strict"` 或者 `'use strict'`。当它处于脚本文件的顶部时,则整个脚本文件都将以“现代”模式进行工作。
比如:
+=======
+For a long time, JavaScript evolved without compatibility issues. New features were added to the language while old functionality didn't change.
+
+That had the benefit of never breaking existing code. But the downside was that any mistake or an imperfect decision made by JavaScript's creators got stuck in the language forever.
+
+This was the case until 2009 when ECMAScript 5 (ES5) appeared. It added new features to the language and modified some of the existing ones. To keep the old code working, most modifications are off by default. You need to explicitly enable them with a special directive: `"use strict"`.
+
+## "use strict"
+
+The directive looks like a string: `"use strict"` or `'use strict'`. When it is located at the top of a script, the whole script works the "modern" way.
+
+For example:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
"use strict";
@@ -21,6 +35,7 @@
稍后我们才会学习函数(一种组合命令的方式)。
+<<<<<<< HEAD
但我们可以提前了解一下,`"use strict"` 可以放在函数(大多数函数)而不是整个脚本的开头。那么严格模式仅在该函数中启用。但通常人们会将它用于整个脚本。
@@ -32,6 +47,19 @@
```js no-strict
alert("some code");
// 下面的 "use strict" 会被忽略,必须在最顶部。
+=======
+Looking ahead, let's just note that `"use strict"` can be put at the start of most kinds of functions instead of the whole script. Doing that enables strict mode in that function only. But usually, people use it for the whole script.
+
+
+````warn header="Ensure that \"use strict\" is at the top"
+Please make sure that `"use strict"` is at the top of your scripts, otherwise strict mode may not be enabled.
+
+Strict mode isn't enabled here:
+
+```js no-strict
+alert("some code");
+// "use strict" below is ignored--it must be at the top
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
"use strict";
@@ -41,14 +69,40 @@ alert("some code");
只有注释可以出现在 `"use strict"` 的上面。
````
+<<<<<<< HEAD
```warn header="没有办法取消 `use strict`"
没有类似于 `"no use strict"` 这样的指令可以使程序返回默认模式。
一旦进入了严格模式,就没有退路了。
+=======
+```warn header="There's no way to cancel `use strict`"
+There is no directive like `"no use strict"` that reverts the engine to old behavior.
+
+Once we enter strict mode, there's no return.
+```
+
+## Browser console
+
+For the future, when you use a browser console to test features, please note that it doesn't `use strict` by default.
+
+Sometimes, when `use strict` makes a difference, you'll get incorrect results.
+
+Even if we press `key:Shift+Enter` to input multiple lines, and put `use strict` on top, it doesn't work. That's because of how the console executes the code internally.
+
+The reliable way to ensure `use strict` would be to input the code into console like this:
+
+```js
+(function() {
+ 'use strict';
+
+ // ...your code...
+})()
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 总是使用 "use strict"
+<<<<<<< HEAD
使用 `"use strict"` 与“默认”模式的区别仍然有待完善。
在接下来的章节中,当我们学习语言功能时,我们会记录严格模式的差异。幸运的是,没有那么多。实际上,它们为我们编写代码提供了极大的便利。
@@ -59,3 +113,15 @@ alert("some code");
2. 严格模式通过顶部的 `"use strict"` 启用。一些新语言特性诸如 "classes" 和 "modules" 也会自动开启严格模式。
3. 所有的现代浏览器都支持严格模式。
4. 建议始终使用 `"use strict"` 启动脚本。本教程的所有例子都默认采用严格模式,除非特别指定(非常少)。
+=======
+We have yet to cover the differences between strict mode and the "default" mode.
+
+In the next chapters, as we learn language features, we'll note the differences between the strict and default modes. Luckily, there aren't many and they actually make our lives better.
+
+For now, it's enough to know about it in general:
+
+1. The `"use strict"` directive switches the engine to the "modern" mode, changing the behavior of some built-in features. We'll see the details later in the tutorial.
+2. Strict mode is enabled by placing `"use strict"` at the top of a script or function. Several language features, like "classes" and "modules", enable strict mode automatically.
+3. Strict mode is supported by all modern browsers.
+4. We recommended always starting scripts with `"use strict"`. All examples in this tutorial assume strict mode unless (very rarely) specified otherwise.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md
index 65194ae7d9..2fecf89655 100644
--- a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md
+++ b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md
@@ -18,4 +18,8 @@ let currentUserName = "John";
现代编辑器的自动补全可以让长变量名变得容易书写。不要浪费这个特性。一个名字中包含三个词就挺好的。
+<<<<<<< HEAD
如果你的编辑器没有合适的自动补全,换[一个新的吧](/code-editors)。
+=======
+And if your editor does not have proper autocompletion, get [a new one](/code-editors).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/04-variables/2-declare-variables/task.md b/1-js/02-first-steps/04-variables/2-declare-variables/task.md
index a048299cf6..0e411f1780 100644
--- a/1-js/02-first-steps/04-variables/2-declare-variables/task.md
+++ b/1-js/02-first-steps/04-variables/2-declare-variables/task.md
@@ -4,5 +4,10 @@ importance: 3
# 给出正确的名字
+<<<<<<< HEAD
1. 使用我们的星球的名字创建一个变量。你会怎么命名这个变量?
2. 创建一个变量来存储当前浏览者的名字。你会怎么命名这个变量?
+=======
+1. Create a variable with the name of our planet. How would you name such a variable?
+2. Create a variable to store the name of a current visitor to a website. How would you name that variable?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md
index e5b2a3ae17..2bedd03b5a 100644
--- a/1-js/02-first-steps/04-variables/article.md
+++ b/1-js/02-first-steps/04-variables/article.md
@@ -1,16 +1,28 @@
# 变量
+<<<<<<< HEAD
大多数情况下,脚本需要处理信息。这有两个例子:
1. 一个网上商店 —— 这里的信息可能包含正在售卖的商品和购物车
2. 一个聊天应用 —— 这里的信息可能包括用户、消息等等。
+=======
+Most of the time, a JavaScript application needs to work with information. Here are two examples:
+1. An online shop -- the information might include goods being sold and a shopping cart.
+2. A chat application -- the information might include users, messages, and much more.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
变量就是用来储存这些信息的。
## 一个变量
+<<<<<<< HEAD
一个 [变量](https://en.wikipedia.org/wiki/Variable_(computer_science)) 是数据的“命名存储”。我们可以使用变量来保存商品、访客和其他信息。
在 JavaScript 中创建一个变量,我们需要用到 `let` 关键字。
+=======
+A [variable](https://en.wikipedia.org/wiki/Variable_(computer_science)) is a "named storage" for data. We can use variables to store goodies, visitors, and other data.
+
+To create a variable in JavaScript, use the `let` keyword.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
下面的语句创建(换句话说,**声明**或者**定义**)了一个名称为 "message" 的变量:
@@ -18,7 +30,11 @@
let message;
```
+<<<<<<< HEAD
现在,通过赋值操作符 `=` 为变量添加一些数据:
+=======
+Now, we can put some data into it by using the assignment operator `=`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let message;
@@ -39,7 +55,11 @@ alert(message); // 显示变量内容
*/!*
```
+<<<<<<< HEAD
简洁一点,我们将变量定义和赋值合并成一行:
+=======
+To be concise, we can combine the variable declaration and assignment into a single line:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let message = 'Hello!'; // 定义变量,并且赋值
@@ -53,7 +73,11 @@ alert(message); // Hello!
let user = 'John', age = 25, message = 'Hello';
```
+<<<<<<< HEAD
看上去代码长度更短,但并不推荐。为了更好的可读性,请一行声明一个变量。
+=======
+That might seem shorter, but we don't recommend it. For the sake of better readability, please use a single line per variable.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
多行变量声明有点长,但更容易阅读:
@@ -63,7 +87,11 @@ let age = 25;
let message = 'Hello';
```
+<<<<<<< HEAD
一些程序员采用下面的形式书写多个变量:
+=======
+Some people also define multiple variables in this multiline style:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js no-beautify
let user = 'John',
age = 25,
@@ -78,19 +106,33 @@ let user = 'John'
, message = 'Hello';
```
+<<<<<<< HEAD
技术上讲,这些变体都有一样的效果。所以,这是个个人品味和审美方面的问题。
````smart header="`var` 而不是 `let`"
在较旧的脚本中,你也可能发现另一个关键字 `var`,而不是 `let`:
+=======
+Technically, all these variants do the same thing. So, it's a matter of personal taste and aesthetics.
+
+
+````smart header="`var` instead of `let`"
+In older scripts, you may also find another keyword: `var` instead of `let`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
*!*var*/!* message = 'Hello';
```
+<<<<<<< HEAD
`var` 关键字与 `let` **大体**相同,也用来声明变量,但稍微有些不同,也有点“老派”。
`let` 和 `var` 之间有些微妙的差别,但目前对于我们来说并不重要。我们将会在 章节中介绍它们。
+=======
+The `var` keyword is *almost* the same as `let`. It also declares a variable, but in a slightly different, "old-school" way.
+
+There are subtle differences between `let` and `var`, but they do not matter for us yet. We'll cover them in detail in the chapter .
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
## 一个现实生活的类比
@@ -101,10 +143,15 @@ let user = 'John'

+<<<<<<< HEAD
我们可以在盒子内放入任何值。
同样,我们也可以改变它。值可以根据需要多次改变。
+=======
+We can put any value in the box.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
+We can also change it as many times as we want:
```js run
let message;
@@ -136,29 +183,51 @@ alert(hello); // Hello world!
alert(message); // Hello world!
```
+<<<<<<< HEAD
```smart header="函数式语言"
有趣的是,也存在禁止更改变量值的[函数式](https://en.wikipedia.org/wiki/Functional_programming)编程语言。比如,[Scala](http://www.scala-lang.org/) 或者 [Erlang](http://www.erlang.org/)。
+=======
+```smart header="Functional languages"
+It's interesting to note that there exist [functional](https://en.wikipedia.org/wiki/Functional_programming) programming languages, like [Scala](http://www.scala-lang.org/) or [Erlang](http://www.erlang.org/) that forbid changing variable values.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
在这种类型的语言中,一旦值保存在盒子中,就永远存在。如果你试图保存其他值,它会强制创建一个新盒子(声明一个新变量),无法重用先前的变量。
+<<<<<<< HEAD
虽然看上去有点奇怪,但是这些语言有很大的发展潜力。不仅如此,在某些领域,比如并行计算,这个限制有一定的好处。研究这样的一门语言(即使不打算很快就用上它)有助于开阔视野。
+=======
+Though it may seem a little odd at first sight, these languages are quite capable of serious development. More than that, there are areas like parallel computations where this limitation confers certain benefits. Studying such a language (even if you're not planning to use it soon) is recommended to broaden the mind.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 变量命名 [#variable-naming]
+<<<<<<< HEAD
JavaScript 的变量命名有两个限制:
1. 变量名称必须仅包含字母,数字,符号 `$` and `_`。
2. 首字符必须非数字。
有效的命名,例如:
+=======
+There are two limitations on variable names in JavaScript:
+
+1. The name must contain only letters, digits, or the symbols `$` and `_`.
+2. The first character must not be a digit.
+
+Examples of valid names:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let userName;
let test123;
```
+<<<<<<< HEAD
如果命名包括多个单词,通常采用驼峰式命名法([camelCase](https://en.wikipedia.org/wiki/CamelCase))。也就是,单词一个接一个,每个单词以大写字母开头:`myVeryLongName`。
+=======
+When the name contains multiple words, [camelCase](https://en.wikipedia.org/wiki/CamelCase) is commonly used. That is: words go one after another, each word except first starting with a capital letter: `myVeryLongName`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
有趣的是,美元符号 `'$'` 和下划线 `'_'` 也可以在命名中使用。它们是正常的符号,就跟字母一样,没有任何特殊的含义。
@@ -176,6 +245,7 @@ alert($ + _); // 3
```js no-beautify
let 1a; // 不能以数字开始
+<<<<<<< HEAD
let my-name; // 连字符 '-' 不允许在命名中出现
```
@@ -185,6 +255,17 @@ let my-name; // 连字符 '-' 不允许在命名中出现
````smart header="允许非英文字母,但不推荐"
可以使用任何语言,包括西里尔字母(cyrillic letters)甚至是象形文字,就像这样:
+=======
+let my-name; // hyphens '-' aren't allowed in the name
+```
+
+```smart header="Case matters"
+Variables named `apple` and `AppLE` are two different variables.
+```
+
+````smart header="Non-Latin letters are allowed, but not recommended"
+It is possible to use any language, including cyrillic letters or even hieroglyphs, like this:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let имя = '...';
@@ -194,10 +275,17 @@ let 我 = '...';
技术上讲,完全没有错误,这样的命名是完全允许的,但是有一个国际传统:在变量命名中使用英文。哪怕我们正在写一个很小的脚本,它也有可能有很长的生命周期。某个时候,来自其他国家的人可能会阅读它。
````
+<<<<<<< HEAD
````warn header="保留字"
有一长串的保留字无法用作变量命名,因为它们被语言本身采用了。
比如,单词 `let`、`class`、`return`、`function` 被保留。
+=======
+````warn header="Reserved names"
+There is a [list of reserved words](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords), which cannot be used as variable names because they are used by the language itself.
+
+For example: `let`, `class`, `return`, and `function` are reserved.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
下面的代码将会抛出一个语法错误:
@@ -209,37 +297,56 @@ let return = 5; // 同样,不能使用 "return",错误!
````warn header="未采用 `use strict` 下的赋值"
+<<<<<<< HEAD
一般,需要在使用一个变量前定义它。但是在旧时代,可以简单地赋值来创建一个变量,而不需要 `let`。如果不使用 `use strict`,这仍然正常工作,这种行为是为了保持与旧脚本的兼容。
+=======
+Normally, we need to define a variable before using it. But in the old times, it was technically possible to create a variable by a mere assignment of the value without using `let`. This still works now if we don't put `use strict` in our scripts to maintain compatibility with old scripts.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-strict
// 注意:这个例子中没有 "use strict"
+<<<<<<< HEAD
num = 5; // 如果变量 "num" 不存在,就会被创建
+=======
+num = 5; // the variable "num" is created if it didn't exist
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
alert(num); // 5
```
+<<<<<<< HEAD
这是个糟糕的做法,严格模式下会抛出错误。
+=======
+This is a bad practice and would cause an error in strict mode:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
-```js run untrusted
+```js
"use strict";
*!*
num = 5; // error: num is not defined
*/!*
```
-
````
## 常量
+<<<<<<< HEAD
声明一个常数(不变)变量,可以使用 `const` 而非 `let`:
+=======
+To declare a constant (unchanging) variable, use `const` instead of `let`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
const myBirthday = '18.04.1982';
```
+<<<<<<< HEAD
使用 `const` 声明的变量称为“常量”。它们不能被修改,尝试这样做就会造成错误:
+=======
+Variables declared using `const` are called "constants". They cannot be changed. An attempt to do so would cause an error:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
const myBirthday = '18.04.1982';
@@ -247,7 +354,11 @@ const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // 错误,不能对常量重新赋值
```
+<<<<<<< HEAD
当程序员能确定这个变量永远不会改变的时候,就可以使用 `const` 来确保这种行为,并且清楚地向别人传递这一事实。
+=======
+When a programmer is sure that a variable will never change, they can declare it with `const` to guarantee and clearly communicate that fact to everyone.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
### 大写形式的常数
@@ -256,7 +367,11 @@ myBirthday = '01.01.2001'; // 错误,不能对常量重新赋值
这些常量使用大写和下划线命名。
+<<<<<<< HEAD
就像这样:
+=======
+For instance, let's make constants for colors in so-called "web" (hexadecimal) format:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
const COLOR_RED = "#F00";
@@ -271,6 +386,7 @@ alert(color); // #FF7F00
好处:
+<<<<<<< HEAD
- `COLOR_ORANGE` 比 `"#FF7F00"` 更容易记忆。
- 比起 `COLOR_ORANGE` 而言,`"#FF7F00"` 更容易输错。
- 阅读代码时,`COLOR_ORANGE` 比 `#FF7F00` 更有含义。
@@ -278,13 +394,26 @@ alert(color); // #FF7F00
什么时候该为常量使用大写命名,什么时候常规命名。让我们弄清楚一点:
作为一个常数,意味着值永远不变。但是有些常量在执行之前就已知了(比如红色的十六进制值),还有些在执行期间实时“计算”,赋值之后才不会改变。
+=======
+- `COLOR_ORANGE` is much easier to remember than `"#FF7F00"`.
+- It is much easier to mistype `"#FF7F00"` than `COLOR_ORANGE`.
+- When reading the code, `COLOR_ORANGE` is much more meaningful than `#FF7F00`.
+
+When should we use capitals for a constant and when should we name it normally? Let's make that clear.
+
+Being a "constant" just means that a variable's value never changes. But there are constants that are known prior to execution (like a hexadecimal value for red) and there are constants that are *calculated* in run-time, during the execution, but do not change after their initial assignment.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
```js
const pageLoadTime = /* time taken by a webpage to load */;
```
+<<<<<<< HEAD
`pageLoadTime` 的值在页面加载之前是未知的,所以采用常规命名。但是它仍然是个常量,因为赋值之后不会改变。
+=======
+The value of `pageLoadTime` is not known prior to the page load, so it's named normally. But it's still a constant because it doesn't change after assignment.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
换句话说,大写命名的常量仅用作“硬编码”值的别名。
@@ -292,6 +421,7 @@ const pageLoadTime = /* time taken by a webpage to load */;
谈到变量,还有一件非常重要的事。
+<<<<<<< HEAD
请合理地命名变量。如果有需要,花时间思考一下。
变量命名是编程过程中最重要和最复杂的技能之一。快速地浏览变量的命名就知道代码是一个初学者还是有经验的开发者书写的。
@@ -299,9 +429,19 @@ const pageLoadTime = /* time taken by a webpage to load */;
在一个现实的项目中,大多数的时间用来修改和扩展现有的代码库,而不是从头开始写一些完全独立的代码。当一段时间后,我们做完其他事情,重返我们的代码,找到命名良好的信息要容易得多。换句话说,变量要有个好名字。
声明变量之前,多花点时间思考它的良好命名。你会受益良多。
+=======
+A variable name should have a clean, obvious meaning, describe the data that it stores.
+
+Variable naming is one of the most important and complex skills in programming. A quick glance at variable names can reveal which code was written by a beginner versus an experienced developer.
+
+In a real project, most of the time is spent modifying and extending an existing code base rather than writing something completely separate from scratch. When we return to some code after doing something else for a while, it's much easier to find information that is well-labeled. Or, in other words, when the variables have good names.
+
+Please spend time thinking about the right name for a variable before declaring it. Doing so will repay you handsomely.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
一些很好遵循的规则是:
+<<<<<<< HEAD
- 使用人类可读的命名,比如 `userName` 或者 `shoppingCart`。
- 诸如 `a`、`b`、`c` 的缩写和短名称,离它们远点,除非你真的知道你在干什么。
- 变量名要能够准确描述变量并且足够简洁。不好的例子就是 `data` 和 `value`,这样的名称等于什么都没说。如果能够非常明显地从上下文知道数据和值所表达的含义,这样使用它们也是可以的。
@@ -315,18 +455,45 @@ const pageLoadTime = /* time taken by a webpage to load */;
结果是,这个变量就像是被扔进不同东西盒子,而没有改变它的贴纸。现在里面是什么?谁知道呢。我们需要靠近一点,然后检查它。
这样的程序员节省了一点变量声明的时间,但却在调试代码的时候损失数十倍。
+=======
+- Use human-readable names like `userName` or `shoppingCart`.
+- Stay away from abbreviations or short names like `a`, `b`, `c`, unless you really know what you're doing.
+- Make names maximally descriptive and concise. Examples of bad names are `data` and `value`. Such names say nothing. It's only okay to use them if the context of the code makes it exceptionally obvious which data or value the variable is referencing.
+- Agree on terms within your team and in your own mind. If a site visitor is called a "user" then we should name related variables `currentUser` or `newUser` instead of `currentVisitor` or `newManInTown`.
+
+Sounds simple? Indeed it is, but creating descriptive and concise variable names in practice is not. Go for it.
+
+```smart header="Reuse or create?"
+And the last note. There are some lazy programmers who, instead of declaring new variables, tend to reuse existing ones.
+
+As a result, their variables are like boxes into which people throw different things without changing their stickers. What's inside the box now? Who knows? We need to come closer and check.
+
+Such programmers save a little bit on variable declaration but lose ten times more on debugging.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
额外声明一个变量绝对是利大于弊的。
+<<<<<<< HEAD
目前的 JavaScript 压缩器和浏览器都很够很好地优化代码,所以不会产生性能问题。为不同的值使用不同的变量可以帮助引擎进行优化。
+=======
+Modern JavaScript minifiers and browsers optimize code well enough, so it won't create performance issues. Using different variables for different values can even help the engine optimize your code.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 总结
+<<<<<<< HEAD
我们可以声明变量来存储数据。可以通过使用 `var`、`let` 或者 `const` 来完成。
+=======
+We can declare variables to store data by using the `var`, `let`, or `const` keywords.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- `let` -- 新时代的变量声明方式。Chrome(V8)中代码必须开启严格模式以使用 `let`。
- `var` -- 旧时代的变量声明方式。一般情况下,我们不会使用它。但是,我们会在 章节介绍 `var` 和 `let` 的微妙差别,以防你需要它们。
- `const` -- 类似于`let`,但是变量的值无法被修改。
+<<<<<<< HEAD
变量应当以一种容易理解变量内部是什么的方式进行命名。
+=======
+Variables should be named in a way that allows us to easily understand what's inside them.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/04-variables/variable-change.png b/1-js/02-first-steps/04-variables/variable-change.png
index 6dd3803d97..9135e930a0 100644
Binary files a/1-js/02-first-steps/04-variables/variable-change.png and b/1-js/02-first-steps/04-variables/variable-change.png differ
diff --git a/1-js/02-first-steps/04-variables/variable-change@2x.png b/1-js/02-first-steps/04-variables/variable-change@2x.png
index f57b04ab16..c9569e6386 100644
Binary files a/1-js/02-first-steps/04-variables/variable-change@2x.png and b/1-js/02-first-steps/04-variables/variable-change@2x.png differ
diff --git a/1-js/02-first-steps/04-variables/variable.png b/1-js/02-first-steps/04-variables/variable.png
index ab532d91d3..6d24825561 100644
Binary files a/1-js/02-first-steps/04-variables/variable.png and b/1-js/02-first-steps/04-variables/variable.png differ
diff --git a/1-js/02-first-steps/04-variables/variable@2x.png b/1-js/02-first-steps/04-variables/variable@2x.png
index c9c37f034e..845f344084 100644
Binary files a/1-js/02-first-steps/04-variables/variable@2x.png and b/1-js/02-first-steps/04-variables/variable@2x.png differ
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index e4041b1b8a..f96d1b541d 100644
--- a/1-js/02-first-steps/05-types/article.md
+++ b/1-js/02-first-steps/05-types/article.md
@@ -1,6 +1,10 @@
# 数据类型
+<<<<<<< HEAD
JavaScript 中的变量可以保存任何数据。变量在前一刻可以是个字符串,然后又收到一个数值:
+=======
+A variable in JavaScript can contain any data. A variable can at one moment be a string and at another be a number:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// 没有错误
@@ -10,7 +14,11 @@ message = 123456;
允许这种操作的编程语言称为“动态类型”(dynamically typed)的编程语言,意思是,拥有数据类型,但是变量并不限于数据类型中的任何一个。
+<<<<<<< HEAD
在 JavaScript 中有七种基本数据类型。这一章我们会学习基本知识,下一章我们会详细介绍它们。
+=======
+There are seven basic data types in JavaScript. Here, we'll cover them in general and in the next chapters we'll talk about each of them in detail.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## number 类型
@@ -19,11 +27,19 @@ let n = 123;
n = 12.345;
```
+<<<<<<< HEAD
*number* 类型用于整数和浮点数。
数字有很多操作,比如,乘法 `*`、除法 `/`、加法 `+`、减法 `-` 等等。
除了常规的数字,还包括所谓的“特殊数值”也属于这种类型:`Infinity`、`-Infinity` 和 `NaN`。
+=======
+The *number* type represents both integer and floating point numbers.
+
+There are many operations for numbers, e.g. multiplication `*`, division `/`, addition `+`, subtraction `-`, and so on.
+
+Besides regular numbers, there are so-called "special numeric values" which also belong to this data type: `Infinity`, `-Infinity` and `NaN`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- `Infinity` 代表数学概念中的[无穷大](https://en.wikipedia.org/wiki/Infinity) ∞。是一个比任何数字都大的特殊值。
@@ -33,7 +49,11 @@ n = 12.345;
alert( 1 / 0 ); // Infinity
```
+<<<<<<< HEAD
或者在代码中直接提及它。
+=======
+ Or just reference it directly:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( Infinity ); // Infinity
@@ -44,12 +64,17 @@ n = 12.345;
alert( "not a number" / 2 ); // NaN, 这样的除法是错误的
```
+<<<<<<< HEAD
`NaN` 是粘性的。任何对 `NaN` 的进一步操作都会给出 `NaN`:
+=======
+ `NaN` is sticky. Any further operation on `NaN` returns `NaN`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( "not a number" / 2 + 5 ); // NaN
```
+<<<<<<< HEAD
所以,如果在数学表达式中有一个 `NaN`,会被传播到最终结果。
```smart header="数学运算是安全的"
@@ -59,12 +84,27 @@ n = 12.345;
```
特殊的数值属于 **number** 类型。当然,对这个词的一般认识是,它们并不是数字。
+=======
+ So, if there's a `NaN` somewhere in a mathematical expression, it propagates to the whole result.
+
+```smart header="Mathematical operations are safe"
+Doing maths is "safe" in JavaScript. We can do anything: divide by zero, treat non-numeric strings as numbers, etc.
+
+The script will never stop with a fatal error ("die"). At worst, we'll get `NaN` as the result.
+```
+
+Special numeric values formally belong to the "number" type. Of course they are not numbers in the common sense of this word.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
我们将在章节 了解更多有关使用数字的内容。
## string 类型
+<<<<<<< HEAD
JavaScript 中的字符串必须被包含在引号里面。
+=======
+A string in JavaScript must be surrounded by quotes.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let str = "Hello";
@@ -92,9 +132,15 @@ alert( `Hello, *!*${name}*/!*!` ); // Hello, John!
alert( `the result is *!*${1 + 2}*/!*` ); // 结果是 3
```
+<<<<<<< HEAD
`${…}` 内的表达式会被计算,结果成为字符串的一部分。可以在 `${…}` 内放置任何东西:诸如 `name` 的变量,或者诸如 `1 + 2` 的算数表达式,或者其他一些更复杂的。
需要注意的是,这仅仅在反引号内有效,其他引号不允许这种嵌入。
+=======
+The expression inside `${…}` is evaluated and the result becomes a part of the string. We can put anything in there: a variable like `name` or an arithmetical expression like `1 + 2` or something more complex.
+
+Please note that this can only be done in backticks. Other quotes don't have this embedding functionality!
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( "the result is ${1 + 2}" ); // 结果是 ${1 + 2} (双引号什么也不做)
```
@@ -128,31 +174,57 @@ let isGreater = 4 > 1;
alert( isGreater ); // true (比较的结果是 "yes")
```
+<<<<<<< HEAD
更详细的内容将会在章节 进行介绍。
+=======
+We'll cover booleans more deeply in the chapter .
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## "null" 值
+<<<<<<< HEAD
特殊的 `null` 值不属于上述任何一种类型。
它构成一个独立的类型,只包含 `null` 值:
+=======
+The special `null` value does not belong to any of the types described above.
+
+It forms a separate type of its own which contains only the `null` value:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let age = null;
```
+<<<<<<< HEAD
相比较于其他语言,JavaScript 中的 `null` 不是一个“对不存在对象的引用”或者 “null 指针”。
仅仅是一个含义为“无”、“空”或“值未知”的特殊值。
上面的代码表示,由于某些原因,`age` 是未知的。
+=======
+In JavaScript, `null` is not a "reference to a non-existing object" or a "null pointer" like in some other languages.
+
+It's just a special value which represents "nothing", "empty" or "value unknown".
+
+The code above states that `age` is unknown or empty for some reason.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## "undefined" 值
+<<<<<<< HEAD
特殊值和 `null` 一样,自成类型。
+=======
+The special value `undefined` also stands apart. It makes a type of its own, just like `null`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`undefined` 的含义是 `未被赋值`。
+<<<<<<< HEAD
如果变量被声明,而未被赋值,那么它的值就是 `undefined`:
+=======
+If a variable is declared, but not assigned, then its value is `undefined`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let x;
@@ -170,26 +242,47 @@ x = undefined;
alert(x); // "undefined"
```
+<<<<<<< HEAD
...但是不建议这样做。通常,使用使用 `null` 将一个“空”或者“未知”的值写入变量中,`undefined` 仅仅用于检验,以查看变量是否被赋值或者其他类似的操作。
+=======
+...But we don't recommend doing that. Normally, we use `null` to assign an "empty" or "unknown" value to a variable, and we use `undefined` for checks like seeing if a variable has been assigned.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## object 类型和 symbol 类型
`object` 类型是特殊的类型。
+<<<<<<< HEAD
其他所有的类型都称为“原生类型”,因为它们的值只包含一个单独的东西(字符串、数字或者其他)。相反,对象用于储存数据集合和更复杂的实体。在充分了解原生类型之后,我们会在章节 介绍对象。
`symbol` 类型用于创建对象的唯一标识符。为了学习的完整性,我们在这里提到 `symbol` 类型,但最好在学完对象之后再学习它。
+=======
+All other types are called "primitive" because their values can contain only a single thing (be it a string or a number or whatever). In contrast, objects are used to store collections of data and more complex entities. We'll deal with them later in the chapter after we learn more about primitives.
+
+The `symbol` type is used to create unique identifiers for objects. We have to mention it here for completeness, but it's better to study this type after objects.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## typeof 运算符 [#type-typeof]
+<<<<<<< HEAD
`typeof` 运算符返回参数的类型。当我们想要分别处理不同类型值的时候,或者简单地进行检验,就很有用。
+=======
+The `typeof` operator returns the type of the argument. It's useful when we want to process values of different types differently or just want to do a quick check.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
它支持两种语法形式:
+<<<<<<< HEAD
1. 作为运算符:`typeof x`。
2. 函数形式:`typeof(x)`。
换言之,有括号和没有括号,结果是一样的。
+=======
+1. As an operator: `typeof x`.
+2. As a function: `typeof(x)`.
+
+In other words, it works with parentheses or without them. The result is the same.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
对 `typeof x` 的调用返回数据类型的字符串。
@@ -217,16 +310,25 @@ typeof alert // "function" (3)
*/!*
```
+<<<<<<< HEAD
最后三行可能需要额外的说明:
1. `Math` 是一个提供数学运算的内建对象。我们会在章节 学习它。此处作为一个对象的例子。
2. `typeof null` 的结果是 `"object"`。这是不对的。这是官方在 `typeof` 方面承认的错误,只是为了兼容性而保留。当然,`null` 不是一个对象。它有自己的类型,是一个特殊值。再次强调,这是语言中的一个错误。
3. `typeof alert` 的结果是 `"function"`,因为 `alert` 在语言中是一个函数。我们会在下一章学习函数,那时我们会了解到,在语言中没有一个特别的 "function" 类型。函数隶属于 object 类型。但是 `typeof` 会对函数区分对待。这不正确,但在实践中非常方便。
+=======
+The last three lines may need additional explanation:
+
+1. `Math` is a built-in object that provides mathematical operations. We will learn it in the chapter . Here, it serves just as an example of an object.
+2. The result of `typeof null` is `"object"`. That's wrong. It is an officially recognized error in `typeof`, kept for compatibility. Of course, `null` is not an object. It is a special value with a separate type of its own. So, again, this is an error in the language.
+3. The result of `typeof alert` is `"function"`, because `alert` is a function of the language. We'll study functions in the next chapters where we'll see that there's no special "function" type in JavaScript. Functions belong to the object type. But `typeof` treats them differently. Formally, it's incorrect, but very convenient in practice.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 总结
JavaScript 中有七种基本的类型。
+<<<<<<< HEAD
- `number` 用于任何类型的数字:整数或者浮点数。
- `string` 用于字符串。一个字符串可以包含一个或多个字符,所以没有单独的单字符类型。
- `boolean` 用于 `true` 和 `false`。
@@ -234,11 +336,24 @@ JavaScript 中有七种基本的类型。
- `undefined` 用于未定义的值 —— 只有一个 `undefined` 值的独立类型。
- `object` 用于更复杂的数据结构。
- `symbol` 用于唯一的标识符。
+=======
+There are 7 basic data types in JavaScript.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`typeof` 运算符可以查看变量的类型。
+<<<<<<< HEAD
- 两种形式:`typeof x` 或者 `typeof(x)`。
- 返回的类型的字符串,比如 `"string"`。
- `null` 返回 `"object"` —— 这是语言中的一个错误,实际上它并不是一个对象。
在接下来的章节中,我们将重点介绍原生类型值,一旦掌握了,我们将继续讨论对象。
+=======
+The `typeof` operator allows us to see which type is stored in a variable.
+
+- Two forms: `typeof x` or `typeof(x)`.
+- Returns a string with the name of the type, like `"string"`.
+- For `null` returns `"object"` -- this is an error in the language, it's not actually an object.
+
+In the next chapters, we'll concentrate on primitive values and once we're familiar with them, we'll move on to objects.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md b/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md
index bbb50e78bb..f73833c371 100644
--- a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md
+++ b/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md
@@ -10,13 +10,22 @@ true + false = 1
"4" - 2 = 2
"4px" - 2 = NaN
7 / 0 = Infinity
-" -9\n" + 5 = " -9\n5"
-" -9\n" - 5 = -14
-null + 1 = 1 // (3)
-undefined + 1 = NaN // (4)
+" -9 " + 5 = " -9 5" // (3)
+" -9 " - 5 = -14 // (4)
+null + 1 = 1 // (5)
+undefined + 1 = NaN // (6)
```
+<<<<<<< HEAD
1. 字符串的加法 `"" + 1` 会将 `1` 转换为一个字符串:`"" + 1 = "1"`,然后我们得到了 `"1" + 0`,再次应用同样的规则。
2. 减法 `-` (就像大多数数学操作那样)只能用于数字,它会将空字符串 `""` 转换为 `0`。
3. `null` 经过数字化转换之后会变为 `0`。
4. `undefined` 经过数字化转换之后会变为 `NaN`。
+=======
+1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied.
+2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`.
+3. The addition with a string appends the number `5` to the string.
+4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it).
+5. `null` becomes `0` after the numeric conversion.
+6. `undefined` becomes `NaN` after the numeric conversion.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md b/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md
index a44227ce4f..a14e966630 100644
--- a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md
+++ b/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md
@@ -17,8 +17,8 @@ true + false
"4" - 2
"4px" - 2
7 / 0
-" -9\n" + 5
-" -9\n" - 5
+" -9 " + 5
+" -9 " - 5
null + 1
undefined + 1
```
diff --git a/1-js/02-first-steps/06-type-conversions/article.md b/1-js/02-first-steps/06-type-conversions/article.md
index cf4b446a3d..5c5a7c1f24 100644
--- a/1-js/02-first-steps/06-type-conversions/article.md
+++ b/1-js/02-first-steps/06-type-conversions/article.md
@@ -1,13 +1,24 @@
# 类型转换
+<<<<<<< HEAD
大多数情况下,运算符和函数会自动转换将值转换为正确的类型。称之为“类型转换”。
+=======
+Most of the time, operators and functions automatically convert the values given to them to the right type.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
比如,`alert` 会自动将任何值转换为字符串。算术运算符会将值转换为数字。
+<<<<<<< HEAD
还有些例子,需要显式进行类型转换,以得到正确的结果。
```smart header="对象还未纳入讨论中"
本章并不会讨论 object 类型。先学习原始类型,之后我们会学习 object 类型。对象的类型转换在章节 介绍。
+=======
+There are also cases when we need to explicitly convert a value to the expected type.
+
+```smart header="Not talking about objects yet"
+In this chapter, we won't cover objects. Instead, we'll study primitives first. Later, after we learn about objects, we'll see how object conversion works in the chapter .
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## ToString
@@ -16,7 +27,11 @@
比如,`alert(value)` 将 `value` 转换为 string 类型,然后显示这个值。
+<<<<<<< HEAD
也可以显式地调用 `String(value)` 来达到这一目的:
+=======
+We can also call the `String(value)` function to convert a value to a string:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let value = true;
@@ -28,7 +43,11 @@ alert(typeof value); // string
*/!*
```
+<<<<<<< HEAD
转换为 string 类型的值往往是可预见的。`false` 变成 `"false"`,`null` 变成 `"null"` 等。
+=======
+String conversion is mostly obvious. A `false` becomes `"false"`, `null` becomes `"null"`, etc.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## ToNumber
@@ -40,7 +59,11 @@ alert(typeof value); // string
alert( "6" / "2" ); // 3, strings are converted to numbers
```
+<<<<<<< HEAD
也可以使用 `Number(value)` 显式地将这个值转换为 number 类型。
+=======
+We can use the `Number(value)` function to explicitly convert a `value` to a number:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let str = "123";
@@ -51,9 +74,15 @@ let num = Number(str); // 变成 number 类型 123
alert(typeof num); // number
```
+<<<<<<< HEAD
当从 string 类型源读取值时,比如一个文本表单,但是我们期待数字输入,就经常进行显式转换。
如果字符串不是一个有效的数字,转换的结果会是 `NaN`,例如:
+=======
+Explicit conversion is usually required when we read a value from a string-based source like a text form but expect a number to be entered.
+
+If the string is not a valid number, the result of such a conversion is `NaN`. For instance:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let age = Number("an arbitrary string instead of a number");
@@ -67,8 +96,13 @@ number 类型转换规则:
|-------|-------------|
|`undefined`|`NaN`|
|`null`|`0`|
+<<<<<<< HEAD
|true 和 false | `1` and `0` |
| `string` | 字符串开始和末尾的空白会被移除,剩下的如果是空字符串,结果为 `0`,否则 —— 从字符串中读出数字。错误返回 `NaN`。 |
+=======
+|true and false | `1` and `0` |
+| `string` | Whitespaces from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. |
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -79,31 +113,53 @@ alert( Number(true) ); // 1
alert( Number(false) ); // 0
```
+<<<<<<< HEAD
请注意 `null` 和 `undefined` 有点不同。`null` 变成数字 `0`,`undefined` 变成 `NaN`。
````smart header="加号'+' 连接字符串"
几乎所有的算术运算符都将值转换为数字,加号 `+` 是个例外。如果其中一个运算元是字符串,则另一个也会转换为字符串。
然后,连接两者:
+=======
+Please note that `null` and `undefined` behave differently here: `null` becomes zero while `undefined` becomes `NaN`.
+
+````smart header="Addition '+' concatenates strings"
+Almost all mathematical operations convert values to numbers. A notable exception is addition `+`. If one of the added values is a string, the other one is also converted to a string.
+
+Then, it concatenates (joins) them:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( 1 + '2' ); // '12' (字符串在加号右边)
alert( '1' + 2 ); // '12' (字符串在加号左边)
```
+<<<<<<< HEAD
这仅仅发生在其中一方为字符串(译者注:或者双方都为字符串)的情况下。其他情况下会被转换为数字。
+=======
+This only happens when at least one of the arguments is a string. Otherwise, values are converted to numbers.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
## ToBoolean
转换为 boolean 类型是最为简单的一个。
+<<<<<<< HEAD
逻辑操作或显式调用 `Boolean(value)` 会触发 boolean 类型转换。
+=======
+It happens in logical operations (later we'll meet condition tests and other similar things) but can also be performed explicitly with a call to `Boolean(value)`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
转换规则如下:
+<<<<<<< HEAD
- 假值,比如 `0`、空的字符串、`null`、`undefined` 和 `NaN` 变成 `false`。
- 其他值变成 `true`。
+=======
+- Values that are intuitively "empty", like `0`, an empty string, `null`, `undefined`, and `NaN`, become `false`.
+- Other values become `true`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
比如:
@@ -115,8 +171,13 @@ alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
```
+<<<<<<< HEAD
````warn header="请注意: 包含 0 的字符串 `\"0\"` 是 `true`"
一些编程语言(比如 PHP)视 `"0"` 为 `false`。但在 JavaScript 中,非空的字符串总是 `true`。
+=======
+````warn header="Please note: the string with zero `\"0\"` is `true`"
+Some languages (namely PHP) treat `"0"` as `false`. But in JavaScript, a non-empty string is always `true`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( Boolean("0") ); // true
@@ -127,11 +188,19 @@ alert( Boolean(" ") ); // 空白, 也是 true (任何非空字符串是 true)
## 总结
+<<<<<<< HEAD
有三种常用的类型转换:转换为 string 类型、转换为 number 类型和转换为 boolean 类型。
**`ToString`** —— 输出内容时 `ToString` 发生转换,或通过 `String(value)` 进行显式转换。原始类型值的 string 类型转换通常是可预见的。
**`ToNumber`** -- 进行算术操作时发生 `ToNumber` 转换,或通过 `Number(value)` 进行显式转换。
+=======
+The three most widely used type conversions are to string, to number, and to boolean.
+
+**`ToString`** -- Occurs when we output something. Can be performed with `String(value)`. The conversion to string is usually obvious for primitive values.
+
+**`ToNumber`** -- Occurs in math operations. Can be performed with `Number(value)`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`ToNumber` 转换遵循以下规则:
@@ -142,7 +211,11 @@ alert( Boolean(" ") ); // 空白, 也是 true (任何非空字符串是 true)
|true / false | `1 / 0` |
| `string` | 字符串“按原样读取”,两端的空白被忽略。空字符串变成 `0`。出错变成 `NaN`。 |
+<<<<<<< HEAD
**`ToBoolean`** -- 进行逻辑操作时发生 `ToBoolean` 转换。或通过 `Boolean(value)` 进行显式转换。
+=======
+**`ToBoolean`** -- Occurs in logical operations. Can be performed with `Boolean(value)`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`ToBoolean` 遵循以下规则:
@@ -157,4 +230,8 @@ alert( Boolean(" ") ); // 空白, 也是 true (任何非空字符串是 true)
- `undefined` 进行 `ToNumber` 时变成 `NaN`,而非 `0`。
- `"0"` 和只有空格的字符串(比如:`" "` )在进行 `ToBoolean` 变成 `true`。
+<<<<<<< HEAD
对象的转换并未在此提及,我们会在章节 介绍,随后我们会学习 JavaScript 更多基础的细节。
+=======
+Objects aren't covered here. We'll return to them later in the chapter that is devoted exclusively to objects after we learn more basic things about JavaScript.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/07-operators/article.md b/1-js/02-first-steps/07-operators/article.md
index 9520a857f3..753f385aea 100644
--- a/1-js/02-first-steps/07-operators/article.md
+++ b/1-js/02-first-steps/07-operators/article.md
@@ -1,15 +1,28 @@
# 运算符
+<<<<<<< HEAD
从入学开始,我们就熟悉许多运算符,比如说加号 `+`、乘号 `*`、减号 `-` 等。
这个章节,我们将关注一些在学校数学课程中没有涵盖的运算符。
+=======
+We know many operators from school. They are things like addition `+`, multiplication `*`, subtraction `-`, and so on.
+
+In this chapter, we'll concentrate on aspects of operators that are not covered by school arithmetic.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 术语:「一元运算符」、「二元运算符」、「运算元」
+<<<<<<< HEAD
首先,我们简单浏览一下常用术语。
- **运算元** —— 运算符应用的对象。比如说乘法运算 `5 * 2`,有两个运算元:左运算元 `5` 和右运算元 `2`。有时候人们也称其为「参数」。
- 如果一个运算符对应的只有一个运算元,那么它是 **一元运算符**。比如说一元运算符 `-`,它的作用是对数字取反:
+=======
+Before we move on, let's grasp some common terminology.
+
+- *An operand* -- is what operators are applied to. For instance, in the multiplication of `5 * 2` there are two operands: the left operand is `5` and the right operand is `2`. Sometimes, people call these "arguments" instead of "operands".
+- An operator is *unary* if it has a single operand. For example, the unary negation `-` reverses the sign of a number:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let x = 1;
@@ -19,13 +32,18 @@
*/!*
alert( x ); // -1,一元负号运算符生效
```
+<<<<<<< HEAD
- 如果一个运算符拥有两个运算元,那么它是 **二元运算符**。减号还存在二元运算符形式:
+=======
+- An operator is *binary* if it has two operands. The same minus exists in binary form as well:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
let x = 1, y = 3;
alert( y - x ); // 2,二元运算符减号做减运算
```
+<<<<<<< HEAD
正式说明:我们正在讨论两种不同的运算符:一元负号运算符(单一运算元,改变正负号)和二元运算符减号(两个运算元,做减法)。
## 字符串连接功能,二元运算符 +
@@ -35,13 +53,28 @@
通常,加号 `+` 用来求和。
但是如果加号 `+` 应用于字符串,它将合并(连接)各个字符串:
+=======
+ Formally, we're talking about two different operators here: the unary negation (single operand: reverses the sign) and the binary subtraction (two operands: subtracts).
+
+## String concatenation, binary +
+
+Now, let's see special features of JavaScript operators that are beyond school arithmetics.
+
+Usually, the plus operator `+` sums numbers.
+
+But, if the binary `+` is applied to strings, it merges (concatenates) them:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let s = "my" + "string";
alert(s); // mystring
```
+<<<<<<< HEAD
注意:只要任一运算元是字符串,那么其它运算元也将转化为字符串。
+=======
+Note that if one of the operands is a string, the other one is converted to a string too.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -50,7 +83,11 @@ alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
```
+<<<<<<< HEAD
可以看出,字符串在前和在后并不影响这个规则。简单来说:如果任一运算元是字符串,那么其它运算元将被转化为字符串。
+=======
+See, it doesn't matter whether the first operand is a string or the second one. The rule is simple: if either operand is a string, the other one is converted into a string as well.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
但是,请注意:运算符的运算方向是由左至右。如果是两个数字,后面再跟一个字符串,那么两个数字会先相加,再转化为字符串:
@@ -59,7 +96,11 @@ alert( 2 + '1' ); // "21"
alert(2 + 2 + '1' ); // "41" 而不是 "221"
```
+<<<<<<< HEAD
字符串连接和转化是加号 `+` 的一个特性。其它的数学运算符都只对数字有效。通常,他们会转化运算元为数字。
+=======
+String concatenation and conversion is a special feature of the binary plus `+`. Other arithmetic operators work only with numbers and always convert their operands to numbers.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:减号和除号:
@@ -70,9 +111,15 @@ alert( '6' / '2' ); // 3
## 数字转化功能,一元运算符 +
+<<<<<<< HEAD
加号 `+` 有两种形式。一种是以上讨论的二元运算符,还有一种是一元运算符。
一元运算符加号,或者说,加号 `+` 应用于单个值,对数字没有作用。但是如果运算元是非数字,它会将其转化为数字。
+=======
+The plus `+` exists in two forms: the binary form that we used above and the unary form.
+
+The unary plus or, in other words, the plus operator `+` applied to a single value, doesn't do anything to numbers. But if the operand is not a number, the unary plus converts it into a number.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
比如:
@@ -91,9 +138,15 @@ alert( +"" ); // 0
*/!*
```
+<<<<<<< HEAD
它的效果和 `Number(...)` 相同,但是更加简短。
将字符串转化为数字的需求经常出现。比如,如果我们正在从 HTML 表单中取值,通常得到的都是字符串。
+=======
+It actually does the same thing as `Number(...)`, but is shorter.
+
+The need to convert strings to numbers arises very often. For example, if we are getting values from HTML form fields, they are usually strings.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如果我们想对他们求和,该怎么办?
@@ -106,7 +159,11 @@ let oranges = "3";
alert( apples + oranges ); // "23",二元运算符连接成字符串
```
+<<<<<<< HEAD
如果我们想把它们当做数字对待,我们需要转化它们,然后再求和:
+=======
+If we want to treat them as numbers, we need to convert and then sum them:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let apples = "2";
@@ -121,6 +178,7 @@ alert( +apples + +oranges ); // 5
// alert( Number(apples) + Number(oranges) ); // 5
```
+<<<<<<< HEAD
从一个数学家的视角来看,大量的加号可能很奇怪。但是从一个程序员的视角,没什么好奇怪的:一元运算符首先起作用,他们将字符串转为数字,然后二元运算符加号对它们求和。
为什么一元运算符先于二元运算符作用于运算元?接下去我们将讨论到,这是由于它们拥有更高的 **优先级**。
@@ -136,6 +194,23 @@ alert( +apples + +oranges ); // 5
在 JavaScript 中有众多运算符。每个运算符都有对应的优先级数字。数字越大,越先执行。如果优先级相同,那么执行顺序由左至右。
摘抄自 [优先级表](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) (你不必记住它,只要知道一元运算符优先级高于二元运算符):
+=======
+From a mathematician's standpoint, the abundance of pluses may seem strange. But from a programmer's standpoint, there's nothing special: unary pluses are applied first, they convert strings to numbers, and then the binary plus sums them up.
+
+Why are unary pluses applied to values before the binary ones? As we're going to see, that's because of their *higher precedence*.
+
+## Operator precedence
+
+If an expression has more than one operator, the execution order is defined by their *precedence*, or, in other words, the implicit priority order of operators.
+
+From school, we all know that the multiplication in the expression `1 + 2 * 2` should be calculated before the addition. That's exactly the precedence thing. The multiplication is said to have *a higher precedence* than the addition.
+
+Parentheses override any precedence, so if we're not satisfied with the implicit order, we can use them to change it. For example: `(1 + 2) * 2`.
+
+There are many operators in JavaScript. Every operator has a corresponding precedence number. The one with the larger number executes first. If the precedence is the same, the execution order is from left to right.
+
+Here's an extract from the [precedence table](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones):
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
| Precedence | Name | Sign |
|------------|------|------|
@@ -150,13 +225,21 @@ alert( +apples + +oranges ); // 5
| 3 | assignment | `=` |
| ... | ... | ... |
+<<<<<<< HEAD
我们可以看到,「一元运算符 加号」 拥有优先级 `16`,高于「二元运算符 加法」的优先级 `13`。这也是为什么表达式 `"+apples + +oranges"` 一元加号先生效,然后才是二元加法。
+=======
+As we can see, the "unary plus" has a priority of `16` which is higher than the `13` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 赋值运算符
我们知道赋值符号 `=` 也是一个运算符。在优先级表中显示它的优先级非常低,只有 `3`。
+<<<<<<< HEAD
这也是为什么,当我们赋值时,比如 `x = 2 * 2 + 1`,所有的计算先执行,然后 `=` 执行,将计算结果存储到 `x`。
+=======
+That's why, when we assign a variable, like `x = 2 * 2 + 1`, the calculations are done first and then the `=` is evaluated, storing the result in `x`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let x = 2 * 2 + 1;
@@ -178,14 +261,25 @@ alert( b ); // 4
alert( c ); // 4
```
+<<<<<<< HEAD
链式赋值由右到左执行。首先最右侧表达式 `2 + 2` 执行,然后将结果赋值给左侧:`c`、`b`、`a`。最后,所有的变量都共享一个值。
````smart header="赋值运算符 `\"=\"` 返回一个值"
每个运算符都有一个返回值。对于以加号 `+` 或者乘号 `*` 为例的大部分运算符而言,这一点很显然。对于赋值运算符而言,这一点同样适用。
+=======
+Chained assignments evaluate from right to left. First, the rightmost expression `2 + 2` is evaluated and then assigned to the variables on the left: `c`, `b` and `a`. At the end, all the variables share a single value.
+
+````smart header="The assignment operator `\"=\"` returns a value"
+An operator always returns a value. That's obvious for most of them like addition `+` or multiplication `*`. But the assignment operator follows this rule too.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
语句 `x = value` 把 `value` 的值写入 `x` *然后返回 x*。
+<<<<<<< HEAD
下面是一个在复杂语句中使用赋值的例子:
+=======
+Here's a demo that uses an assignment as part of a more complex expression:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let a = 1;
@@ -201,12 +295,20 @@ alert( c ); // 0
以上这个例子,`(a = b + 1)` 的结果是赋值给 `a` 的值(即是 3)。然后该值用于与 `3` 相减。
+<<<<<<< HEAD
有趣的代码,不是吗?我们应该理解它的原理,因为我们有时会在第三方库中见到这样的写法,我们自己不应该这样写。这样的小技巧让代码变得不整洁,阅读性也变差。
+=======
+Funny code, isn't it? We should understand how it works, because sometimes we see it in 3rd-party libraries, but shouldn't write anything like that ourselves. Such tricks definitely don't make code clearer or readable.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
## 求余运算符 %
+<<<<<<< HEAD
运算符 `%` 尽管看上去是个百分号,但和百分数没有什么关系。
+=======
+The remainder operator `%`, despite its appearance, is not related to percents.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`a % b` 的结果是 `a` 除以 `b` 的余数。
@@ -232,7 +334,13 @@ alert( 2 ** 3 ); // 8 (2 * 2 * 2)
alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2)
```
+<<<<<<< HEAD
这个运算符对于 `a` 和 `b` 是非整数的情况依然适用,举个例子:
+=======
+The operator works for non-integer numbers as well.
+
+For instance:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( 4 ** (1/2) ); // 2 (1 / 2 幂相当于开方,这是数学常识)
@@ -245,7 +353,11 @@ alert( 8 ** (1/3) ); // 2 (1 / 3 幂相当于开三次方)
对一个数进行加操作或者减操作是最常见的数值运算符。
+<<<<<<< HEAD
因此,围绕着它们,有一些特殊的运算符:
+=======
+So, there are special operators for it:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- **自相加** `++` 将变量与1相加:
@@ -263,6 +375,7 @@ alert( 8 ** (1/3) ); // 2 (1 / 3 幂相当于开三次方)
```
```warn
+<<<<<<< HEAD
自相加/自相减只能应用于变量。尝试将其应用于数值(比如 `5++`)会报错。
```
@@ -272,12 +385,29 @@ alert( 8 ** (1/3) ); // 2 (1 / 3 幂相当于开三次方)
- 当运算符在变量前,被称为「前置形式」:`++counter`。
两者都做同一件事:将变量 `counter` 与 `1` 相加。
+=======
+Increment/decrement can only be applied to variables. Trying to use it on a value like `5++` will give an error.
+```
+
+The operators `++` and `--` can be placed either before or after a variable.
+
+- When the operator goes after the variable, it is in "postfix form": `counter++`.
+- The "prefix form" is when the operator goes before the variable: `++counter`.
+
+Both of these statements do the same thing: increase `counter` by `1`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
那么,有什么区别呢?有,但只有当我们需要 `++/--` 的返回值时才能看到区别。
+<<<<<<< HEAD
让我们来明确这一点。我们知道,所有的运算符都有返回值。自相加/自相减也不例外。前置形式返回一个新的值,但后置返回原来的值(做加法/减法之前的值)。
为了直观看到区别,看下面的例子:
+=======
+Let's clarify. As we know, all operators return a value. Increment/decrement is no exception. The prefix form returns the new value while the postfix form returns the old value (prior to increment/decrement).
+
+To see the difference, here's an example:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let counter = 1;
@@ -286,9 +416,15 @@ let a = ++counter; // (*)
alert(a); // *!*2*/!*
```
+<<<<<<< HEAD
`(*)` 所在的行是前置形式 `++counter`,对 `counter` 做自相加,返回的是新的值 `2`。因此 `alert` 显示的是 `2`。
下面让我们看看后置形式:
+=======
+In the line `(*)`, the *prefix* form `++counter` increments `counter` and returns the new value, `2`. So, the `alert` shows `2`.
+
+Now, let's use the postfix form:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let counter = 1;
@@ -297,11 +433,19 @@ let a = counter++; // (*) 将 ++counter 改为 counter++
alert(a); // *!*1*/!*
```
+<<<<<<< HEAD
`(*)` 所在的行是后置形式 `counter++`,它同样对 `counter` 做加法,但是返回的是**旧值**(做加法之前)。因此 `alert` 显示的是 `1`。
+=======
+In the line `(*)`, the *postfix* form `counter++` also increments `counter` but returns the *old* value (prior to increment). So, the `alert` shows `1`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
总结:
+<<<<<<< HEAD
- 如果自相加/自相减的值不会被使用,那么两者形式没有区别:
+=======
+- If the result of increment/decrement is not used, there is no difference in which form to use:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let counter = 0;
@@ -309,21 +453,34 @@ alert(a); // *!*1*/!*
++counter;
alert( counter ); // 2,以上两行作用相同
```
+<<<<<<< HEAD
- 如果我们想要对变量自相加 **并且** 立刻使用值,那么我们需要使用前置形式:
+=======
+- If we'd like to increase a value *and* immediately use the result of the operator, we need the prefix form:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let counter = 0;
alert( ++counter ); // 1
```
+<<<<<<< HEAD
- 如果我们想要使用之前的值,那么我们需要使用后置形式:
+=======
+- If we'd like to increment a value but use its previous value, we need the postfix form:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let counter = 0;
alert( counter++ ); // 0
```
+<<<<<<< HEAD
````smart header="自相加/自相减和其它运算符的对比"
`++/--` 运算符同样可以在表达式内部使用。它们的优先级比绝大部分的运算符要高。
+=======
+````smart header="Increment/decrement among other operators"
+The operators `++/--` can be used inside expressions as well. Their precedence is higher than most other arithmetical operations.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -339,11 +496,19 @@ let counter = 1;
alert( 2 * counter++ ); // 2,因为 counter++ 返回的是「旧值」
```
+<<<<<<< HEAD
尽管从技术层面上来说可行,但是这样的写法会减少代码的可阅读性。在一行上做多个操作 —— 这样并不好。
当阅读代码时,快速的视觉「纵向」扫描会很容易漏掉 `counter++`,知道那个变量自相加并不简单。
「一行一个操作」模式是更好的选择:
+=======
+Though technically okay, such notation usually makes code less readable. One line does multiple things -- not good.
+
+While reading code, a fast "vertical" eye-scan can easily miss something like `counter++` and it won't be obvious that the variable increased.
+
+We advise a style of "one line -- one action":
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let counter = 1;
@@ -368,11 +533,19 @@ counter++;
- 右移 ( `>>` )
- 无符号右移 ( `>>>` )
+<<<<<<< HEAD
这些操作使用得非常少。为了理解它们,我们需要探讨底层的数字表达形式,现在不是做这个的最好时机。尤其是我们现在不会立刻使用它。如果你感兴趣,可以阅读 MDN 中的[位运算符](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators)相关文章。当有实际需求出现的时候再去阅读是更明智的选择。
+=======
+These operators are used very rarely. To understand them, we need to delve into low-level number representation and it would not be optimal to do that right now, especially since we won't need them any time soon. If you're curious, you can read the [Bitwise Operators](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) article on MDN. It would be more practical to do that when a real need arises.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 修改并替换
+<<<<<<< HEAD
我们经常需要对一个变量进行操作,然后把新的结果存储给变量。
+=======
+We often need to apply an operator to a variable and store the new result in that same variable.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -382,7 +555,11 @@ n = n + 5;
n = n * 2;
```
+<<<<<<< HEAD
这个操作可以使用运算符 `+=` 和 `*=` 来简化:
+=======
+This notation can be shortened using the operators `+=` and `*=`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let n = 2;
@@ -392,7 +569,11 @@ n *= 2; // now n = 14 (同n = n * 2)
alert( n ); // 14
```
+<<<<<<< HEAD
简短的「修改并替换」 运算符对所有的运算符都有效,以及位运算符:`/=`、`-=`等等。
+=======
+Short "modify-and-assign" operators exist for all arithmetical and bitwise operators: `/=`, `-=`, etc.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这些运算符和正常的赋值运算符拥有相同的优先级,因此它们会在其它运算之后运行:
@@ -406,9 +587,15 @@ alert( n ); // 16 (右侧计算首先进行,和 n *= 8 相同)
## 逗号运算符
+<<<<<<< HEAD
逗号运算符 `,` 是最少见最不常使用的运算符之一。有时候它会被用来写更简短的代码,因此为了能够理解代码,我们需要了解它。
逗号运算符能让我们处理多个语句,使用 `,` 将它们分开。每个语句都运行了,但是只有最后的语句结果会被返回。
+=======
+The comma operator `,` is one of the rarest and most unusual operators. Sometimes, it's used to write shorter code, so we need to know it in order to understand what's going on.
+
+The comma operator allows us to evaluate several expressions, dividing them with a comma `,`. Each of them is evaluated but only the result of the last one is returned.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -420,17 +607,30 @@ let a = (1 + 2, 3 + 4);
alert( a ); // 7 (3 + 4 的结果)
```
+<<<<<<< HEAD
这里,第一个语句 `1 + 2` 运行了,但是它的结果被丢弃了,然后 `3 + 4` 运行,计算结果被返回。
+=======
+Here, the first expression `1 + 2` is evaluated and its result is thrown away. Then, `3 + 4` is evaluated and returned as the result.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```smart header="逗号运算符的优先级非常低"
请注意逗号运算符的优先级非常低,比 `=` 还要低,因此上面你的例子中圆括号非常重要。
+<<<<<<< HEAD
如果没有圆括号:`a = 1 + 2, 3 + 4` 会先执行 `+`,将数值相加得到 `a = 3, 7`,然后赋值运算符 `=` 执行, 'a = 3',然后逗号之后的数值 `7` 不会再执行,它被忽略掉了。
```
为什么我们需要这样一个运算符,它只返回最后一个值呢?
有时候,人们会使用它把几个操作放在一行上来进行复杂的运算。
+=======
+Without them: `a = 1 + 2, 3 + 4` evaluates `+` first, summing the numbers into `a = 3, 7`, then the assignment operator `=` assigns `a = 3`, and finally the number after the comma, `7`, is not processed so it's ignored.
+```
+
+Why do we need an operator that throws away everything except the last part?
+
+Sometimes, people use it in more complex constructs to put several actions in one line.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -441,4 +641,8 @@ for (*!*a = 1, b = 3, c = a * b*/!*; a < 10; a++) {
}
```
+<<<<<<< HEAD
这样的技巧在许多 JavaScript 框架中都有使用,这也是为什么我们提到它。但是通常它并不能提升代码的可阅读性,使用它之前,我们要想清楚。
+=======
+Such tricks are used in many JavaScript frameworks. That's why we're mentioning them. But, usually, they don't improve code readability so we should think well before using them.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/task.md b/1-js/02-first-steps/08-comparison/1-comparison-questions/task.md
index 2c4446fefe..1f95ca14fa 100644
--- a/1-js/02-first-steps/08-comparison/1-comparison-questions/task.md
+++ b/1-js/02-first-steps/08-comparison/1-comparison-questions/task.md
@@ -4,7 +4,11 @@ importance: 5
# 值的比较
+<<<<<<< HEAD
以下表达式的执行结果是?
+=======
+What will be the result for these expressions?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js no-beautify
5 > 4
diff --git a/1-js/02-first-steps/08-comparison/article.md b/1-js/02-first-steps/08-comparison/article.md
index 9389c1e450..2c29682560 100644
--- a/1-js/02-first-steps/08-comparison/article.md
+++ b/1-js/02-first-steps/08-comparison/article.md
@@ -1,18 +1,34 @@
# 值的比较
+<<<<<<< HEAD
在 JavaScript 中,我们可以使用一些熟知的数学符号进行值的比较:
- 大于 / 小于:a > b,a < b。
- 大于等于 / 小于等于:a >= b,a <= b。
- 检测两个值的相等写为 `a == b`(注意表达式中是两个等号 `=`,若写为单个等号 `a = b` 则表示赋值)。
- 检测两个值的不等,在数学中使用 ≠ 符号,而在 JavaScript 中则通过在赋值符号前增加叹号表示:a != b。
+=======
+We know many comparison operators from maths:
+
+- Greater/less than: a > b, a < b.
+- Greater/less than or equals: a >= b, a <= b.
+- Equals: `a == b` (please note the double equals sign `=`. A single symbol `a = b` would mean an assignment).
+- Not equals. In maths the notation is ≠, but in JavaScript it's written as an assignment with an exclamation sign before it: a != b.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 比较结果为 Boolean 类型
+<<<<<<< HEAD
和其他操作符一样,比较操作符也会有返回值,其类型为布尔值(Boolean)。
- `true` —— 表示“yes(是)”,“correct(正确)”或“the truth(真理)”。
- `false` —— 表示“no(否)”,“wrong(错误)”或“a lie(谎言)”。
+=======
+Like all other operators, a comparison returns a value. In this case, the value is a boolean.
+
+- `true` -- means "yes", "correct" or "the truth".
+- `false` -- means "no", "wrong" or "not the truth".
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
示例:
@@ -31,7 +47,11 @@ alert( result ); // true
## 字符串间的比较
+<<<<<<< HEAD
在比较字符串的大小时,会使用“字典”或“词典”顺序进行判定。
+=======
+To see whether a string is greater than another, JavaScript uses the so-called "dictionary" or "lexicographical" order.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
换言之,字符串是按字符(母)逐个进行比较的。
@@ -45,6 +65,7 @@ alert( 'Bee' > 'Be' ); // true
字符串间的比较算法非常简单:
+<<<<<<< HEAD
1. 首先比较两个字符串的首位字符大小。
2. 如果一方字符较大(或较小),则该字符串大于(或小于)另一个字符串。算法结束。
3. 否则,两个字符串中的字符相等,继续取出各自的后一位字符进行比较。
@@ -54,20 +75,40 @@ alert( 'Bee' > 'Be' ); // true
在上面的例子中,`'Z' > 'A'` 在算法的第 1 步就得到了返回结果。
字符串 `"Glow"` 和 `"Glee"` 会按字符逐个进行比较:
+=======
+1. Compare the first character of both strings.
+2. If the first character from the first string is greater (or less) than the other string's, then the first string is greater (or less) than the second. We're done.
+3. Otherwise, if both strings' first characters are the same, compare the second characters the same way.
+4. Repeat until the end of either string.
+5. If both strings end at the same length, then they are equal. Otherwise, the longer string is greater.
+
+In the examples above, the comparison `'Z' > 'A'` gets to a result at the first step while the strings `"Glow"` and `"Glee"` are compared character-by-character:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
1. `G` 和 `G` 相等。
2. `l` 和 `l` 相等。
3. `o` 比 `e` 大,算法停止,第一个字符串大于第二个。
+<<<<<<< HEAD
```smart header="非真正的字典顺序,而是 Unicode 编码顺序"
在上面的算法中,比较大小的逻辑与字典或电话簿中的排序很像,但也不完全相同。
比如说,算法中的比较对大小写是敏感的。大写的 `"A"` 并不等于小写的 `"a"`。哪一个更大呢?实际上小写的 `"a"` 更大。至于原因嘛,这是因为在内部的编码表中(Unicode),小写字母的字符索引更大。我们会在 这章讨论更多关于字符串的细节。
+=======
+```smart header="Not a real dictionary, but Unicode order"
+The comparison algorithm given above is roughly equivalent to the one used in dictionaries or phone books, but it's not exactly the same.
+
+For instance, case matters. A capital letter `"A"` is not equal to the lowercase `"a"`. Which one is greater? The lowercase `"a"`. Why? Because the lowercase character has a greater index in the internal encoding table JavaScript uses (Unicode). We'll get back to specific details and consequences of this in the chapter .
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 不同类型间的比较
+<<<<<<< HEAD
当不同类型的值进行比较时,它们会首先被转为数字(number)再判定大小。
+=======
+When comparing values of different types, JavaScript converts the values to numbers.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
示例:
@@ -76,7 +117,13 @@ alert( '2' > 1 ); // true,字符串 '2' 会被转为数字 2
alert( '01' == 1 ); // true,字符串 '01' 会被转为数字 1
```
+<<<<<<< HEAD
对于布尔类型,`true` 会被转为 `1`、`false` 转为 `0`,即有:
+=======
+For boolean values, `true` becomes `1` and `false` becomes `0`.
+
+For example:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( true == 1 ); // true
@@ -101,24 +148,40 @@ alert( Boolean(b) ); // true
alert(a == b); // true!
```
+<<<<<<< HEAD
对于 JavaScript 而言这种现象蛮正常的,因为它会把待比较的值转为数字后再做比较(因此 `"0"` 变成了 `0` )。若只是将一个变量转为 `Boolean`,则会使用其他的类型转换规则。
+=======
+From JavaScript's standpoint, this result is quite normal. An equality check converts values using the numeric conversion (hence `"0"` becomes `0`), while the explicit `Boolean` conversion uses another set of rules.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
## 严格相等
+<<<<<<< HEAD
普通的相等性检查 `==` 存在一个问题,它不能区分出 `0` 和 `false`:
+=======
+A regular equality check `==` has a problem. It cannot differentiate `0` from `false`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( 0 == false ); // true
```
+<<<<<<< HEAD
也同样无法区分空字符串和 `false`:
+=======
+The same thing happens with an empty string:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( '' == false ); // true
```
+<<<<<<< HEAD
这是因为在比较不同类型的值时,处于相等判断符号 `==` 两侧的值会被转换为数字的原因。空字符串和 `false` 也是如此,转换后它们都等于 0。
+=======
+This happens because operands of different types are converted to numbers by the equality operator `==`. An empty string, just like `false`, becomes a zero.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如果我们需要区分 `0` 和 `false`,该怎么做呢?
@@ -132,19 +195,33 @@ alert( '' == false ); // true
alert( 0 === false ); // false,比较不同类型的值
```
+<<<<<<< HEAD
同样的,与“不相等”符号 `!=` 类似,“严格不相等”表示为 `!==`。
严格相等的操作符虽然略为冗长,但是它很清楚地显示了比较的意图,降低你犯错的可能性。
+=======
+There is also a "strict non-equality" operator `!==` analogous to `!=`.
+
+The strict equality operator is a bit longer to write, but makes it obvious what's going on and leaves less room for errors.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 涉及 null 和 undefined 的比较
让我们看看更多的边缘案例。
+<<<<<<< HEAD
当使用 `null` 或 `undefined` 与其他值进行比较时,其返回结果常常出乎你的意料。
当使用严格相等 `===` 比较二者时:
它们是不相等的,因为它们属于不同的类型。
+=======
+There's a non-intuitive behavior when `null` or `undefined` are compared to other values.
+
+
+For a strict equality check `===`
+: These values are different, because each of them is a different type.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( null === undefined ); // false
@@ -157,10 +234,17 @@ JavaScript 存在一个专属的规则,会判定它们互等。而它们就像
alert( null == undefined ); // true
```
+<<<<<<< HEAD
当使用数学式或其他比较方法 `< > <= >=` 时:
`null/undefined` 的值会被转换为数字:`null` 转为 `0`,`undefined` 转为 `NaN`。
下面让我们看看,这些规则会带来什么有趣的现象。同时更重要的是,我们需要从中学会如何远离这些特性带来的“陷阱”。
+=======
+For maths and other comparisons `< > <= >=`
+: `null/undefined` are converted to numbers: `null` becomes `0`, while `undefined` becomes `NaN`.
+
+Now let's see some funny things that happen when we apply these rules. And, what's more important, how to not fall into a trap with them.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
### 奇怪的结果:null vs 0
@@ -172,15 +256,27 @@ alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) *!*true*/!*
```
+<<<<<<< HEAD
是的,上面的结果完全打破了你对数学的认识。在最后一行代码显示“`null` 大于等于 0”的情况下,前两行代码中一定会有一个是正确的,然而事实表明它们的结果都是 false。
为什么会出现这种反常结果,这是因为相等性检测 `==` 和普通比较符 `> < >= <=` 的代码逻辑是相互独立的。进行值的比较会把 `null` 转为数字,因此它被转为了 `0`。这就是为什么(3)中 `null >= 0` 返回 true,(1)中 `null > 0` 返回 false。
另一方面,`undefined` 和 `null` 在相等性检测 `==` 中不会进行任何的类型转换,它们有自己独立的比较规则,所以除了它们之间互等外不会等于任何其他的值。这就解释了为什么(2)中 `null == 0` 会返回 false。
+=======
+Mathematically, that's strange. The last result states that "`null` is greater than or equal to zero", so in one of the comparisons above it must be `true`, but they are both false.
+
+The reason is that an equality check `==` and comparisons `> < >= <=` work differently. Comparisons convert `null` to a number, treating it as `0`. That's why (3) `null >= 0` is true and (1) `null > 0` is false.
+
+On the other hand, the equality check `==` for `undefined` and `null` is defined such that, without any conversions, they equal each other and don't equal anything else. That's why (2) `null == 0` is false.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
### “拒不合作”的 undefined
+<<<<<<< HEAD
`undefined` 不应该参与任何值的比较:
+=======
+The value `undefined` shouldn't be compared to other values:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( undefined > 0 ); // false (1)
@@ -188,25 +284,50 @@ alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
```
+<<<<<<< HEAD
为何它看起来如此厌恶 0?无论怎么比较双方其结果总是返回 false!
原因如下:
- `(1)` 和 `(2)` 中返回 `false` 是因为 `undefined` 在比较中被转换为了 `NaN`,而 `NaN` 是一个特殊的数值型取值,它与任何值进行比较都会返回 `false`。
- `(3)` 中返回 `false` 是因为这是一个相等性检测,而 `undefined` 只与 `null` 相等。
+=======
+Why does it dislike zero so much? Always false!
+
+We get these results because:
+
+- Comparisons `(1)` and `(2)` return `false` because `undefined` gets converted to `NaN` and `NaN` is a special numeric value which returns `false` for all comparisons.
+- The equality check `(3)` returns `false` because `undefined` only equals `null`, `undefined`, and no other value.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
### 规避错误
+<<<<<<< HEAD
我们为何要研究以上示例?我们需要时刻记得这些古怪的规则吗?不,并不需要。虽然这些规则随着使用都会烂熟于胸,但是我们需要遵循更为可靠的方法来避免潜在的问题。
+=======
+Why did we go over these examples? Should we remember these peculiarities all the time? Well, not really. Actually, these tricky things will gradually become familiar over time, but there's a solid way to evade problems with them:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
除了严格相等 `===` 外,其他凡是有 `undefined/null` 参与的比较,我们都需要额外 “关照”。
+<<<<<<< HEAD
除非你非常清楚自己在做什么,否则永远不要使用 `>= > < <=` 去比较一个可能为 `null/undefined` 的变量。对于取值可能是 `null/undefined` 的变量,请按需要分别检查它的取值情况。
+=======
+Don't use comparisons `>= > < <=` with a variable which may be `null/undefined`, unless you're really sure of what you're doing. If a variable can have these values, check for them separately.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 小结
+<<<<<<< HEAD
- 比较操作符始终返回逻辑值。
- 字符串间按“词典”顺序逐字符比较大小。
- 当待比较的值类型不同时,它们会被转为数字(不包括严格相等检测)进行比较。
- 在非严格相等 `==` 下,`null` 和 `undefined` 相等且各自不等于任何其他的值。
- 在使用 `>` 或 `<` 进行比较时,需要注意变量可能为 `null/undefined` 的情况。比较好的方法是单独检查变量是否等于 `null/undefined`。
+=======
+- Comparison operators return a boolean value.
+- Strings are compared letter-by-letter in the "dictionary" order.
+- When values of different types are compared, they get converted to numbers (with the exclusion of a strict equality check).
+- The values `null` and `undefined` equal `==` each other and do not equal any other value.
+- Be careful when using comparisons like `>` or `<` with variables that can occasionally be `null/undefined`. Checking for `null/undefined` separately is a good idea.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/article.md b/1-js/02-first-steps/09-alert-prompt-confirm/article.md
index f2b4e3ff71..46a4bc3a86 100644
--- a/1-js/02-first-steps/09-alert-prompt-confirm/article.md
+++ b/1-js/02-first-steps/09-alert-prompt-confirm/article.md
@@ -1,8 +1,14 @@
# 交互:alert、prompt、confirm
+<<<<<<< HEAD
本部分旨在覆盖 JavaScript “原生”,而无需针对特定环境进行调整。
但我们仍然使用浏览器作为演示环境。所以我们至少应该知道一些用户界面函数。在本章节我们将会熟悉函数 `alert`、`prompt` 和 `confirm` 的用法。
+=======
+In this part of the tutorial we cover JavaScript language "as is", without environment-specific tweaks.
+
+But we'll still be using the browser as our demo environment, so we should know at least a few of its user-interface functions. In this chapter, we'll get familiar with the browser functions `alert`, `prompt` and `confirm`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## alert
@@ -12,7 +18,11 @@
alert(message);
```
+<<<<<<< HEAD
浏览器会弹出一段信息并暂停脚本,直到用户点击了“确定”。
+=======
+This shows a message and pauses script execution until the user presses "OK".
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -20,27 +30,48 @@ alert(message);
alert("Hello");
```
+<<<<<<< HEAD
这个小窗口被称为 **模态窗**。"modal" 意味着用户不能与页面的其他部分进行交互,点击其他按钮等,直到他们处理完窗口。在这种情况下 - 直到他们按下“确定”。
## prompt
`prompt` 函数接收两个参数:
+=======
+The mini-window with the message is called a *modal window*. The word "modal" means that the visitor can't interact with the rest of the page, press other buttons, etc. until they have dealt with the window. In this case -- until they press "OK".
+
+## prompt
+
+The function `prompt` accepts two arguments:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js no-beautify
-result = prompt(title[, default]);
+result = prompt(title, [default]);
```
+<<<<<<< HEAD
浏览器会显示一个带有文本消息的模态窗口,还有 input 框和确定/取消按钮。
`title`
: 显示给用户的文本
+=======
+It shows a modal window with a text message, an input field for the visitor, and the buttons OK/CANCEL.
+
+`title`
+: The text to show the visitor.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`default`
: 可选的第二个参数,指定 input 框的初始值。
+<<<<<<< HEAD
用户在 prompt 对话框的 input 框输入文本并点击确定。不然就点击取消按钮或敲击 `key:Esc` 键来取消。
`prompt` 返回输入的文本;如果取消输入就返回 `null`。
+=======
+The visitor may type something in the prompt input field and press OK. Or they can cancel the input by pressing CANCEL or hitting the `key:Esc` key.
+
+The call to `prompt` returns the text from the input field or `null` if the input was canceled.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -50,16 +81,27 @@ let age = prompt('How old are you?', 100);
alert(`You are ${age} years old!`); // You are 100 years old!
```
+<<<<<<< HEAD
````warn header="IE: always supply a `default`"
第二个参数可选。但是如果我们不提供的话,Internet Explorer 会把 `"undefined"` 插入到 prompt。
在 Internet Explorer 中运行将会看到:
+=======
+````warn header="In IE: always supply a `default`"
+The second parameter is optional, but if we don't supply it, Internet Explorer will insert the text `"undefined"` into the prompt.
+
+Run this code in Internet Explorer to see:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let test = prompt("Test");
```
+<<<<<<< HEAD
所以,在 IE 中看起来很好,建议始终提供第二个参数:
+=======
+So, for prompts to look good in IE, we recommend always providing the second argument:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let test = prompt("Test", ''); // <-- for IE
@@ -74,7 +116,11 @@ let test = prompt("Test", ''); // <-- for IE
result = confirm(question);
```
+<<<<<<< HEAD
`confirm` 函数显示一个带有 `question` 和两个按钮的模态窗口:确定和取消。
+=======
+The function `confirm` shows a modal window with a `question` and two buttons: OK and CANCEL.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
点击确定返回 `true`,点击取消返回 `false`。
@@ -88,22 +134,39 @@ alert( isBoss ); // true if OK is pressed
## 总结
+<<<<<<< HEAD
我们探讨了与用户交互的 3 个浏览器指定的函数:
+=======
+We covered 3 browser-specific functions to interact with visitors:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`alert`
: 显示信息。
`prompt`
+<<<<<<< HEAD
: 显示信息要求用户输入文本。点击确定返回文本,点击取消或按下 `key:Esc` 键返回 `null`。
+=======
+: shows a message asking the user to input text. It returns the text or, if CANCEL or `key:Esc` is clicked, `null`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`confirm`
: 显示信息等待用户点击确定或取消。点击确定返回 `true`,点击取消或 `key:Esc` 键返回 `false`。
+<<<<<<< HEAD
这些方法都是模态的:它们暂停脚本执行,并且不允许用户与该页面的其余部分交互,直到消息被解除。
+=======
+All these methods are modal: they pause script execution and don't allow the visitor to interact with the rest of the page until the window has been dismissed.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
上述所有方法共有两个限制:
+<<<<<<< HEAD
1. 模态窗口的确切位置由浏览器决定。通常在页面中心。
2. 窗口的确切外观还取决于浏览器。我们不能修改它。
+=======
+1. The exact location of the modal window is determined by the browser. Usually, it's in the center.
+2. The exact look of the window also depends on the browser. We can't modify it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这是简单的代价。还有其他一些方法可以显示更漂亮的窗口,并与用户进行更丰富的交互,但如果“花里胡哨”不是非常重要,这些方法也可以工作的很好。
diff --git a/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.png b/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.png
index 8c57b18850..04fb1fb0b7 100644
Binary files a/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.png and b/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2.png differ
diff --git a/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2@2x.png b/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2@2x.png
index cbb2c611a0..08226b7903 100644
Binary files a/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2@2x.png and b/1-js/02-first-steps/10-ifelse/2-check-standard/ifelse_task2@2x.png differ
diff --git a/1-js/02-first-steps/10-ifelse/4-check-login/ifelse_task.png b/1-js/02-first-steps/10-ifelse/4-check-login/ifelse_task.png
deleted file mode 100644
index 8b54dc83d5..0000000000
Binary files a/1-js/02-first-steps/10-ifelse/4-check-login/ifelse_task.png and /dev/null differ
diff --git a/1-js/02-first-steps/10-ifelse/4-check-login/ifelse_task@2x.png b/1-js/02-first-steps/10-ifelse/4-check-login/ifelse_task@2x.png
deleted file mode 100644
index 92001dfe86..0000000000
Binary files a/1-js/02-first-steps/10-ifelse/4-check-login/ifelse_task@2x.png and /dev/null differ
diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md
index 56f50e69d1..57fe3c3e85 100644
--- a/1-js/02-first-steps/10-ifelse/article.md
+++ b/1-js/02-first-steps/10-ifelse/article.md
@@ -1,12 +1,22 @@
# 条件运算符:if、'?'
+<<<<<<< HEAD
有时我们需要根据不同条件执行不同的操作。
`if` 语句可以解决这个问题,条件运算符(三元),简称为“问号”运算符也可以解决。
+=======
+Sometimes, we need to perform different actions based on different conditions.
+
+To do that, we can use the `if` statement and the conditional operator `?`, that's also called a "question mark" operator.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## "if" 语句
+<<<<<<< HEAD
`if` 语句获得一个条件,计算这个条件表达式,如果计算结果是 `true`,就会执行对应的代码。
+=======
+The `if` statement evaluates a condition and, if the condition's result is `true`, executes a block of code.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如下:
@@ -18,9 +28,15 @@ if (year == 2015) alert( 'You are right!' );
*/!*
```
+<<<<<<< HEAD
在上面的例子中,条件是一个简单的相等性检查:`year == 2015`,但它可能更复杂。
如果有多个语句要执行,我们必须将要执行的代码块封装在大括号内:
+=======
+In the example above, the condition is a simple equality check (`year == 2015`), but it can be much more complex.
+
+If we want to execute more than one statement, we have to wrap our code block inside curly braces:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
if (year == 2015) {
@@ -29,16 +45,29 @@ if (year == 2015) {
}
```
+<<<<<<< HEAD
建议每次使用 if 语句都用大括号 `{}` 来包装代码块,即使只有一条语句也是。这样能提高代码可读性。
+=======
+We recommend wrapping your code block with curly braces `{}` every time you use an `if` statement, even if there is only one statement to execute. Doing so improves readability.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 布尔转换
+<<<<<<< HEAD
`if(……)` 语句会计算圆括号包围的表达式的结果并将其转换为布尔类型。
+=======
+The `if (…)` statement evaluates the expression in its parentheses and converts the result to a boolean.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
让我们回顾一下 一章中的转换规则:
+<<<<<<< HEAD
- 数字 `0`、一个空字符串 `""`、`null`、`undefined` 和 `NaN` 都会转换成 `false`。因为他们被称为 “falsy” 值。
- 其他值变成 `true`,所以它们被称为 “truthy”。
+=======
+- A number `0`, an empty string `""`, `null`, `undefined`, and `NaN` all become `false`. Because of that they are called "falsy" values.
+- Other values become `true`, so they are called "truthy".
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
所以,下面条件下的代码永远不会执行:
@@ -48,7 +77,11 @@ if (0) { // 0 是 falsy
}
```
+<<<<<<< HEAD
……但下面的条件 — 始终有效:
+=======
+...and inside this condition -- it always will:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
if (1) { // 1 是 truthy
@@ -56,7 +89,11 @@ if (1) { // 1 是 truthy
}
```
+<<<<<<< HEAD
我们也可以将未计算的布尔值传入 `if` 语句,如下所示:
+=======
+We can also pass a pre-evaluated boolean value to `if`, like this:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let cond = (year == 2015); // 相等运算符的结果是 true 或 false
@@ -68,11 +105,15 @@ if (cond) {
## "else" 语句
+<<<<<<< HEAD
`if` 语句包含一个可选的 “else” 块。如果条件不成立,就会执行它内部的代码。
+=======
+The `if` statement may contain an optional "else" block. It executes when the condition is false.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如下所示:
```js run
-let year = prompt('In which year was ECMAScript-2015 specification published?', '');
+let year = prompt('In which year was the ECMAScript-2015 specification published?', '');
if (year == 2015) {
alert( 'You guessed it right!' );
@@ -83,12 +124,16 @@ if (year == 2015) {
## 多个条件:"else if"
+<<<<<<< HEAD
有时我们需要测试一个条件的几个变体。使用 `else if` 子句可以实现。
+=======
+Sometimes, we'd like to test several variants of a condition. The `else if` clause lets us do that.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如下所示:
```js run
-let year = prompt('In which year was ECMAScript-2015 specification published?', '');
+let year = prompt('In which year was the ECMAScript-2015 specification published?', '');
if (year < 2015) {
alert( 'Too early...' );
@@ -99,6 +144,7 @@ if (year < 2015) {
}
```
+<<<<<<< HEAD
在上面的代码中,首先检查 `year < 2015`。如果它是假的,就会转到下一个条件 `year > 2015`,否则显示最后一个 `alert`。
可以有更多的 `else if` 块。结尾的 `else` 是可选的。
@@ -106,6 +152,15 @@ if (year < 2015) {
## 三元运算符 '?'
有时我们需要根据一个条件去声明变量。
+=======
+In the code above, JavaScript first checks `year < 2015`. If that is falsy, it goes to the next condition `year > 2015`. If that is also falsy, it shows the last `alert`.
+
+There can be more `else if` blocks. The final `else` is optional.
+
+## Conditional operator '?'
+
+Sometimes, we need to assign a variable depending on a condition.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如下所示:
@@ -124,16 +179,26 @@ if (age > 18) {
alert(accessAllowed);
```
+<<<<<<< HEAD
所谓的“三元”或“问号”操作符让我们可以更简便地达到目的。
它用问号 `?` 表示。“三元”意味着操作符有三个操作数。它实际上是JavaScript 中唯一一个有这么多操作数的操作符。
+=======
+The so-called "conditional" or "question mark" operator lets us do that in a shorter and simpler way.
+
+The operator is represented by a question mark `?`. Sometimes it's called "ternary", because the operator has three operands. It is actually the one and only operator in JavaScript which has that many.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
语法如下:
```js
-let result = condition ? value1 : value2
+let result = condition ? value1 : value2;
```
+<<<<<<< HEAD
计算条件结果,如果结果为真,则返回 `value1`,否则返回 `value2`。
+=======
+The `condition` is evaluated: if it's truthy then `value1` is returned, otherwise -- `value2`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如下所示:
@@ -141,7 +206,13 @@ let result = condition ? value1 : value2
let accessAllowed = (age > 18) ? true : false;
```
+<<<<<<< HEAD
技术上,我们可以省略 `age > 18` 外面的括号。问号运算符的优先级较低。它在比较 `>` 后执行,所以也会执行相同的操作:
+=======
+Technically, we can omit the parentheses around `age > 18`. The question mark operator has a low precedence, so it executes after the comparison `>`.
+
+This example will do the same thing as the previous one:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// 比较运算符 “age > 18” 首先执行
@@ -149,10 +220,17 @@ let accessAllowed = (age > 18) ? true : false;
let accessAllowed = age > 18 ? true : false;
```
+<<<<<<< HEAD
但括号使代码更具可读性,所以建议使用它们。
````smart
在上面的例子中,可以去掉问号运算符,因为比较本身就返回 `true/false`:
+=======
+But parentheses make the code more readable, so we recommend using them.
+
+````smart
+In the example above, you can avoid using the question mark operator because the comparison itself returns `true/false`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// 下面代码同样可以实现
@@ -162,7 +240,11 @@ let accessAllowed = age > 18;
## 多个 '?'
+<<<<<<< HEAD
使用一系列问号 `?` 运算符可以返回一个取决于多个条件的值。
+=======
+A sequence of question mark operators `?` can return a value that depends on more than one condition.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如下所示:
```js run
@@ -176,6 +258,7 @@ let message = (age < 3) ? 'Hi, baby!' :
alert( message );
```
+<<<<<<< HEAD
很难一下子看出发生了什么。但经过仔细观察,我们可以看到它只是一个普通的检查序列。
1. 第一个问号检查 `age < 3`。
@@ -184,6 +267,16 @@ alert( message );
4. 如果为真 — 返回 `'Greetings!'`,否则 — 在最后一个冒号 `":"` 后面返回 `'What an unusual age!'`。
使用 `if..else` 实现上面的逻辑:
+=======
+It may be difficult at first to grasp what's going on. But after a closer look, we can see that it's just an ordinary sequence of tests:
+
+1. The first question mark checks whether `age < 3`.
+2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon '":"', checking `age < 18`.
+3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon '":"', checking `age < 100`.
+4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon '":"', returning `'What an unusual age!'`.
+
+Here's how this looks using `if..else`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
if (age < 3) {
@@ -210,6 +303,7 @@ let company = prompt('Which company created JavaScript?', '');
*/!*
```
+<<<<<<< HEAD
根据 `company =='Netscape'` 条件,要么执行 `?` 后面的第一部分方法并显示对应内容,要么执行第二部分的方法并显示对应内容。
在这里我们不是把结果赋值给变量。而是根据条件执行不同的代码。
@@ -219,6 +313,17 @@ let company = prompt('Which company created JavaScript?', '');
这种写法比 `if` 语句更短,对一些程序员很有吸引力。但它的可读性较差。
下面是使用 `if` 语句实现的相同功能的代码,进行下比较:
+=======
+Depending on the condition `company == 'Netscape'`, either the first or the second expression after the `?` gets executed and shows an alert.
+
+We don't assign a result to a variable here. Instead, we execute different code depending on the condition.
+
+**We don't recommend using the question mark operator in this way.**
+
+The notation is shorter than the equivalent `if` statement, which appeals to some programmers. But it is less readable.
+
+Here is the same code using `if` for comparison:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
let company = prompt('Which company created JavaScript?', '');
@@ -232,6 +337,12 @@ if (company == 'Netscape') {
*/!*
```
+<<<<<<< HEAD
因为我们的眼睛垂直扫描代码。跨越多行的结构比长的水平代码更容易理解。
问号 `?` 的作用是根据条件返回一个或另一个值。请正确使用它。`if` 还可以用来执行代码的不同分支。
+=======
+Our eyes scan the code vertically. Code blocks which span several lines are easier to understand than a long, horizontal instruction set.
+
+The purpose of the question mark operator `?` is to return one value or another depending on its condition. Please use it for exactly that. Use `if` when you need to execute different branches of code.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/11-logical-operators/1-alert-null-2-undefined/task.md b/1-js/02-first-steps/11-logical-operators/1-alert-null-2-undefined/task.md
index 512fd6f33a..a2719ce0d9 100644
--- a/1-js/02-first-steps/11-logical-operators/1-alert-null-2-undefined/task.md
+++ b/1-js/02-first-steps/11-logical-operators/1-alert-null-2-undefined/task.md
@@ -4,7 +4,11 @@ importance: 5
# 或运算的结果是什么?
+<<<<<<< HEAD
如下代码将会输出什么?
+=======
+What is the code below going to output?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
alert( null || 2 || undefined );
diff --git a/1-js/02-first-steps/11-logical-operators/2-alert-or/task.md b/1-js/02-first-steps/11-logical-operators/2-alert-or/task.md
index fac364cc24..13a8df6b0f 100644
--- a/1-js/02-first-steps/11-logical-operators/2-alert-or/task.md
+++ b/1-js/02-first-steps/11-logical-operators/2-alert-or/task.md
@@ -4,7 +4,11 @@ importance: 3
# 或运算和 alerts 的结果是什么?
+<<<<<<< HEAD
下面的代码将会输出什么?
+=======
+What will the code below output?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
alert( alert(1) || 2 || alert(3) );
diff --git a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/task.md b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/task.md
index 2331e3e223..432bda60eb 100644
--- a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/task.md
+++ b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/task.md
@@ -4,7 +4,11 @@ importance: 5
# 与操作的结果是什么?
+<<<<<<< HEAD
下面这段代码将会显示什么?
+=======
+What is this code going to show?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
alert( 1 && null && 2 );
diff --git a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md
index c98fae47c1..1fa3f30d73 100644
--- a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md
@@ -12,5 +12,9 @@ alert( null || 2 && 3 || 4 );
null || 3 || 4
```
+<<<<<<< HEAD
现在的结果就是第一个真值:`3`。
+=======
+Now the result is the first truthy value: `3`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md
index 05b7f18aa7..226f7dd65e 100644
--- a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md
+++ b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md
@@ -4,7 +4,11 @@ importance: 5
# 或运算、与运算、或运算串联的结果
+<<<<<<< HEAD
结果将会是什么?
+=======
+What will the result be?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
alert( null || 2 && 3 || 4 );
diff --git a/1-js/02-first-steps/11-logical-operators/8-if-question/task.md b/1-js/02-first-steps/11-logical-operators/8-if-question/task.md
index 466673e2a9..aa1164a345 100644
--- a/1-js/02-first-steps/11-logical-operators/8-if-question/task.md
+++ b/1-js/02-first-steps/11-logical-operators/8-if-question/task.md
@@ -6,7 +6,11 @@ importance: 5
下面哪一个 `alert` 将会被执行?
+<<<<<<< HEAD
`if(...)` 语句内表达式的结果是什么?
+=======
+What will the results of the expressions be inside `if(...)`?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
if (-1 || 0) alert( 'first' );
diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.png b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.png
new file mode 100644
index 0000000000..32f0d4b94c
Binary files /dev/null and b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.png differ
diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task@2x.png b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task@2x.png
new file mode 100644
index 0000000000..c3867e62c0
Binary files /dev/null and b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task@2x.png differ
diff --git a/1-js/02-first-steps/10-ifelse/4-check-login/solution.md b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
similarity index 100%
rename from 1-js/02-first-steps/10-ifelse/4-check-login/solution.md
rename to 1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
diff --git a/1-js/02-first-steps/10-ifelse/4-check-login/task.md b/1-js/02-first-steps/11-logical-operators/9-check-login/task.md
similarity index 71%
rename from 1-js/02-first-steps/10-ifelse/4-check-login/task.md
rename to 1-js/02-first-steps/11-logical-operators/9-check-login/task.md
index 9925377b9c..b3d0ab3de1 100644
--- a/1-js/02-first-steps/10-ifelse/4-check-login/task.md
+++ b/1-js/02-first-steps/11-logical-operators/9-check-login/task.md
@@ -20,6 +20,10 @@ importance: 3
请使用嵌套的 `if` 块。注意代码整体的可读性。
+<<<<<<< HEAD:1-js/02-first-steps/10-ifelse/4-check-login/task.md
提示:将空字符串输入,prompt 会获取到一个空字符串 `''`。Prompt 运行过程中,按下 `key:ESC` 键会得到 `null`。
+=======
+Hint: passing an empty input to a prompt returns an empty string `''`. Pressing `key:ESC` during a prompt returns `null`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb:1-js/02-first-steps/11-logical-operators/9-check-login/task.md
[示例]
diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md
index 7a65d5bbbc..cc0feca378 100644
--- a/1-js/02-first-steps/11-logical-operators/article.md
+++ b/1-js/02-first-steps/11-logical-operators/article.md
@@ -2,7 +2,11 @@
JavaScript 里有三个逻辑运算符:`||` (或), `&&` (与), `!` (非)。
+<<<<<<< HEAD
虽然被称为“逻辑”,这些运算符却可以被应用于任意类型的值,而不仅仅是布尔值。结果也同样可能是任意类型。
+=======
+Although they are called "logical", they can be applied to values of any type, not only boolean. Their result can also be of any type.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
让我们来详细看一下。
@@ -14,9 +18,15 @@ JavaScript 里有三个逻辑运算符:`||` (或), `&&` (与), `!` (非)。
result = a || b;
```
+<<<<<<< HEAD
在传统的编程中,逻辑或仅能够操作布尔值。如果参与运算的一个参数为 `true`,结果将返回 `true`,否则返回 `false`。
在 JavaScript 中,逻辑运算符更加灵活强大。但是首先我们看一下操作数是布尔值的时候发生了什么。
+=======
+In classical programming, the logical OR is meant to manipulate boolean values only. If any of its arguments are `true`, it returns `true`, otherwise it returns `false`.
+
+In JavaScript, the operator is a little bit trickier and more powerful. But first, let's see what happens with boolean values.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
下面是四种可能的逻辑组合:
@@ -29,9 +39,15 @@ alert( false || false ); // false
正如我们所见,除了两个操作数都是 `false` 的情况,结果总是 `true`。
+<<<<<<< HEAD
如果操作数不是布尔值,那么它将会被转化为布尔值来参与运算。
例如,数字 `1` 将会被作为 `true`,数字 `0` 则作为 `false`:
+=======
+If an operand is not a boolean, it's converted to a boolean for the evaluation.
+
+For instance, the number `1` is treated as `true`, the number `0` as `false`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
if (1 || 0) { // 工作原理相当于 if( true || false )
@@ -39,7 +55,11 @@ if (1 || 0) { // 工作原理相当于 if( true || false )
}
```
+<<<<<<< HEAD
大多数时间,或 `||` 会被用在 `if` 语句中,用来测试是否有**任何**给定的条件是正确的。
+=======
+Most of the time, OR `||` is used in an `if` statement to test if *any* of the given conditions is `true`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -64,9 +84,15 @@ if (hour < 10 || hour > 18 || isWeekend) {
}
```
+<<<<<<< HEAD
## 或运算寻找第一个真值
上文提到的逻辑处理多少有些传统了。下面让我们看看 JavaScript 的“附加”特性。
+=======
+## OR finds the first truthy value
+
+The logic described above is somewhat classical. Now, let's bring in the "extra" features of JavaScript.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
拓展的算法如下所示。
@@ -78,13 +104,23 @@ result = value1 || value2 || value3;
或运算符 `||` 做了如下的事情:
+<<<<<<< HEAD
- 从左到右依次计算操作数。
- 将每一个操作数转化为布尔值。如果结果是 `true`,就停止计算,返回这个操作数的初始值。
- 如果所有的操作数都被计算过(也就是,转换结果都是 `false`),返回最后一个操作数。
+=======
+- Evaluates operands from left to right.
+- For each operand, converts it to boolean. If the result is `true`, stops and returns the original value of that operand.
+- If all operands have been evaluated (i.e. all were `false`), returns the last operand.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
返回的值是操作数的初始形式,不会做布尔转换。
+<<<<<<< HEAD
也就是,一个或 `"||"` 运算的链将返回第一个真值,如果这样的值不存在就返回该链的最后一个值。
+=======
+In other words, a chain of OR `"||"` returns the first truthy value or the last one if no truthy value is found.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -97,6 +133,7 @@ alert( null || 0 || 1 ); // 1(第一个真值)
alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返回最后一个值)
```
+<<<<<<< HEAD
对比与“纯粹的、传统的、仅仅处理布尔值的或运算”,这个就有很有趣的用法了。
1. **获取变量列表或者表达式的第一个真值**
@@ -104,6 +141,15 @@ alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返
假设我们有几个变量,它们可能包含某些数据或者是 `null/undefined`。我们需要选出第一个包含数据的变量。
我们可以这样应用或运算 `||`:
+=======
+This leads to some interesting usage compared to a "pure, classical, boolean-only OR".
+
+1. **Getting the first truthy value from a list of variables or expressions.**
+
+ Imagine we have a list of variables which can either contain data or be `null/undefined`. How can we find the first one with data?
+
+ We can use OR `||`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let currentUser = null;
@@ -116,6 +162,7 @@ alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返
alert( name ); // 选出了 “John” - 第一个真值
```
+<<<<<<< HEAD
如果 `currentUser` 和 `defaultUser` 都是假值,那么结果就是 `"unnamed"`。
2. **短路取值。**
@@ -124,6 +171,16 @@ alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返
当表达式作为第二个参数并且有一定副作用,比如变量赋值的时候,这就清楚可见了。
如果我们运行下面的例子,`x` 将不会被赋值:
+=======
+ If both `currentUser` and `defaultUser` were falsy, `"unnamed"` would be the result.
+2. **Short-circuit evaluation.**
+
+ Operands can be not only values, but arbitrary expressions. OR evaluates and tests them from left to right. The evaluation stops when a truthy value is reached, and the value is returned. This process is called "a short-circuit evaluation" because it goes as short as possible from left to right.
+
+ This is clearly seen when the expression given as the second argument has a side effect like a variable assignment.
+
+ In the example below, `x` does not get assigned:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
let x;
@@ -133,7 +190,11 @@ alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返
alert(x); // undefined,因为 (x = 1) 没有被执行
```
+<<<<<<< HEAD
...如果第一个参数是 `false`,或运算将会继续并计算第二个参数,也就会运行赋值操作。
+=======
+ If, instead, the first argument is `false`, `||` evaluates the second one, thus running the assignment:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
let x;
@@ -143,11 +204,19 @@ alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返
alert(x); // 1
```
+<<<<<<< HEAD
赋值操作只是一个很简单的情况,其他副作用同样可以被包含进来。
正如我们所见,这种用法是“`if` 语句的简便方式”。第一个操作数被转化为布尔值,如果是假,那么第二个参数就会被执行。
大多数情况下,使用正常的 `if` 语句,这样代码可读性更高,但是有时候这种方式会很简洁。
+=======
+ An assignment is a simple case. There may be side effects, that won't show up if the evaluation doesn't reach them.
+
+ As we can see, such a use case is a "shorter way of doing `if`". The first operand is converted to boolean. If it's false, the second one is evaluated.
+
+ Most of time, it's better to use a "regular" `if` to keep the code easy to understand, but sometimes this can be handy.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## &&(与)
@@ -157,7 +226,11 @@ alert( undefined || null || 0 ); // 0(所有的转化结果都是 false,返
result = a && b;
```
+<<<<<<< HEAD
传统的编程中,当两个操作数都是真值,与操作返回 `true`,否则返回 `false`:
+=======
+In classical programming, AND returns `true` if both operands are truthy and `false` otherwise:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( true && true ); // true
@@ -173,11 +246,15 @@ let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) {
- alert( 'Time is 12:30' );
+ alert( 'The time is 12:30' );
}
```
+<<<<<<< HEAD
就像或运算一样,与运算的操作数可以是任意类型的值:
+=======
+Just as with OR, any value is allowed as an operand of AND:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
if (1 && 0) { // 作为 true && false 来执行
@@ -186,7 +263,11 @@ if (1 && 0) { // 作为 true && false 来执行
```
+<<<<<<< HEAD
## 与操作寻找第一个假值
+=======
+## AND finds the first falsy value
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
给出多个参加与运算的值:
@@ -196,9 +277,15 @@ result = value1 && value2 && value3;
与运算 `&&` 做了如下的事情:
+<<<<<<< HEAD
- 从左到右依次计算操作数。
- 将每一个操作数转化为布尔值。如果结果是 `false`,就停止计算,返回这个操作数的初始值。
- 如果所有的操作数都被计算过(也就是,转换结果都是 `true`),返回最后一个操作数。
+=======
+- Evaluates operands from left to right.
+- For each operand, converts it to a boolean. If the result is `false`, stops and returns the original value of that operand.
+- If all operands have been evaluated (i.e. all were truthy), returns the last operand.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
换句话说,与操作符返回第一个假值,如果没有假值就返回最后一个值。
@@ -230,6 +317,7 @@ alert( 1 && 2 && null && 3 ); // null
alert( 1 && 2 && 3 ); // 3,最后一个值
```
+<<<<<<< HEAD
````smart header="与运算 `&&` 在或操作符 `||` 之前执行"
与运算 `&&` 的优先级比或运算 `||` 要高,所以它将会比或运算先执行。
@@ -238,6 +326,12 @@ alert( 1 && 2 && 3 ); // 3,最后一个值
```js run
alert( 5 || 1 && 0 ); // 5
```
+=======
+````smart header="Precedence of AND `&&` is higher than OR `||`"
+The precedence of AND `&&` operator is higher than OR `||`.
+
+So the code `a && b || c && d` is essentially the same as if the `&&` expressions were in parentheses: `(a && b) || (c && d)`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
就像或运算一样,与运算 `&&` 有时候能够代替 `if`。
@@ -250,7 +344,11 @@ let x = 1;
(x > 0) && alert( 'Greater than zero!' );
```
+<<<<<<< HEAD
`&&` 右边的代码只有运算抵达到那里才能被执行。也就是,当且仅当 `(x > 0)` 返回了真值。
+=======
+The action in the right part of `&&` would execute only if the evaluation reaches it. That is, only if `(x > 0)` is true.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
所以我们基本可以类似的得到:
@@ -262,9 +360,15 @@ if (x > 0) {
}
```
+<<<<<<< HEAD
带 `&&` 的代码变体看上去更短。但是 `if` 的含义更明显,可读性也更高。
所以建议是根据目的选择代码的结构。需要条件判断就用 `if`,需要与运算就用 `&&`。
+=======
+The variant with `&&` appears shorter. But `if` is more obvious and tends to be a little bit more readable.
+
+So we recommend using every construct for its purpose: use `if` if we want if and use `&&` if we want AND.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## !(非)
@@ -278,8 +382,13 @@ result = !value;
操作符接受一个参数,并按如下运作:
+<<<<<<< HEAD
1. 将操作数转化为布尔类型:`true/false`。
2. 返回相反的值。
+=======
+1. Converts the operand to boolean type: `true/false`.
+2. Returns the inverse value.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -295,7 +404,11 @@ alert( !!"non-empty string" ); // true
alert( !!null ); // false
```
+<<<<<<< HEAD
也就是,第一个非运算将该值转化为布尔类型并取反,第二个非运算再次取反。最后我们就得到了一个任意值到布尔值的转化。
+=======
+That is, the first NOT converts the value to boolean and returns the inverse, and the second NOT inverses it again. In the end, we have a plain value-to-boolean conversion.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这是一个更详细的方法,完成的同样的事情 -- 一个内置的 `Boolean` 函数:
@@ -303,3 +416,5 @@ alert( !!null ); // false
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
```
+
+The precedence of NOT `!` is the highest of all logical operators, so it always executes first, before `&&` or `||`.
diff --git a/1-js/02-first-steps/12-while-for/2-which-value-while/solution.md b/1-js/02-first-steps/12-while-for/2-which-value-while/solution.md
index abee806bb9..6f1d6f9836 100644
--- a/1-js/02-first-steps/12-while-for/2-which-value-while/solution.md
+++ b/1-js/02-first-steps/12-while-for/2-which-value-while/solution.md
@@ -7,18 +7,28 @@
while (++i < 5) alert( i );
```
+<<<<<<< HEAD
第一个值是 `i=1`,因为 `++i` 首先递增 `i` 然后返回新值。因此先比较 `1 < 5` 然后 `alert` 显示 `1`。
然后按照 `2,3,4…` —— 数值一个接着一个出现。比较总是使用递增值,因为 `++` 在变量前。
最终,`i=4` 递增到 `5`,当比较 `while(5 < 5)` 失败时,循环停止。所以没有显示 `5`。
2. **从 1 到 5**
+=======
+ The first value is `i = 1`, because `++i` first increments `i` and then returns the new value. So the first comparison is `1 < 5` and the `alert` shows `1`.
+
+ Then follow `2, 3, 4…` -- the values show up one after another. The comparison always uses the incremented value, because `++` is before the variable.
+
+ Finally, `i = 4` is incremented to `5`, the comparison `while(5 < 5)` fails, and the loop stops. So `5` is not shown.
+2. **From 1 to 5**
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let i = 0;
while (i++ < 5) alert( i );
```
+<<<<<<< HEAD
第一个值也是 `i=1`。后缀形式 `i++` 递增 `i` 然后返回**旧**值,因此比较 `i++ < 5` 将使用 `i=0` (与 `++i < 5` 相反)。
但 `alert` 调用是独立的。这是在递增和比较之后执行的另一条语句。因此它得到了当前的 `i=1`。
@@ -28,3 +38,14 @@
我们在 `i=4` 时暂停,前缀形式 `++i` 会递增并在比较中使用 `5`。但我们这里还有后缀形式 `i++`。因此,它将 `i` 递增到 `5`,但返回旧值。因此实际比较的是 `while(4 < 5)` —— true,控制继续执行 `alert`。
`i=5` 是最后一个值,因为下一步 `while(5 < 5)` 为 false。
+=======
+ The first value is again `i = 1`. The postfix form of `i++` increments `i` and then returns the *old* value, so the comparison `i++ < 5` will use `i = 0` (contrary to `++i < 5`).
+
+ But the `alert` call is separate. It's another statement which executes after the increment and the comparison. So it gets the current `i = 1`.
+
+ Then follow `2, 3, 4…`
+
+ Let's stop on `i = 4`. The prefix form `++i` would increment it and use `5` in the comparison. But here we have the postfix form `i++`. So it increments `i` to `5`, but returns the old value. Hence the comparison is actually `while(4 < 5)` -- true, and the control goes on to `alert`.
+
+ The value `i = 5` is the last one, because on the next step `while(5 < 5)` is false.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/12-while-for/2-which-value-while/task.md b/1-js/02-first-steps/12-while-for/2-which-value-while/task.md
index ce6ba71723..3fc3c878f2 100644
--- a/1-js/02-first-steps/12-while-for/2-which-value-while/task.md
+++ b/1-js/02-first-steps/12-while-for/2-which-value-while/task.md
@@ -2,11 +2,19 @@ importance: 4
---
+<<<<<<< HEAD
# 哪个值才是 while?
对于每次循环,写出你认为会显示的值,然后与答案进行比较。
两次循环的 `alert` 值是否相同?
+=======
+# Which values does the while loop show?
+
+For every loop iteration, write down which value it outputs and then compare it with the solution.
+
+Both loops `alert` the same values, or not?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
1. 前缀形式 `++i`:
diff --git a/1-js/02-first-steps/12-while-for/6-repeat-until-correct/task.md b/1-js/02-first-steps/12-while-for/6-repeat-until-correct/task.md
index 43922b1fbd..8bdb3e8d3c 100644
--- a/1-js/02-first-steps/12-while-for/6-repeat-until-correct/task.md
+++ b/1-js/02-first-steps/12-while-for/6-repeat-until-correct/task.md
@@ -3,7 +3,11 @@ importance: 5
# 重复输入,直到正确为止
+<<<<<<< HEAD
编写一个提示输入大于 `100` 的循环。如果使用者输入其他数值 —— 请他重新输入。
+=======
+Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask them to input again.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
循环必须请求一个数值,直到使用者输入一个大于 `100` 的数值或取消输入/输入空行为止。
diff --git a/1-js/02-first-steps/12-while-for/7-list-primes/solution.md b/1-js/02-first-steps/12-while-for/7-list-primes/solution.md
index 741b287522..18a4b779c2 100644
--- a/1-js/02-first-steps/12-while-for/7-list-primes/solution.md
+++ b/1-js/02-first-steps/12-while-for/7-list-primes/solution.md
@@ -26,4 +26,8 @@ for (let i = 2; i <= n; i++) { // for each i...
}
```
+<<<<<<< HEAD
这段代码有很大空间可以优化。例如,我们可以从 `2` 到 `i` 的平方根中寻找除数。但无论如何,如果我们想要在很大的时间间隔内实现高效率,我们需要改变方法,依赖高等数学和复杂算法,如[二次筛选] [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) 等等。
+=======
+There's a lot of space to opimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need to change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/12-while-for/article.md b/1-js/02-first-steps/12-while-for/article.md
index 0a01a165a9..1f14606b66 100644
--- a/1-js/02-first-steps/12-while-for/article.md
+++ b/1-js/02-first-steps/12-while-for/article.md
@@ -1,10 +1,18 @@
# 循环:while 和 for
+<<<<<<< HEAD
我们经常需要连续多次执行类似的操作。
例如,我们需要从列表中逐个输出商品时,或者对从 1 到 10 的每个数字运行相同的代码时。
**循环**是一种多次重复运行同一部分代码的方法。
+=======
+We often need to repeat actions.
+
+For example, outputting goods from a list one after another or just running the same code for each number from 1 to 10.
+
+*Loops* are a way to repeat the same code multiple times.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## "while" 循环
@@ -31,11 +39,19 @@ while (i < 3) { // 结果分别是 0、1、2
循环体的单次执行叫作**一次迭代**。上面示例中的循环进行三次迭代。
+<<<<<<< HEAD
如果上述示例中没有 `i++`,那么循环(理论上)会永远重复。实际上,浏览器提供了阻止这种循环的方法,对于服务器端 JavaScript,我们可以终止该过程。
任何表达式或变量都可以是循环条件,而不仅仅是比较。对它们进行计算,并通过 `while` 将其结果转化为布尔值。
例如,`while (i != 0)` 可简写为 `while (i)`:
+=======
+If `i++` was missing from the example above, the loop would repeat (in theory) forever. In practice, the browser provides ways to stop such loops, and in server-side JavaScript, we can kill the process.
+
+Any expression or variable can be a loop condition, not just comparisons: the condition is evaluated and converted to a boolean by `while`.
+
+For instance, a shorter way to write `while (i != 0)` is `while (i)`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let i = 3;
@@ -47,8 +63,13 @@ while (i) { // 当 i 变成 0 时,条件为 false,循环终止
}
```
+<<<<<<< HEAD
````smart header="Brackets are not required for a single-line body"
如果循环体只有一条语句,则可以省略括号 `{…}`:
+=======
+````smart header="Curly braces are not required for a single-line body"
+If the loop body has a single statement, we can omit the curly braces `{…}`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let i = 3;
@@ -68,7 +89,11 @@ do {
} while (condition);
```
+<<<<<<< HEAD
循环首先执行循环体,然后检查条件,当条件为真时,重复执行循环体。
+=======
+The loop will first execute the body, then check the condition, and, while it's truthy, execute it again and again.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -80,11 +105,19 @@ do {
} while (i < 3);
```
+<<<<<<< HEAD
这种形式的语法很少使用,除非您希望不管条件是否为真,循环体**至少执行一次**。通常其他形式是首选:`while(…) {…}`。
+=======
+This form of syntax should only be used when you want the body of the loop to execute **at least once** regardless of the condition being truthy. Usually, the other form is preferred: `while(…) {…}`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## "for" 循环
+<<<<<<< HEAD
`for` 循环是最常使用的。
+=======
+The `for` loop is the most commonly used loop.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
看起来就像这样:
@@ -102,6 +135,7 @@ for (let i = 0; i < 3; i++) { // 结果为 0、1、2
}
```
+<<<<<<< HEAD
我们逐部分地检查 `for` 语句:
| 部分 | | |
@@ -110,6 +144,16 @@ for (let i = 0; i < 3; i++) { // 结果为 0、1、2
| 条件 | `i < 3`| 在每次循环迭代之前检查,如果失败,循环停止。 |
| 步骤 | `i++` | 在每次迭代后执行主体,但在条件检查之前执行。 |
| 主体 | `alert(i)`| 条件为真时,重复运行。 |
+=======
+Let's examine the `for` statement part-by-part:
+
+| part | | |
+|-------|----------|----------------------------------------------------------------------------|
+| begin | `i = 0` | Executes once upon entering the loop. |
+| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. |
+| step| `i++` | Executes after the body on each iteration but before the condition check. |
+| body | `alert(i)`| Runs again and again while the condition is truthy. |
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
一般循环算法的工作原理如下:
@@ -121,9 +165,15 @@ Run begin
→ ...
```
+<<<<<<< HEAD
如果您是循环方面的小白,那么回到这个例子,在一张纸上重现它逐步运行的过程,可能会对你有所帮助。
以下是我们示例中发生的情况:
+=======
+If you are new to loops, it could help to go back to the example and reproduce how it runs step-by-step on a piece of paper.
+
+Here's exactly what happens in our case:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// for (let i = 0; i < 3; i++) alert(i)
@@ -140,7 +190,11 @@ if (i < 3) { alert(i); i++ }
```
````smart header="Inline variable declaration"
+<<<<<<< HEAD
这里“计数”变量 `i` 在循环中声明。这叫做“内联”变量声明。这样的变量只在循环中可见。
+=======
+Here, the "counter" variable `i` is declared right in the loop. This is called an "inline" variable declaration. Such variables are visible only inside the loop.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
for (*!*let*/!* i = 0; i < 3; i++) {
@@ -149,7 +203,11 @@ for (*!*let*/!* i = 0; i < 3; i++) {
alert(i); // 错误,没有这个变量。
```
+<<<<<<< HEAD
我们可以使用现有的变量而不是定义变量:
+=======
+Instead of defining a variable, we could use an existing one:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let i = 0;
@@ -190,9 +248,15 @@ for (; i < 3;) {
}
```
+<<<<<<< HEAD
该循环与 `while (i < 3)` 等价。
实际上我们可以删除所有内容,从而创建一个无限循环:
+=======
+This makes the loop identical to `while (i < 3)`.
+
+We can actually remove everything, creating an infinite loop:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
for (;;) {
@@ -200,15 +264,27 @@ for (;;) {
}
```
+<<<<<<< HEAD
请注意 `for` 的两个 `;` 必须存在,否则会出现语法错误。
+=======
+Please note that the two `for` semicolons `;` must be present. Otherwise, there would be a syntax error.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 跳出循环
+<<<<<<< HEAD
通常条件为假时,循环会终止。
但我们随时都可以强制退出,因为有一个特殊的 `break` 指令可以做到这一点。
例如,下述循环要求用户输入一系列数字,但会在没有数字输入时候“终止”。
+=======
+Normally, a loop exits when its condition becomes falsy.
+
+But we can force the exit at any time using the special `break` directive.
+
+For example, the loop below asks the user for a series of numbers, "breaking" when no number is entered:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let sum = 0;
@@ -227,15 +303,27 @@ while (true) {
alert( 'Sum: ' + sum );
```
+<<<<<<< HEAD
如果用户输入空行或取消输入,在 `(*)` 行 `break` 指令会被激活。它立刻终止循环,将控制权传递给循环后的第一行,即,`alert`。
根据需要,"无限循环 + `break`" 的组合非常适用于不必在循环开始/结束时检查条件,但在中间甚至是主体的多个位置进行检查的情况。
+=======
+The `break` directive is activated at the line `(*)` if the user enters an empty line or cancels the input. It stops the loop immediately, passing control to the first line after the loop. Namely, `alert`.
+
+The combination "infinite loop + `break` as needed" is great for situations when a loop's condition must be checked not in the beginning or end of the loop, but in the middle or even in several places of its body.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 继续下一次迭代 [#continue]
+<<<<<<< HEAD
`continue` 指令是 `break` 的“轻量版”。这并不能阻止整个循环。相反,它将停止当前的迭代,并强制启动新一轮循环(如果条件允许的话)。
如果我们完成了当前的迭代,并且希望继续执行下一次迭代,我们就可以使用它。
+=======
+The `continue` directive is a "lighter version" of `break`. It doesn't stop the whole loop. Instead, it stops the current iteration and forces the loop to start a new one (if the condition allows).
+
+We can use it if we're done with the current iteration and would like to move on to the next one.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
下述循环使用 `continue` 只输出奇数:
@@ -249,10 +337,17 @@ for (let i = 0; i < 10; i++) {
}
```
+<<<<<<< HEAD
对于偶数的 `i`,`continue` 指令停止执行,将控制权传递给下一次 `for`(使用下一个数字)的迭代。因此 `alert` 仅被奇数值调用。
````smart header="The directive `continue` helps to decrease nesting level"
显示奇数的循环如下所示:
+=======
+For even values of `i`, the `continue` directive stops executing the body and passes control to the next iteration of `for` (with the next number). So the `alert` is only called for odd values.
+
+````smart header="The `continue` directive helps decrease nesting"
+A loop that shows odd values could look like this:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
for (let i = 0; i < 10; i++) {
@@ -264,6 +359,7 @@ for (let i = 0; i < 10; i++) {
}
```
+<<<<<<< HEAD
从技术角度看,它与上述示例完全相同。当然,我们可以将代码包装在 `if` 块而不是 `continue` 块。
但作为副作用,我们还有一个嵌套级别(花括号内的 `alert` 调用)。如果 `if` 中代码超过几行,则可能会降低总体可读性。
@@ -271,6 +367,15 @@ for (let i = 0; i < 10; i++) {
````warn header="No `break/continue` to the right side of '?'"
请注意非表达式的语法结构不能与三元运算符 `?` 一起使用。特别是 `break/continue` 这样的指令是不被允许使用的。
+=======
+From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`.
+
+But as a side-effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of`if` is longer than a few lines, that may decrease the overall readability.
+````
+
+````warn header="No `break/continue` to the right side of '?'"
+Please note that syntax constructs that are not expressions cannot be used with the ternary operator `?`. In particular, directives such as `break/continue` aren't allowed there.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如,我们使用如下代码:
@@ -282,24 +387,39 @@ if (i > 5) {
}
```
+<<<<<<< HEAD
...然后用问号重写:
+=======
+...and rewrite it using a question mark:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js no-beautify
-(i > 5) ? alert(i) : *!*continue*/!*; // continue not allowed here
+(i > 5) ? alert(i) : *!*continue*/!*; // continue isn't allowed here
```
+<<<<<<< HEAD
...然后会停止运行。这样的代码将给出语法错误:
这只是不适用 `?` 而不是 `if` 的另一个原因。
+=======
+...it stops working. Code like this will give a syntax error:
+
+
+This is just another reason not to use the question mark operator `?` instead of `if`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
## break/continue 标签
有时候我们需要从多个嵌套循环中跳出来。
+<<<<<<< HEAD
例如,下述代码中我们的循环使用 `i` 和 `j`,提示坐标 `(i, j)` 从 `(0,0)` 到 `(3,3)`:
+=======
+For example, in the code below we loop over `i` and `j`, prompting for the coordinates `(i, j)` from `(0,0)` to `(3,3)`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
for (let i = 0; i < 3; i++) {
@@ -318,7 +438,11 @@ alert('Done!');
如果用户取消输入,我们需要另一种方法来停止这个过程。
+<<<<<<< HEAD
在 `input` 之后的普通 `break` 只会打破内部循环。这还不够。标签可以拯救。
+=======
+The ordinary `break` after `input` would only break the inner loop. That's not sufficient--labels, come to the rescue!
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
**标签**是在循环之前带有冒号的标识符:
```js
@@ -327,9 +451,13 @@ labelName: for (...) {
}
```
+<<<<<<< HEAD
`break ` 语句跳出循环至标签处。
就像这样:
+=======
+The `break ` statement in the loop below breaks out to the label:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
*!*outer:*/!* for (let i = 0; i < 3; i++) {
@@ -347,7 +475,11 @@ labelName: for (...) {
alert('Done!');
```
+<<<<<<< HEAD
上述代码中,`break outer` 向上寻找名为 `outer` 的标签并跳出当前循环。
+=======
+In the code above, `break outer` looks upwards for the label named `outer` and breaks out of that loop.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
因此,控制权直接从 `(*)` 转至 `alert('Done!')`。
@@ -358,10 +490,17 @@ outer:
for (let i = 0; i < 3; i++) { ... }
```
+<<<<<<< HEAD
`continue` 指令也可以与标签一起使用。在这种情况下,执行跳转到标记循环的下一次迭代。
````warn header="Labels are not a \"goto\""
标签不允许我们跳到任意代码位置。
+=======
+The `continue` directive can also be used with a label. In this case, code execution jumps to the next iteration of the labeled loop.
+
+````warn header="Labels are not a \"goto\""
+Labels do not allow us to jump into an arbitrary place in the code.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如,这样做是不可能的:
```js
@@ -370,7 +509,11 @@ break label; // 跳转到标签?不。
label: for (...)
```
+<<<<<<< HEAD
只有在循环内部才能调用 `break/continue`,并且标签必须位于指令上方的某个位置。
+=======
+A call to `break/continue` is only possible from inside a loop and the label must be somewhere above the directive.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
## 总结
@@ -383,6 +526,12 @@ label: for (...)
通常使用 `while(true)` 来构造“无限”循环。这样的循环就像任何其他循环一样,可以通过 `break` 指令来终止。
+<<<<<<< HEAD
如果我们不想在当前迭代中做任何事,并且想要转移至下一次迭代,那么 `continue` 指令就会执行它。
`break/continue` 支持循环前的标签。标签是 `break/continue` 避免嵌套并转到外部循环的唯一方法。
+=======
+If we don't want to do anything in the current iteration and would like to forward to the next one, we can use the `continue` directive.
+
+`break/continue` support labels before the loop. A label is the only way for `break/continue` to escape a nested loop to go to an outer one.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/02-first-steps/13-switch/article.md b/1-js/02-first-steps/13-switch/article.md
index 0f53e310f2..5a546344ad 100644
--- a/1-js/02-first-steps/13-switch/article.md
+++ b/1-js/02-first-steps/13-switch/article.md
@@ -148,7 +148,7 @@ switch (a) {
比如,我们来看下面的代码:
```js run
-let arg = prompt("Enter a value?")
+let arg = prompt("Enter a value?");
switch (arg) {
case '0':
case '1':
@@ -163,7 +163,7 @@ switch (arg) {
alert( 'Never executes!' );
break;
default:
- alert( 'An unknown value' )
+ alert( 'An unknown value' );
}
```
diff --git a/1-js/02-first-steps/14-function-basics/4-pow/task.md b/1-js/02-first-steps/14-function-basics/4-pow/task.md
index 7acf9d7102..e66ddbd966 100644
--- a/1-js/02-first-steps/14-function-basics/4-pow/task.md
+++ b/1-js/02-first-steps/14-function-basics/4-pow/task.md
@@ -9,7 +9,7 @@ importance: 4
```js
pow(3, 2) = 3 * 3 = 9
pow(3, 3) = 3 * 3 * 3 = 27
-pow(1, 100) = 1 * 1 * ...*1 = 1
+pow(1, 100) = 1 * 1 * ...* 1 = 1
```
创建一个 web 页面,提示输入 `x` 和 `n` 然后返回 `pow(x,n)` 的函数值。
diff --git a/1-js/02-first-steps/14-function-basics/article.md b/1-js/02-first-steps/14-function-basics/article.md
index 47f42f324b..4ed37cb742 100644
--- a/1-js/02-first-steps/14-function-basics/article.md
+++ b/1-js/02-first-steps/14-function-basics/article.md
@@ -101,7 +101,11 @@ showMessage();
alert( userName ); // *!*Bob*/!*, 值被函数修改
```
+<<<<<<< HEAD
只有在没有本地变量的情况下才会使用外部变量。因此如果我们忘记了 `let`,可能会发生意外修改的情况。
+=======
+The outer variable is only used if there's no local one.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如果在函数中声明了同名变量,那么它**遮蔽**外部变量。例如,在如下代码中,函数使用本地的 `userName`,外部部分被忽略:
@@ -128,7 +132,11 @@ alert( userName ); // *!*John*/!*,未更改,函数没有访问外部变量
全局变量在任意函数中都是可见的(除非被局部变量遮蔽)。
+<<<<<<< HEAD
通常,函数声明与任务相关的所有变量。全局变量只存储项目级的数据,所以这些变量从任何地方都可以访问是很重要的事情。现代的代码有很少或没有全局变量。大多数变量存在于它们的函数中。
+=======
+It's a good practice to minimize the use of global variables. Modern code has few or no globals. Most variables reside in their functions. Sometimes though, they can be useful to store project-level data.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 参数
@@ -204,6 +212,12 @@ function showMessage(from, text = anotherFunction()) {
}
```
+```smart header="Evaluation of default parameters"
+
+In JavaScript, a default parameter is evaluated every time the function is called without the respective parameter. In the example above, `anotherFunction()` is called every time `showMessage()` is called without the `text` parameter. This is in contrast to some other languages like Python, where any default parameters are evaluated only once during the initial interpretation.
+
+```
+
````smart header="Default parameters old-style"
旧版本的 JavaScript 不支持默认参数。所以有其他的方法来支持它们,您可以在旧的脚本中找到。
@@ -263,7 +277,7 @@ function checkAge(age) {
*/!*
} else {
*!*
- return confirm('Got a permission from the parents?');
+ return confirm('Do you have permission from your parents?');
*/!*
}
}
@@ -334,7 +348,11 @@ return*!*;*/!*
## 函数命名 [#function-naming]
+<<<<<<< HEAD
函数是行为。所以它们的名字通常是动词。它应该简短且尽可能准确地描述函数的作用。这样读代码的人就能得到正确的线索。
+=======
+Functions are actions. So their name is usually a verb. It should be brief, as accurate as possible and describe what the function does, so that someone reading the code gets an indication of what the function does.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
一种普遍的做法是用动词前缀来开始一个函数,这个前缀模糊地描述了这个动作。团队内部必须就前缀的含义达成一致。
@@ -366,19 +384,33 @@ checkPermission(..) // 检查权限并返回 true/false
有几个违反这一规则的例子:
+<<<<<<< HEAD
- `getAge` —— 如果它显示一个 `alert` 和这个 age(只应该得到),那就是有问题的。
- `createForm` —— 如果它修改文档,向它添加一个表单(只应该创建它并返回),那就是有问题的。
- `checkPermission` —— 如果显示 `access granted/denied` 消息(只应执行检查并返回结果),那就是错误的。
这些例子具有前缀的共同含义。它们对您的意义取决于您和您的团队。也许您的代码行为不同是很正常的。但是您应该对前缀意味着什么,前缀函数能做什么和不能做什么有一个明确的理解。所有相同的前缀函数都应遵守规则。团队应该分享知识。
+=======
+- `getAge` -- would be bad if it shows an `alert` with the age (should only get).
+- `createForm` -- would be bad if it modifies the document, adding a form to it (should only create it and return).
+- `checkPermission` -- would be bad if it displays the `access granted/denied` message (should only perform the check and return the result).
+
+These examples assume common meanings of prefixes. You and your team are free to agree on other meanings, but usually they're not much different. In any case, you should have a firm understanding of what a prefix means, what a prefixed function can and cannot do. All same-prefixed functions should obey the rules. And the team should share the knowledge.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
```smart header="Ultrashort function names"
常用的函数有时会有**非常短**的名字。
+<<<<<<< HEAD
例如,[jQuery](http://jquery.com) 框架定义函数用 `$`。[LoDash](http://lodash.com/) 库的核心函数命名用 `_`。
这些都是例外,一般而言,函数名应简明扼要且具有描述性。
+=======
+For example, the [jQuery](http://jquery.com) framework defines a function with `$`. The [Lodash](http://lodash.com/) library has its core function named `_`.
+
+These are exceptions. Generally functions names should be concise and descriptive.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 函数 == 注释
diff --git a/1-js/02-first-steps/14-function-basics/function_basics.png b/1-js/02-first-steps/14-function-basics/function_basics.png
index 7eb6e11e54..f5e6f94183 100644
Binary files a/1-js/02-first-steps/14-function-basics/function_basics.png and b/1-js/02-first-steps/14-function-basics/function_basics.png differ
diff --git a/1-js/02-first-steps/14-function-basics/function_basics@2x.png b/1-js/02-first-steps/14-function-basics/function_basics@2x.png
index e629bd712c..c31b2636a6 100644
Binary files a/1-js/02-first-steps/14-function-basics/function_basics@2x.png and b/1-js/02-first-steps/14-function-basics/function_basics@2x.png differ
diff --git a/1-js/02-first-steps/15-function-expressions-arrows/article.md b/1-js/02-first-steps/15-function-expressions-arrows/article.md
index e4f5da2a18..90991c6ba8 100644
--- a/1-js/02-first-steps/15-function-expressions-arrows/article.md
+++ b/1-js/02-first-steps/15-function-expressions-arrows/article.md
@@ -78,8 +78,13 @@ let func = sayHi;
这两种声明的函数是一样的,那么他们有什么不同的地方呢?
+<<<<<<< HEAD
````smart header="Why there's a semicolon at the end?"
这里可能有个疑问,为什么函数表达式结尾有一个 `;`,而函数声明没有:
+=======
+````smart header="Why is there a semicolon at the end?"
+You might wonder, why does Function Expression have a semicolon `;` at the end, but Function Declaration does not:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
function sayHi() {
@@ -175,7 +180,11 @@ ask(
让我们来阐述函数声明和表达式之间的关键区别。
+<<<<<<< HEAD
首先是语法:看下面代码
+=======
+First, the syntax: how to differentiate between them in the code.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- **函数声明:** 函数在主代码流中单独声明。
@@ -185,8 +194,13 @@ ask(
return a + b;
}
```
+<<<<<<< HEAD
- **函数表达式:** 一个函数,在一个表达式中或另一个语法结构中创建。这里,该函数由赋值表达式 `=` 右侧创建:
+=======
+- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created at the right side of the "assignment expression" `=`:
+
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// Function Expression
let sum = function(a, b) {
@@ -198,11 +212,19 @@ ask(
**函数表达式在执行到达时创建并可用。**
+<<<<<<< HEAD
一旦执行到右侧分配 `let sum = function…`,就会创建并可以使用(复制,调用等)。
+=======
+Once the execution flow passes to the right side of the assignment `let sum = function…` -- here we go, the function is created and can be used (assigned, called, etc. ) from now on.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
函数声明则不同。
+<<<<<<< HEAD
**函数声明可用于整个脚本/代码块。**
+=======
+**A Function Declaration is usable in the whole script (or a code block, if it's inside a block).**
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
换句话说,当 JavaScript **准备**运行脚本或代码块时,它首先在其中查找函数声明并创建函数。我们可以将其视为“初始化阶段”。
@@ -350,8 +372,13 @@ welcome(); // ok now
```
+<<<<<<< HEAD
```smart header="When to choose Function Declaration versus Function Expression?"
作为一个经验,当我们需要声明一个函数时,首先要考虑的是函数声明语法,这是我们之前使用的语法。它给如何组织我们的代码提供了更多的自由,因为我们可以在声明它们之前调用这些函数。
+=======
+```smart header="When should you choose Function Declaration versus Function Expression?"
+As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax, the one we used before. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
在代码中查找 `function f(…) {…}` 比 `let f = function(…) {…}` 更容易。
@@ -375,7 +402,7 @@ let func = (arg1, arg2, ...argN) => expression
```js
let func = function(arg1, arg2, ...argN) {
return expression;
-}
+};
```
...精简下。
diff --git a/1-js/02-first-steps/16-javascript-specials/article.md b/1-js/02-first-steps/16-javascript-specials/article.md
index f8c6018e85..efd848be1d 100644
--- a/1-js/02-first-steps/16-javascript-specials/article.md
+++ b/1-js/02-first-steps/16-javascript-specials/article.md
@@ -102,9 +102,14 @@ typeof function(){} == "function" // 函数特殊
## 交互
+<<<<<<< HEAD
我们使用浏览器作为工作环境,所以基本的 UI 功能将是:
[`prompt(question[, default])`](mdn:api/Window/prompt)
: 询问一个问题,并返回访问者输入的内容,如果他按下「取消」则返回 `null`。
+=======
+[`prompt(question, [default])`](mdn:api/Window/prompt)
+: Ask a `question`, and return either what the visitor entered or `null` if they clicked "cancel".
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
[`confirm(question)`](mdn:api/Window/confirm)
: 提出一个问题,并建议在确定和取消之间进行选择。该选项以 `true/false` 形式返回。
@@ -112,7 +117,11 @@ typeof function(){} == "function" // 函数特殊
[`alert(message)`](mdn:api/Window/alert)
: 输出一个 `消息`。
+<<<<<<< HEAD
所有这些函数都会产生**模态框**,它们会暂停代码执行并阻止访问者与页面交互,直到用户输入内容。
+=======
+All these functions are *modal*, they pause the code execution and prevent the visitor from interacting with the page until they answer.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
@@ -148,8 +157,13 @@ JavaScript 支持以下运算符:
三元运算
: 唯一具有三个参数的操作:`cond? resultA: resultB`。如果 `cond` 是真的,则返回 `resultA`,否则返回 `resultB`。
+<<<<<<< HEAD
逻辑运算符
: 逻辑与 `&&` 和或 `||` 执行短路评估,然后返回停止时的值。
+=======
+Logical operators
+: Logical AND `&&` and OR `||` perform short-circuit evaluation and then return the value where it stopped. Logical NOT `!` converts the operand to boolean type and returns the inverse value.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
比较运算符
: 运算符 `==` 将不同类型的值转换为一个数字(除了 `null` 和 `undefined`,它们彼此相等而没有别的情况),所以下面的例子是相等的:
@@ -160,12 +174,25 @@ JavaScript 支持以下运算符:
```
其他比较也转换为数字。
+<<<<<<< HEAD
严格相等运算符 `===` 不会进行转换:不同的类型总是为其指定不同的值,因此:
值 `null` 和 `undefined` 是特殊的:它们只在 `==` 下相等。
字符串按照字符顺序逐一比较,其他类型转换为数字。
逻辑运算符
: 其他合规的运算符比较少,其中有逗号运算符。
+=======
+ Other comparisons convert to a number as well.
+
+ The strict equality operator `===` doesn't do the conversion: different types always mean different values for it.
+
+ Values `null` and `undefined` are special: they equal `==` each other and don't equal anything else.
+
+ Greater/less comparisons compare strings character-by-character, other types are converted to a number.
+
+Other operators
+: There are few others, like a comma operator.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
More in: , , .
更多信息:, , 。
diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md
index 2b69951f14..26aa6d3c39 100644
--- a/1-js/03-code-quality/01-debugging-chrome/article.md
+++ b/1-js/03-code-quality/01-debugging-chrome/article.md
@@ -20,7 +20,11 @@
切换按钮 会打开文件列表的选项卡。
+<<<<<<< HEAD
让我们在预览树中点击和选择 `index.html` 和 `hello.js`。应该会出现这个视图:
+=======
+Let's click it and select `hello.js` in the tree view. Here's what should show up:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb

@@ -34,7 +38,11 @@
## Console(控制台)
+<<<<<<< HEAD
如果我们按下 `Esc`,下面会出现一个控制台,我们可以输入一些命令然后按下 `key:Enter` 来执行。
+=======
+If we press `key:Esc`, then a console opens below. We can type commands there and press `key:Enter` to execute.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
语句执行之后,会将其结果显示在下面。
@@ -56,11 +64,19 @@
当代码被暂停时,我们可以检查当前的变量、在控制台执行命令等等。换句话说,我们可以调试它。
+<<<<<<< HEAD
我们总是可以在右侧的面板中找到断点的列表。当我们在数个文件中有许多断点时,这是非常有用的。
- 快速跳转至代码中的断点(通过点击右侧面板中的对应的断点)。
- 通过取消选中来临时禁用。
- 通过右键单击和选择移除来删除一个断点。
- 等等。
+=======
+We can always find a list of breakpoints in the right pane. That's useful when we have many breakpoints in various files. It allows us to:
+- Quickly jump to the breakpoint in the code (by clicking on it in the right pane).
+- Temporarily disable the breakpoint by unchecking it.
+- Remove the breakpoint by right-clicking and selecting Remove.
+- ...And so on.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```smart header="条件断点"
在行号上**右键单击**允许你创建一个**条件**断点。只有当给定的条件为真(即满足条件)时才会被触发。
@@ -169,10 +185,17 @@ for (let i = 0; i < 5; i++) {
## 总结
+<<<<<<< HEAD
我们可以看到,有 3 种方式来暂停一个脚本:
1. 一个断点。
2. `debugger` 声明。
3. 一个错误(如果开发者工具是打开状态并且按钮 是开启状态)。
+=======
+As we can see, there are three main ways to pause a script:
+1. A breakpoint.
+2. The `debugger` statements.
+3. An error (if dev tools are open and the button is "on").
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
然后我们就能检查变量,并逐步查看执行器在哪里走错路了。
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.png b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.png
index efa3c19df1..abc59905a2 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources@2x.png
index e184bdd01f..546615e30e 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources@2x.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.png
index 2fe449c9b6..caf60ebb61 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint@2x.png
index e4abc89d1f..3f628b6ffc 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint@2x.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.png
index 98b22e777c..0fc22b2ea6 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console@2x.png
index 3269a80f06..f01a7d1017 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console@2x.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.png
index 719293d2e5..424ca26b0a 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause@2x.png
index 5c22ab361b..04cc849d10 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause@2x.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.png
index 1848ccfacf..00507833a3 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1@2x.png
index fcabf722eb..d2a38bf0c9 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1@2x.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.png b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.png
index ff91c531f8..df9e13f3fb 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs@2x.png
index 09b10bf48d..5793bd0596 100644
Binary files a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs@2x.png and b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs@2x.png differ
diff --git a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
index 3ce1ed0d20..8aa0800943 100644
--- a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
+++ b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
@@ -2,6 +2,7 @@
你可以注意到以下几点:
```js no-beautify
+<<<<<<< HEAD
function pow(x,n) // <- 参数之间没有空格
{ // <- 大括号单独一行
let result=1; // <- = 号两边没有空格
@@ -15,11 +16,30 @@ let x=prompt("x?",''), n=prompt("n?",'') // <-- 从技术角度来看是可以
if (n<0) // <- (n < 0) 里面没有空格,并且应该在前面加一个空行
{ // <- 大括号单独一行
// 下面的一行太长了,或许拆分成 2 行更好
+=======
+function pow(x,n) // <- no space between arguments
+{ // <- figure bracket on a separate line
+ let result=1; // <- no spaces before or after =
+ for(let i=0;i>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
alert(`Power ${n} is not supported, please enter an integer number greater than zero`);
}
else // <- 可以像 "} else {" 这样写在一行上
{
+<<<<<<< HEAD
alert(pow(x,n)) // 没有空格和 ;
+=======
+ alert(pow(x,n)) // no spaces and missing ;
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
}
```
diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md
index 47cd5b680b..ec8553087b 100644
--- a/1-js/03-code-quality/02-coding-style/article.md
+++ b/1-js/03-code-quality/02-coding-style/article.md
@@ -1,14 +1,26 @@
+<<<<<<< HEAD
# 代码风格
+=======
+# Coding Style
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
我们的代码必须尽可能的清晰和易读。
+<<<<<<< HEAD
这实际是一种编程艺术 —— 以一种正确并且人类易读的方式编码来完成一个复杂的任务。
有一个帮助你(实现上面的目标)的事情就是良好的代码风格。
+=======
+That is actually the art of programming -- to take a complex task and code it in a way that is both correct and human-readable.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 语法
+<<<<<<< HEAD
一个含有规则的备忘录(更多细节如下):
+=======
+Here is a cheatsheet with some suggested rules (see below for more details):
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb


+<<<<<<< HEAD
总结:
- 对于很短的代码,一行是可以接受的:例如 `if (cond) return null`.
- 但是括号中的每个语句单独一行通常更好些。
@@ -83,12 +110,27 @@ if (n < 0) {
一行的最大长度应该有所限制。没有人喜欢盯着一条长长的水平线。最好把它分割一下。
一行的最大长度在团队层面上达成一致即可。通常是 80 或 120 个字符。
+=======
+In summary:
+- For very short code, one line is acceptable. For example: `if (cond) return null`.
+- But a separate line for each statement in brackets is usually easier to read.
+
+### Line Length
+
+No one likes to read a long horizontal line of code. It's best practice to split them up and limit the length of your lines.
+
+The maximum line length should be agreed upon at the team-level. It's usually 80 or 120 characters.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
### 缩进
有两种类型的缩进:
+<<<<<<< HEAD
- **水平方向上的缩进: 2(4) 个空格。**
+=======
+- **Horizontal indents: 2 or 4 spaces.**
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
一个水平缩进通常由 2 或 4 个空格或者 "Tab" 制表符构成。选择哪一个方式是一场古老的圣战。如今空格更普遍一点。
@@ -107,9 +149,15 @@ if (n < 0) {
}
```
+<<<<<<< HEAD
- **垂直方向上的缩进:用于将逻辑块中的代码进行分割的空行。**
即使是单个函数通常也被分割为数个逻辑块。在下面的例子中,初始化的变量、主要的循环结构和返回值都被垂直分割了。
+=======
+- **Vertical indents: empty lines for splitting code into logical blocks.**
+
+ Even a single function can often be divided into logical blocks. In the example below, the initialization of variables, the main loop and returning the result are split vertically:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
function pow(x, n) {
@@ -125,6 +173,7 @@ if (n < 0) {
插入一个额外的空行有助于让代码更加地易读。连续超过 9 行都没有被垂直分割的代码是不应该出现的。
+<<<<<<< HEAD
### 分号
每一个语句后面都应该有一个分号。即使它可能会被跳过。
@@ -140,6 +189,23 @@ if (n < 0) {
有时候在循环中使用 ["continue"](info:while-for#continue) 指令避免额外的 `if(..) { ... }` 嵌套是一个好主意:
例如:
+=======
+### Semicolons
+
+A semicolon should be present after each statement, even if it could possibly be skipped.
+
+There are languages where a semicolon is truly optional and it is rarely used. In JavaScript, though, there are cases where a line break is not interpreted as a semicolon, leaving the code vulnerable to errors.
+
+As you become more mature as a programmer, you may choose a no-semicolon style like [StandardJS](https://standardjs.com/). Until then, it's best to use semicolons to avoid possible pitfalls.
+
+### Nesting Levels
+
+Try to avoid nesting code too many levels deep.
+
+Sometimes it's a good idea to use the ["continue"](info:while-for#continue) directive in a loop to avoid extra nesting.
+
+For example, instead of adding a nested `if` conditional like this:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
for (let i = 0; i < 10; i++) {
@@ -162,7 +228,11 @@ for (let i = 0; i < 10; i++) {
例如,下面的两个结构是相同的。
+<<<<<<< HEAD
第一个:
+=======
+Option 1:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
function pow(x, n) {
@@ -180,7 +250,11 @@ function pow(x, n) {
}
```
+<<<<<<< HEAD
还有这个:
+=======
+Option 2:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
function pow(x, n) {
@@ -199,6 +273,7 @@ function pow(x, n) {
}
```
+<<<<<<< HEAD
但是第二个更加的可读,因为 `n < 0` 这个”边缘情况“已经提前被处理过,并且我们有一个 ”主“ 代码流,而不需要额外的嵌套。
## 函数在代码下面
@@ -206,6 +281,15 @@ function pow(x, n) {
如果你正在写几个”辅助类“的函数和一些使用它们的代码,有三种方式来放置它们。
1. 函数在调用它们的那些代码之上:
+=======
+The second one is more readable because the "edge case" of `n < 0` is handled early on. Once the check is done we can move on to the "main" code flow without the need for additional nesting.
+
+## Function Placement
+
+If you are writing several "helper" functions and the code that uses them, there are three ways to organize the functions.
+
+1. Functions declared above the code that uses them:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// *!*函数声明*/!*
@@ -235,7 +319,6 @@ function pow(x, n) {
walkAround();
// --- *!*helper functions*/!* ---
-
function createElement() {
...
}
@@ -248,10 +331,15 @@ function pow(x, n) {
...
}
```
+<<<<<<< HEAD
3. 混合,函数定义在它第一次被使用的地方。
+=======
+3. Mixed: a function is declared where it's first used.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
大多数时候,第二种方式更好。
+<<<<<<< HEAD
这是因为当在阅读代码时,我们首先想要知道的是“它做了什么”。如果代码先行,它就会提供这些信息。或许我们一点也不需要阅读这些函数,尤其是他们的名字足够表示出他们做了什么的时候。
## 风格指南
@@ -263,11 +351,25 @@ function pow(x, n) {
当然,一个团队可能会考虑一个他们自己的风格指南。但是现在,他们没必要这样做。现在有很多已经尝试过并制作好的风格指南,可以很容易采用。
例如:
+=======
+That's because when reading code, we first want to know *what it does*. If the code goes first, then it provides that information. Then, maybe we won't need to read the functions at all, especially if their names are descriptive of what they actually do.
+
+## Style Guides
+
+A style guide contains general rules about "how to write" code, e.g. which quotes to use, how many spaces to indent, where to put line breaks, etc. A lot of minor things.
+
+When all members of a team use the same style guide, the code looks uniform, regardless of which team member wrote it.
+
+Of course, a team can always write their own style guide. Most of the time though, there's no need to. There are many existing tried and true options to choose from, so adopting one of these is usually your best bet.
+
+Some popular choices:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- [Google JavaScript 风格指南](https://google.github.io/styleguide/javascriptguide.xml)
- [Airbnb JavaScript 风格指南](https://github.com/airbnb/javascript)
- [Idiomatic.JS](https://github.com/rwaldron/idiomatic.js)
- [StandardJS](https://standardjs.com/)
+<<<<<<< HEAD
- (还有很多)
如果你是一个初学者,你可以从本章中上面的内容开始,然后浏览风格指南并提取出常见规则或者选择一个。
@@ -281,6 +383,19 @@ function pow(x, n) {
因此推荐你安装一个,即使你不想坚持某个 "code style"。它们会帮你找出书写错误 —— 这就已经足够好了。
最出名的工具有:
+=======
+- (plus many more)
+
+If you're a novice developer, start with the cheatsheet at the beginning of this chapter. Once you've mastered that you can browse other style guides to pick up common principles and decide which one you like best.
+
+## Automated Linters
+
+Linters are tools that can automatically check the style of your code and make suggestions for refactoring.
+
+The great thing about them is that style-checking can also find some bugs, like typos in variable or function names. Because of this feature, installing a linter is recommended even if you don't want to stick to one particular "code style".
+
+Here are the most well-known linting tools:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- [JSLint](http://www.jslint.com/) -- 第一批 linters 之一。
- [JSHint](http://www.jshint.com/) -- 比 JSLint 多了更多设置。
@@ -288,15 +403,28 @@ function pow(x, n) {
它们都能够做这些工作。笔者使用 [ESLint](http://eslint.org/).
+<<<<<<< HEAD
大多数 linters 都可以与编辑器集成在一起:只需在编辑器中启用插件并配置风格即可。
+=======
+Most linters are integrated with many popular editors: just enable the plugin in the editor and configure the style.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如,要使用 ESLint 你应该这样做:
+<<<<<<< HEAD
1. 安装 [Node.JS](https://nodejs.org/).
2. 使用 `npm install -g eslint` 命令(npm 是 Node.JS 的包安装工具)安装 ESLint。
3. 在你项目的根目录(包含你所有文件的那个目录)创建一个名叫 `.eslintrc` 的配置文件。
这有一个 `.eslintrc` 的例子:
+=======
+1. Install [Node.js](https://nodejs.org/).
+2. Install ESLint with the command `npm install -g eslint` (npm is a JavaScript package installer).
+3. Create a config file named `.eslintrc` in the root of your JavaScript project (in the folder that contains all your files).
+4. Install/enable the plugin for your editor that integrates with ESLint. The majority of editors have one.
+
+Here's an example of an `.eslintrc` file:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
{
@@ -313,6 +441,7 @@ function pow(x, n) {
}
```
+<<<<<<< HEAD
这里的 `"extends"` 指令表示我们是基于 "eslint:recommended" 的设置项而进行设置的,并且我们还制定了我们自己的规则。
在你的编辑器中安装 / 启用插件以和 ESLint 集成。大多数编辑都有的。
@@ -324,11 +453,26 @@ function pow(x, n) {
因此即使你不关心风格,也推荐你使用一个 linter。
某些 IDE 还支持内置的 linting,但不像 ESLint 那么灵活可配置。
+=======
+Here the directive `"extends"` denotes that the configuration is based on the "eslint:recommended" set of settings. After that, we specify our own.
+
+It is also possible to download style rule sets from the web and extend them instead. See for more details about installation.
+
+Also certain IDEs have built-in linting, which is convenient but not as customizable as ESLint.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 总结
+<<<<<<< HEAD
本章的所有语法规则和样式指南旨在提高可读性,因此所有的内容都是值得商榷的。
当我们思考“如何写地更好”的时候,唯一的标准是“什么会让代码更加可读和容易理解,什么会帮助我们避免错误”。这是当选择一种风格或讨论哪一种更好的时候要牢记的主要原则。
阅读风格指南,以查看相关的最新想法,并遵循那些你发现的最好的。
+=======
+All syntax rules described in this chapter (and in the style guides referenced) aim to increase the readability of your code, but all of them are debatable.
+
+When we think about writing "better" code, the questions we should ask are, "What makes the code more readable and easier to understand?" and "What can help us avoid errors?" These are the main things to keep in mind when choosing and debating code styles.
+
+Reading popular style guides will allow you to keep up to date with the latest ideas about code style trends and best practices.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/03-code-quality/02-coding-style/code-style.png b/1-js/03-code-quality/02-coding-style/code-style.png
index 278fd294cf..1c6d355dd5 100644
Binary files a/1-js/03-code-quality/02-coding-style/code-style.png and b/1-js/03-code-quality/02-coding-style/code-style.png differ
diff --git a/1-js/03-code-quality/02-coding-style/code-style@2x.png b/1-js/03-code-quality/02-coding-style/code-style@2x.png
index b576143455..832623d9c1 100644
Binary files a/1-js/03-code-quality/02-coding-style/code-style@2x.png and b/1-js/03-code-quality/02-coding-style/code-style@2x.png differ
diff --git a/1-js/03-code-quality/02-coding-style/figure-bracket-style.png b/1-js/03-code-quality/02-coding-style/figure-bracket-style.png
index 112c2803ed..b04db65c67 100644
Binary files a/1-js/03-code-quality/02-coding-style/figure-bracket-style.png and b/1-js/03-code-quality/02-coding-style/figure-bracket-style.png differ
diff --git a/1-js/03-code-quality/02-coding-style/figure-bracket-style@2x.png b/1-js/03-code-quality/02-coding-style/figure-bracket-style@2x.png
index ce6e75c4dd..0e994ca4b3 100644
Binary files a/1-js/03-code-quality/02-coding-style/figure-bracket-style@2x.png and b/1-js/03-code-quality/02-coding-style/figure-bracket-style@2x.png differ
diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md
index c83bac1011..7f5609a3ae 100644
--- a/1-js/03-code-quality/03-comments/article.md
+++ b/1-js/03-code-quality/03-comments/article.md
@@ -162,7 +162,11 @@ function addJuice(container) {
## 总结
+<<<<<<< HEAD
一个好的开发者的标志之一就是他的注释:它们的存在甚至它们的缺席。
+=======
+An important sign of a good developer is comments: their presence and even their absence.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
好的注释可以使我们更好的维护代码,并且在很长时间之后依然可以更高效地回到代码中和使用其功能。
diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md
index 2f9b55d219..58f6c6be16 100644
--- a/1-js/03-code-quality/04-ninja-code/article.md
+++ b/1-js/03-code-quality/04-ninja-code/article.md
@@ -5,7 +5,11 @@
学而不思则罔,思而不学则殆。
```
+<<<<<<< HEAD
过去的程序员忍者使用这些技巧来使代码维护者的头脑更加敏锐。
+=======
+Programmer ninjas of the past used these tricks to sharpen the mind of code maintainers.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
代码审查大师在测试任务中寻找它们。
@@ -32,9 +36,15 @@
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
```
+<<<<<<< HEAD
很酷,对吗?如果你这样写了,那些看到这一行代码并尝试去理解 `i` 的值是什么的开发者们就会有一个“快活的”的时光了。然后会来找你寻求答案。
告诉他短一点总是更好的。引导他进入忍者之路。
+=======
+Cool, right? If you write like that, a developer who comes across this line and tries to understand what is the value of `i` is going to have a merry time. Then come to you, seeking for an answer.
+
+Tell them that shorter is always better. Initiate them into the paths of ninja.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 一个字母的变量
@@ -44,11 +54,19 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
编码更快(也更糟糕)的另一种方式是到处使用单字母的变量名。像是 `a`、`b` 或 `c`。
+<<<<<<< HEAD
短变量会像森林中真正的忍者一样在代码中消失不见。没有人能够通过编辑器的“搜索”找到它。即使有人做到了,他也不能“破译”出变量名 `a` 或 `b` 是什么意思。
+=======
+A short variable disappears in the code like a real ninja in the forest. No one will be able to find it using "search" of the editor. And even if someone does, they won't be able to "decipher" what the name `a` or `b` means.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
...但是有一个例外情况。一个真正的忍者绝不会在 `"for"` 循环中使用 `i` 作为计数器。在任何地方都可以,但是这里不会用。看一下四周吧,还有很多不常用的字母呢。例如 `x` 或 `y`。
+<<<<<<< HEAD
如果循环体能够达到 1-2 页(如果可以的话可以让它更长)那么长的话,使用一个不常用的变量作为循环的计数器就更酷了。如果某人看到循环内部的深处后,他就不能很快地找出变量 `x` 是循环计数器啦。
+=======
+An exotic variable as a loop counter is especially cool if the loop body takes 1-2 pages (make it longer if you can). Then if someone looks deep inside the loop, they won't be able to quickly figure out that the variable named `x` is the loop counter.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 使用缩写
@@ -82,7 +100,11 @@ i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
尝试一下吧。新手可能会诧异 —— 这些名字对于忍者来说真的有用吗?事实上,是的!
+<<<<<<< HEAD
一方面,变量名仍然有着一些含义。它说明了变量内是什么:一个字符串、一个数字或是其他的东西。但是当一个局外人试图理解代码时,他会惊讶地发现实际上没有任何有效信息!最终无法改变你精心思考过的代码。
+=======
+ Sure, the variable name still means something. It says what's inside the variable: a string, a number or something else. But when an outsider tries to understand the code, they'll be surprised to see that there's actually no information at all! And will ultimately fail to alter your well-thought code.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
事实上,值的类型很容易就能通过调试看出来。但是变量名的含义呢?它存了哪一个字符串/数字?
@@ -152,9 +174,15 @@ function ninjaFunction(elem) {
}
```
+<<<<<<< HEAD
想要在第二部分中使用 `elem` 的程序员会非常的诧异滴...只有在调试期间,在检查代码之后,他会发现他正在使用克隆过的变量!
经常看到这样的代码,即使对经验丰富的忍者来说也是致命的。
+=======
+A fellow programmer who wants to work with `elem` in the second half of the function will be surprised... Only during the debugging, after examining the code they will find out that they're working with a clone!
+
+Seen in code regularly. Deadly effective even against an experienced ninja.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 下划线的乐趣
@@ -170,7 +198,13 @@ function ninjaFunction(elem) {
事实上,从一方面来说,看似写了一些东西:`super..`、`mega..`、`nice..`,但是从另一方面来说 —— 并没有提供任何细节。读者可能要寻找一个隐藏的含义或深思一两个小时。
+<<<<<<< HEAD
## 重叠外部变量
+=======
+
+
+## Overlap outer variables
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```quote author="关尹子"
处明者不见暗中一物
,
@@ -194,7 +228,11 @@ function render() {
跳过 `render` 的程序员可能不会注意到有一个本地 `user` 遮挡外部的 `user` 了。
+<<<<<<< HEAD
然后他会假设 `user` 仍然是外部的变量然后使用它,`authenticateUser()` 的结果... 陷阱出来啦!你好呀,调试器...
+=======
+Then they'll try to work with `user` assuming that it's the external variable, the result of `authenticateUser()`... The trap is sprung! Hello, debugger...
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 无处不在的副作用!
@@ -203,7 +241,11 @@ function render() {
**一个非常好的技巧 - 除了主要任务之外,还要向它们添加一个“有用的”动作**
+<<<<<<< HEAD
当你的同事看到被命名为 `is..`、`check..` 或 `find...` 的函数改变了某些东西的时候,他的脸上肯定是一脸懵逼的状态。
+=======
+An expression of dazed surprise on the face of your colleague when they see a function named `is..`, `check..` or `find...` changing something -- will definitely broaden your boundaries of reason.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
**另一种惊喜的方式是返回非标准的结果。**
@@ -226,7 +268,11 @@ function render() {
**将多个动作加入到一起可以保护您的代码避免重用。**
+<<<<<<< HEAD
想象一下,另一个开发者只想检查邮箱而不想输出任何信息。你的函数 `validateEmail(email)` 对他而言就不合适啦。所以他不会找你问一些关于这些函数的事情从而打断你的思考。
+=======
+Imagine, another developer wants only to check the email, and not output any message. Your function `validateEmail(email)` that does both will not suit them. So they won't break your meditation by asking anything about it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 总结
diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md
index 988534045f..5601291113 100644
--- a/1-js/03-code-quality/05-testing-mocha/article.md
+++ b/1-js/03-code-quality/05-testing-mocha/article.md
@@ -96,7 +96,11 @@ describe("pow", function() {
```html src="index.html"
```
+<<<<<<< HEAD
该页面可分为四部分:
+=======
+The page can be divided into five parts:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
1. `` -- 为测试添加第三方库和样式文件。
2. `
diff --git a/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js
index 10a032d03a..e5ce2ce433 100644
--- a/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js
+++ b/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js
@@ -1,6 +1,6 @@
describe("pow", function() {
- describe("raises x to power n", function() {
+ describe("raises x to power 3", function() {
function makeTest(x) {
let expected = x * x * x;
diff --git a/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js
index a5a3459795..75ff5e99fd 100644
--- a/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js
+++ b/1-js/03-code-quality/05-testing-mocha/pow-full.view/test.js
@@ -1,6 +1,6 @@
describe("pow", function() {
- describe("raises x to power n", function() {
+ describe("raises x to power 3", function() {
function makeTest(x) {
let expected = x * x * x;
diff --git a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js
index a5a3459795..75ff5e99fd 100644
--- a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js
+++ b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/test.js
@@ -1,6 +1,6 @@
describe("pow", function() {
- describe("raises x to power n", function() {
+ describe("raises x to power 3", function() {
function makeTest(x) {
let expected = x * x * x;
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index 4dfc4de49b..6bb97796da 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -19,21 +19,38 @@ JavaScript 引擎背后的团队关于首先要实现什么有着他们自己想
实际上,Babel 包含了两部分:
+<<<<<<< HEAD
1. 第一,transpiler 程序,就是重写代码的那个。开发者在他自己的电脑上运行它。它将代码重写到旧的标准中。然后将代码交付给用户的网站。诸如 [webpack](http://webpack.github.io/) 或 [brunch](http://brunch.io/) 这样的现代项目构建系统提供了每当代码改变都会自动运行 transpiler 的方法,因此我们这边没有任何的时间损失。
+=======
+1. First, the transpiler program, which rewrites the code. The developer runs it on their own computer. It rewrites the code into the older standard. And then the code is delivered to the website for users. Modern project build system like [webpack](http://webpack.github.io/) provide means to run transpiler automatically on every code change, so that very easy to integrate into development process.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
2. 第二,polyfill。
+<<<<<<< HEAD
transpiler 会重写代码,因此现有的语法特性都被覆盖了。但是对于新特性我们需要写一个特殊的脚本来实现它们。JavaScript 是一个高度动态化的语言。脚本可能不仅是添加一些新特性,还会修改一些内置特性,以便于它们表现得符合现代标准。
脚本有一个术语 "polyfill" 表示用来“填补”缺口并添加缺少的实现。
+=======
+ New language features may include new built-in functions and syntax constructs.
+ The transpiler rewrites the code, transforming syntax constructs into older ones. But as for new built-in functions, we need to implement them. JavaScript is a highly dynamic language, scripts may add/modify any functions, so that they behave according to the modern standard.
+
+ A script that updates/adds new functions is called "polyfill". It "fills in" the gap and adds missing implementations.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
两个有意思的 polyfills 是:
- [babel polyfill](https://babeljs.io/docs/usage/polyfill/) 支持很多,但是很大。
- [polyfill.io](http://polyfill.io) 服务允许我们能根据自己所需的特性来按需加载、构建 polyfill。
+<<<<<<< HEAD
因此,我们需要为那些旧引擎设置 transpiler 并添加 polyfill 来支持现代特性。
如果我们的目标是现代引擎,并且整个项目不使用其他地方不支持的特性,那么我们就不需要使用 Babel。
+=======
+So, if we're going to use modern language features, a transpiler and a polyfill are necessary.
+
+## Examples in the tutorial
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 教程中的案例
@@ -48,9 +65,16 @@ alert('Press the "Play" button in the upper-right corner to run');
````
```offline
+<<<<<<< HEAD
当你正在阅读离线版本时,例子是不可运行的。但是它们通常是可以工作的。:)
```
[Chrome Canary](https://www.google.com/chrome/browser/canary.html) 适用于所有示例,但其他现代浏览器大多数也都很好。
需要注意的是,在生产环境中我们可以用 Babel 来将代码转换为适合少数近代浏览器的代码,所以它们没有这样的限制,代码会在任何地方运行。
+=======
+As you're reading the offline version, in PDF examples are not runnable. In EPUB some of them can run.
+```
+
+Google Chrome is usually the most up-to-date with language features, good to run bleeding-edge demos without any transpilers, but other modern browsers also work fine.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js b/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js
index 4bec82dd37..08089f6dba 100644
--- a/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js
+++ b/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js
@@ -1,7 +1,11 @@
function isEmpty(obj) {
for (let key in obj) {
+<<<<<<< HEAD
// 如果进到循环里面,说明有属性。
+=======
+ // if the loop has started, there is a property
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
return false;
}
return true;
-}
\ No newline at end of file
+}
diff --git a/1-js/04-object-basics/01-object/3-is-empty/solution.md b/1-js/04-object-basics/01-object/3-is-empty/solution.md
index 663c81b3fd..7d53fd7375 100644
--- a/1-js/04-object-basics/01-object/3-is-empty/solution.md
+++ b/1-js/04-object-basics/01-object/3-is-empty/solution.md
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
遍历一个对象,如果对象存在任何属性则 `return false`。
```js
@@ -8,3 +9,6 @@ function isEmpty(obj) {
return true;
}
```
+=======
+Just loop over the object and `return false` immediately if there's at least one property.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/04-object-basics/01-object/4-const-object/task.md b/1-js/04-object-basics/01-object/4-const-object/task.md
index a2997a1304..46e62472d1 100644
--- a/1-js/04-object-basics/01-object/4-const-object/task.md
+++ b/1-js/04-object-basics/01-object/4-const-object/task.md
@@ -4,7 +4,11 @@ importance: 5
# 不可变对象
+<<<<<<< HEAD
有可能改变 `const` 修饰的对象吗, 你怎么看呢?
+=======
+Is it possible to change an object declared with `const`? What do you think?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
const user = {
diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md
index 7153f2b71c..ca96f297fd 100644
--- a/1-js/04-object-basics/01-object/article.md
+++ b/1-js/04-object-basics/01-object/article.md
@@ -1,8 +1,12 @@
# 对象
+<<<<<<< HEAD
正如我们从《引言:类型》那章中知道的那样,JavaScript 中有七种数据类型。有六种原始类型,因为他们的值只包含一种东西(字符串,数值或者其他)。
相反,对象用来存储键值对和更复杂的实体。在 JavaScript 中,对象深入到这门语言的方方面面。所以在我们深入理解这门语言之前,必须先理解对象。
+=======
+As we know from the chapter , there are seven data types in JavaScript. Six of them are called "primitive", because their values contain only a single thing (be it a string or a number or whatever).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
对象可以通过花括号 `{…}` 和其中包含一些可选的**属性**来创建。属性是一个键值对,键是一个字符串(也叫做属性名),值可以是任何类型。
@@ -201,7 +205,7 @@ let obj = {
for: 1,
let: 2,
return: 3
-}
+};
alert( obj.for + obj.let + obj.return ); // 6
```
@@ -216,12 +220,22 @@ alert(obj.__proto__); // [object Object],这样不行
我们从代码中可以看出来,把它赋值成 `5` 被忽略了。
+<<<<<<< HEAD
如果我们蓄意去存储随机的键值对或者允许一个访问者去指定键,那可能就会产生很多 bug 并且使对象变得危险。
+=======
+That can become a source of bugs and even vulnerabilities if we intend to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
比如,访问者可能选择 "__proto__" 作为键,这个赋值的逻辑就失败了(像上面那样)。
+<<<<<<< HEAD
有一种让对象把 `__proto__` 作为属性的方法,在后面章节会讲到,现在我们先来学习对象的更多知识。
还有另外一种数据结构 [Map](info:map-set-weakmap-weakset),我们会在后面章节学到,它支持任意的键值。
+=======
+There is a way to make objects treat `__proto__` as a regular property, which we'll cover later, but first we need to know more about objects.
+There's also another data structure [Map](info:map-set-weakmap-weakset), that we'll learn in the chapter , which supports arbitrary keys.
+````
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
@@ -295,7 +309,13 @@ alert( "age" in user ); // true,user.age 存在
alert( "blabla" in user ); // false,user.blabla 不存在。
```
+<<<<<<< HEAD
注意 `in` 的左边必须是**属性名**。通常是一个字符串,如果不用字符串,那就是一个字符串变量。
+=======
+Please note that on the left side of `in` there must be a *property name*. That's usually a quoted string.
+
+If we omit quotes, that would mean a variable containing the actual name will be tested. For instance:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let user = { age: 30 };
@@ -333,8 +353,13 @@ alert( "test" in obj ); // true,属性存在!
语法:
```js
+<<<<<<< HEAD
for(key in object) {
// 各个属性键值的执行区
+=======
+for (key in object) {
+ // executes the body for each key among object properties
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
}
```
@@ -347,7 +372,7 @@ let user = {
isAdmin: true
};
-for(let key in user) {
+for (let key in user) {
// keys
alert( key ); // name, age, isAdmin
// 属性键的值
@@ -355,7 +380,13 @@ for(let key in user) {
}
```
+<<<<<<< HEAD
注意,所有的 "for" 都允许我们在循环中定义变量,像 `let key` 这样。
+=======
+Note that all "for" constructs allow us to declare the looping variable inside the loop, like `let key` here.
+
+Also, we could use another variable name here instead of `key`. For instance, `"for (let prop in obj)"` is also widely used.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
同样,我们可以用其他属性名来代替 `key`。例如 `"for(let prop in obj)"` 也很常用。
@@ -377,7 +408,7 @@ let codes = {
};
*!*
-for(let code in codes) {
+for (let code in codes) {
alert(code); // 1, 41, 44, 49
}
*/!*
@@ -435,7 +466,7 @@ let codes = {
"+1": "USA"
};
-for(let code in codes) {
+for (let code in codes) {
alert( +code ); // 49, 41, 44, 1
}
```
@@ -598,8 +629,13 @@ for (let key in user) {
}
*/!*
+<<<<<<< HEAD
// 现在复制是独立的复制了
clone.name = "Pete"; // 改变它的值
+=======
+// now clone is a fully independent clone
+clone.name = "Pete"; // changed the data in it
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
alert( user.name ); // 原对象属性值不变
```
@@ -609,7 +645,7 @@ alert( user.name ); // 原对象属性值不变
语法是:
```js
-Object.assign(dest[, src1, src2, src3...])
+Object.assign(dest, [src1, src2, src3...])
```
- 参数 `dest` 和 `src1, ..., srcN`(可以有很多个)是对象。
@@ -692,7 +728,14 @@ user.sizes.width++; // 在这里改变一个属性的值
alert(clone.sizes.width); // 51,在这里查看属性的值
```
+<<<<<<< HEAD
为了解决上面的的问题,我们在复制的时候应该检查 `user[key]` 的每一个值,如果是一个对象,我们再复制一遍这个对象,这叫做深拷贝。
+=======
+To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
+
+There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](http://w3c.github.io/html/infrastructure.html#safe-passing-of-structured-data). In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library [lodash](https://lodash.com), the method is called [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
+
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
有一个标准的深拷贝算法,解决上面和一些更复杂的情况,叫做 [Structured cloning algorithm](https://w3c.github.io/html/infrastructure.html#internal-structured-cloning-algorithm)。为了不重复造轮子,我们使用它的一个 JS 实现的库 [lodash](https://lodash.com), 方法名叫做 [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep)。
@@ -708,10 +751,17 @@ alert(clone.sizes.width); // 51,在这里查看属性的值
- 点符号: `obj.property`。
- 方括号 `obj["property"]`,方括号中可以使用变量 `obj[varWithKey]`。
+<<<<<<< HEAD
其他操作:
- 删除属性:`delete obj.prop`。
- 检查属性是否存在:`"key" in obj`。
- 遍历对象:`for(let key in obj)` 循环。
+=======
+Additional operators:
+- To delete a property: `delete obj.prop`.
+- To check if a property with the given key exists: `"key" in obj`.
+- To iterate over an object: `for (let key in obj)` loop.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
对象根据引用来赋值或者复制。换句话说,变量存的不是对象的"值",而是值的 "引用"(内存地址)。
所以复制变量或者传递变量到方法中只是复制了对象的引用。
diff --git a/1-js/04-object-basics/01-object/object-user-delete.png b/1-js/04-object-basics/01-object/object-user-delete.png
index 688158f9b0..8702675c81 100644
Binary files a/1-js/04-object-basics/01-object/object-user-delete.png and b/1-js/04-object-basics/01-object/object-user-delete.png differ
diff --git a/1-js/04-object-basics/01-object/object-user-delete@2x.png b/1-js/04-object-basics/01-object/object-user-delete@2x.png
index e1ef655414..698766bb0a 100644
Binary files a/1-js/04-object-basics/01-object/object-user-delete@2x.png and b/1-js/04-object-basics/01-object/object-user-delete@2x.png differ
diff --git a/1-js/04-object-basics/01-object/object-user-empty.png b/1-js/04-object-basics/01-object/object-user-empty.png
index 483d072c6d..6b1f27a690 100644
Binary files a/1-js/04-object-basics/01-object/object-user-empty.png and b/1-js/04-object-basics/01-object/object-user-empty.png differ
diff --git a/1-js/04-object-basics/01-object/object-user-empty@2x.png b/1-js/04-object-basics/01-object/object-user-empty@2x.png
index 8db894cb3b..5f261eca41 100644
Binary files a/1-js/04-object-basics/01-object/object-user-empty@2x.png and b/1-js/04-object-basics/01-object/object-user-empty@2x.png differ
diff --git a/1-js/04-object-basics/01-object/object-user-isadmin.png b/1-js/04-object-basics/01-object/object-user-isadmin.png
index 4e76eeb76a..2ce66a49d3 100644
Binary files a/1-js/04-object-basics/01-object/object-user-isadmin.png and b/1-js/04-object-basics/01-object/object-user-isadmin.png differ
diff --git a/1-js/04-object-basics/01-object/object-user-isadmin@2x.png b/1-js/04-object-basics/01-object/object-user-isadmin@2x.png
index b409776903..4a15dac64b 100644
Binary files a/1-js/04-object-basics/01-object/object-user-isadmin@2x.png and b/1-js/04-object-basics/01-object/object-user-isadmin@2x.png differ
diff --git a/1-js/04-object-basics/01-object/object-user-props.png b/1-js/04-object-basics/01-object/object-user-props.png
index 2bfdfabdb3..b0486e900e 100644
Binary files a/1-js/04-object-basics/01-object/object-user-props.png and b/1-js/04-object-basics/01-object/object-user-props.png differ
diff --git a/1-js/04-object-basics/01-object/object-user-props@2x.png b/1-js/04-object-basics/01-object/object-user-props@2x.png
index 4935b59ce8..20859fe911 100644
Binary files a/1-js/04-object-basics/01-object/object-user-props@2x.png and b/1-js/04-object-basics/01-object/object-user-props@2x.png differ
diff --git a/1-js/04-object-basics/01-object/object-user.png b/1-js/04-object-basics/01-object/object-user.png
index 16179209f3..6215b82079 100644
Binary files a/1-js/04-object-basics/01-object/object-user.png and b/1-js/04-object-basics/01-object/object-user.png differ
diff --git a/1-js/04-object-basics/01-object/object-user@2x.png b/1-js/04-object-basics/01-object/object-user@2x.png
index 7203895324..c66fa5159b 100644
Binary files a/1-js/04-object-basics/01-object/object-user@2x.png and b/1-js/04-object-basics/01-object/object-user@2x.png differ
diff --git a/1-js/04-object-basics/01-object/object.png b/1-js/04-object-basics/01-object/object.png
index f94d094a96..a853c9c393 100644
Binary files a/1-js/04-object-basics/01-object/object.png and b/1-js/04-object-basics/01-object/object.png differ
diff --git a/1-js/04-object-basics/01-object/object@2x.png b/1-js/04-object-basics/01-object/object@2x.png
index 003c2f6eab..12011ff5c7 100644
Binary files a/1-js/04-object-basics/01-object/object@2x.png and b/1-js/04-object-basics/01-object/object@2x.png differ
diff --git a/1-js/04-object-basics/01-object/variable-contains-reference.png b/1-js/04-object-basics/01-object/variable-contains-reference.png
index d6e7fddff6..cdd53d0b2d 100644
Binary files a/1-js/04-object-basics/01-object/variable-contains-reference.png and b/1-js/04-object-basics/01-object/variable-contains-reference.png differ
diff --git a/1-js/04-object-basics/01-object/variable-contains-reference@2x.png b/1-js/04-object-basics/01-object/variable-contains-reference@2x.png
index 145bad29af..0701261980 100644
Binary files a/1-js/04-object-basics/01-object/variable-contains-reference@2x.png and b/1-js/04-object-basics/01-object/variable-contains-reference@2x.png differ
diff --git a/1-js/04-object-basics/01-object/variable-copy-reference.png b/1-js/04-object-basics/01-object/variable-copy-reference.png
index 97510c4b21..2870858420 100644
Binary files a/1-js/04-object-basics/01-object/variable-copy-reference.png and b/1-js/04-object-basics/01-object/variable-copy-reference.png differ
diff --git a/1-js/04-object-basics/01-object/variable-copy-reference@2x.png b/1-js/04-object-basics/01-object/variable-copy-reference@2x.png
index a64238a52b..e7b994c534 100644
Binary files a/1-js/04-object-basics/01-object/variable-copy-reference@2x.png and b/1-js/04-object-basics/01-object/variable-copy-reference@2x.png differ
diff --git a/1-js/04-object-basics/01-object/variable-copy-value.png b/1-js/04-object-basics/01-object/variable-copy-value.png
index e21af09907..c360a0e132 100644
Binary files a/1-js/04-object-basics/01-object/variable-copy-value.png and b/1-js/04-object-basics/01-object/variable-copy-value.png differ
diff --git a/1-js/04-object-basics/01-object/variable-copy-value@2x.png b/1-js/04-object-basics/01-object/variable-copy-value@2x.png
index 2f0b2f47d4..323bc46224 100644
Binary files a/1-js/04-object-basics/01-object/variable-copy-value@2x.png and b/1-js/04-object-basics/01-object/variable-copy-value@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/article.md b/1-js/04-object-basics/02-garbage-collection/article.md
index 79a63115d2..6c8295205b 100644
--- a/1-js/04-object-basics/02-garbage-collection/article.md
+++ b/1-js/04-object-basics/02-garbage-collection/article.md
@@ -207,6 +207,10 @@ JavaScript 引擎做了许多优化,使其运行速度更快,并且不会影
如果你熟悉低级编程,关于 V8 引擎垃圾回收器的更详细信息请参阅文章 [V8 的垃圾回收:垃圾回收](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection)。
+<<<<<<< HEAD
[V8 博客](http://v8project.blogspot.com/)还不时发布关于内存管理变化的文章。当然,为了学习垃圾收集,你最好通过学习 V8 引擎内部知识来进行准备,并阅读一个叫 [Vyacheslav Egorov](http://mrale.ph) 的 V8 引擎工程师的博客。我之所以说『V8』,因为它最容易在互联网上找到文章。对于其他引擎,许多方法是相似的,但在垃圾收集上许多方面有所不同。
+=======
+[V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn the garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](http://mrale.ph) who worked as one of V8 engineers. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
当你需要低级别的优化时,对引擎的深入了解是很好的。在熟悉了该语言之后,把熟悉引擎作为下一步是明智的。
diff --git a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.png b/1-js/04-object-basics/02-garbage-collection/family-delete-refs.png
index 5c10f0e47e..05160890e2 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.png and b/1-js/04-object-basics/02-garbage-collection/family-delete-refs.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family-delete-refs@2x.png b/1-js/04-object-basics/02-garbage-collection/family-delete-refs@2x.png
index 24d29630e5..a92fc573b6 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-delete-refs@2x.png and b/1-js/04-object-basics/02-garbage-collection/family-delete-refs@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-family.png b/1-js/04-object-basics/02-garbage-collection/family-no-family.png
index a4ce30a354..e60f9b88d8 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-no-family.png and b/1-js/04-object-basics/02-garbage-collection/family-no-family.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-family@2x.png b/1-js/04-object-basics/02-garbage-collection/family-no-family@2x.png
index 0d9949839e..7549037060 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-no-family@2x.png and b/1-js/04-object-basics/02-garbage-collection/family-no-family@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father-2.png b/1-js/04-object-basics/02-garbage-collection/family-no-father-2.png
index e24dba5b57..823d0a618c 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-no-father-2.png and b/1-js/04-object-basics/02-garbage-collection/family-no-father-2.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father-2@2x.png b/1-js/04-object-basics/02-garbage-collection/family-no-father-2@2x.png
index a6c4ee36a3..9e100d522a 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-no-father-2@2x.png and b/1-js/04-object-basics/02-garbage-collection/family-no-father-2@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father.png b/1-js/04-object-basics/02-garbage-collection/family-no-father.png
index df14624bc0..5ddb6f68ff 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-no-father.png and b/1-js/04-object-basics/02-garbage-collection/family-no-father.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father@2x.png b/1-js/04-object-basics/02-garbage-collection/family-no-father@2x.png
index 5ab4b37920..868c748a06 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family-no-father@2x.png and b/1-js/04-object-basics/02-garbage-collection/family-no-father@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family.png b/1-js/04-object-basics/02-garbage-collection/family.png
index dbbc01d2f5..f37464e6c5 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family.png and b/1-js/04-object-basics/02-garbage-collection/family.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/family@2x.png b/1-js/04-object-basics/02-garbage-collection/family@2x.png
index 64b4619ba1..4f5d47210d 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/family@2x.png and b/1-js/04-object-basics/02-garbage-collection/family@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.png
index 423191778e..5cfe664c35 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1@2x.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-1@2x.png
index 223ea32a12..cf93a1605e 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1@2x.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-1@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.png
index da63d39693..2bbe4241d4 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2@2x.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-2@2x.png
index 1f614e3e6d..f4a7abb526 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2@2x.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-2@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.png
index e77144c1d7..665a22784f 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3@2x.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-3@2x.png
index 37e349b627..60d4059cca 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3@2x.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-3@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.png
index 110e0d9c4b..4ba6e17ecc 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4@2x.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-4@2x.png
index c09d75f9d1..8ac09c80d6 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4@2x.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-4@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.png
index bc4ea9670e..35c8816dcb 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5@2x.png b/1-js/04-object-basics/02-garbage-collection/garbage-collection-5@2x.png
index 0ab697e683..4db0c1732e 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5@2x.png and b/1-js/04-object-basics/02-garbage-collection/garbage-collection-5@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.png b/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.png
index 29c4fcbea8..9ddac3e299 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.png and b/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin@2x.png b/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin@2x.png
index 2f80f19a21..9069781f24 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin@2x.png and b/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.png b/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.png
index cdc1d49049..ae1684b2d2 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.png and b/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost@2x.png b/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost@2x.png
index d58afdb582..c510380f9e 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost@2x.png and b/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost@2x.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john.png b/1-js/04-object-basics/02-garbage-collection/memory-user-john.png
index 3ba5730de9..2ad00b6cb1 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/memory-user-john.png and b/1-js/04-object-basics/02-garbage-collection/memory-user-john.png differ
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john@2x.png b/1-js/04-object-basics/02-garbage-collection/memory-user-john@2x.png
index 5aa81bb0c0..f365ac0365 100644
Binary files a/1-js/04-object-basics/02-garbage-collection/memory-user-john@2x.png and b/1-js/04-object-basics/02-garbage-collection/memory-user-john@2x.png differ
diff --git a/1-js/04-object-basics/03-symbol/article.md b/1-js/04-object-basics/03-symbol/article.md
index 59a2de6116..bac44f39a1 100644
--- a/1-js/04-object-basics/03-symbol/article.md
+++ b/1-js/04-object-basics/03-symbol/article.md
@@ -18,8 +18,13 @@ let id = Symbol();
我们可以给 Symbol 一个描述(也称为 Symbol 名),这对于调试非常有用:
+<<<<<<< HEAD
```js
// id 是描述为 "id" 的 Symbol
+=======
+```js run
+// id is a symbol with the description "id"
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
let id = Symbol("id");
```
@@ -50,7 +55,13 @@ alert(id); // 类型错误:无法将 Symbol 值转换为 String。
*/!*
```
+<<<<<<< HEAD
如果我们真的想显示一个 Symbol,我们需要在它上面调用 `.toString()`,如下所示:
+=======
+That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not occasionally convert one into another.
+
+If we really want to show a symbol, we need to call `.toString()` on it, like here:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let id = Symbol("id");
*!*
@@ -58,7 +69,18 @@ alert(id.toString()); // Symbol(id),现在它起作用了
*/!*
```
+<<<<<<< HEAD
这是一种防止混乱的“语言保护”,因为 String 和 Symbol 有本质上的不同,而且不应该偶尔将它们相互转化。
+=======
+Or get `symbol.description` property to get the description only:
+```js run
+let id = Symbol("id");
+*!*
+alert(id.description); // id
+*/!*
+```
+
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
## “隐藏”属性
@@ -75,7 +97,11 @@ user[id] = "ID Value";
alert( user[id] ); // 我们可以使用 Symbol 作为键来访问数据。
```
+<<<<<<< HEAD
在 string `"id"` 上使用 `Symbol("id")` 有什么好处?
+=======
+What's the benefit of using `Symbol("id")` over a string `"id"`?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
我们用更深入一点的示例来说明这一点。
diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md
index 22c4bf187c..459997624e 100644
--- a/1-js/04-object-basics/04-object-methods/7-calculator/solution.md
+++ b/1-js/04-object-basics/04-object-methods/7-calculator/solution.md
@@ -1,6 +1,5 @@
-
-```js run demo
+```js run demo solution
let calculator = {
sum() {
return this.a + this.b;
@@ -20,4 +19,3 @@ calculator.read();
alert( calculator.sum() );
alert( calculator.mul() );
```
-
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
index a19f7a77bd..db268a8fa0 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
@@ -1,6 +1,6 @@
解决方案就是在每次调用后返回这个对象本身。
-```js run
+```js run demo
let ladder = {
step: 0,
up() {
@@ -28,7 +28,7 @@ ladder.up().up().down().up().down().showStep(); // 1
我们也可以每行一个调用。对于长链接它更具可读性:
-```js
+```js
ladder
.up()
.up()
@@ -37,4 +37,3 @@ ladder
.down()
.showStep(); // 1
```
-
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
index 2d37bf4eb5..788e5c590d 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
@@ -30,7 +30,11 @@ ladder.down();
ladder.showStep(); // 1
```
+<<<<<<< HEAD
修改 `up` 和 `down` 的代码让调用可以链接,就像这样:
+=======
+Modify the code of `up`, `down` and `showStep` to make the calls chainable, like this:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
ladder.up().up().down().showStep(); // 1
diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md
index 8beb5b17b8..fc0a520106 100644
--- a/1-js/04-object-basics/04-object-methods/article.md
+++ b/1-js/04-object-basics/04-object-methods/article.md
@@ -63,7 +63,11 @@ user.sayHi(); // Hello!
```smart header="Object-oriented programming"
当我们在代码中用对象表示实体时,这就是所谓的[面向对象编程](https://en.wikipedia.org/wiki/Object-oriented_programming),简称为 "OOP"。
+<<<<<<< HEAD
OOP 是一门很大的学问,也是一门有其本身乐趣的学问。怎样选择合适的实体?如何组织它们之间的交互?这就是架构,有很多关于此方面的书,例如 E.Gamma、R.Helm、R.Johnson 和 J.Vissides 所著的《设计模式:可复用面向对象软件的基础》、G.Booch 所著的《面向对象分析与设计》等等。在后面的 一章中,我们将会触及这个主题的浅层内容。
+=======
+OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E.Gamma, R.Helm, R.Johnson, J.Vissides or "Object-Oriented Analysis and Design with Applications" by G.Booch, and more.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
### 方法简写
@@ -72,14 +76,19 @@ OOP 是一门很大的学问,也是一门有其本身乐趣的学问。怎样
```js
// 这些对象作用一样
-let user = {
+user = {
sayHi: function() {
alert("Hello");
}
};
+<<<<<<< HEAD
// 方法简写看起来更好,对吧?
let user = {
+=======
+// method shorthand looks better, right?
+user = {
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
*!*
sayHi() { // 与 "sayHi: function()" 一样
*/!*
@@ -166,7 +175,11 @@ admin.sayHi(); // 噢哟!在 sayHi() 使用了旧的变量名。错误!
## “this” 不受限制
+<<<<<<< HEAD
在 JavaScript 中,"this" 关键字与大多数其他编程语言中的不同。首先,它可以用于任何函数。
+=======
+In JavaScript, "this" keyword behaves unlike most other programming languages. It can be used in any function.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这样的代码没有语法错误:
@@ -176,9 +189,15 @@ function sayHi() {
}
```
+<<<<<<< HEAD
`this` 是在运行时求值的。它可以是任何值。
例如,从不同的对象中调用同一个函数可能会有不同的 "this" 值:
+=======
+The value of `this` is evaluated during the run-time, depending on the context. And it can be anything.
+
+For instance, here the same function is assigned to two different objects and has different "this" in the calls:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let user = { name: "John" };
@@ -189,7 +208,11 @@ function sayHi() {
}
*!*
+<<<<<<< HEAD
// 在两个对象中使用的是相同的函数
+=======
+// use the same function in two objects
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
user.f = sayHi;
admin.f = sayHi;
*/!*
@@ -202,7 +225,14 @@ admin.f(); // Admin (this == admin)
admin['f'](); // Admin(使用点或方括号语法来访问这个方法,都没有关系。)
```
+<<<<<<< HEAD
实际上,我们可以在没有任何对象的情况下调用函数:
+=======
+The rule is simple: if `obj.f()` is called, then `this` is `obj` during the call of `f`. So it's either `user` or `admin` in the example above.
+
+````smart header="Calling without an object: `this == undefined`"
+We can even call the function without an object at all:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
function sayHi() {
@@ -214,9 +244,16 @@ sayHi(); // undefined
在这种情况下,严格模式下的 `this` 值为 `undefined`。如果我们尝试访问 `this.name`,将会出现错误。
+<<<<<<< HEAD
在非严格模式(没有使用 `use strict`)的情况下,`this` 将会是**全局对象**(浏览器中的 `window`,我们稍后会进行讨论)。`"use strict"` 可以修复这个历史行为。
请注意,通常在没有对象的情况下使用 `this` 的函数调用是不常见的,会(导致)编程错误。如果函数中有 `this`,那么通常意味着它是在对象上下文环境中被调用的。
+=======
+In non-strict mode the value of `this` in such case will be the *global object* (`window` in a browser, we'll get to it later in the chapter [](info:global-object)). This is a historical behavior that `"use strict"` fixes.
+
+Usually such call is an programming error. If there's `this` inside a function, it expects to be called in an object context.
+````
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```smart header="The consequences of unbound `this`"
如果你来自其他的编程语言,那么你可能熟悉『绑定 `this`』的概念。在对象定义的方法中,`this` 总是指向该对象。
@@ -257,7 +294,11 @@ user.hi(); // John (the simple call works)
该方法立即被括号 `()` 调用。但它无效。
+<<<<<<< HEAD
你可以看到该调用导致了错误,因为调用中的 `"this"` 为 `undefined`。
+=======
+You can see that the call results in an error, because the value of `"this"` inside the call becomes `undefined`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这样是正确的(对象点方法):
```js
@@ -276,7 +317,11 @@ user.hi();
1. 首先,点 `'.'` 取得这个 `obj.method` 属性。
2. 其后的括号 `()` 调用它。
+<<<<<<< HEAD
那么,`this` 是如何从第一部分传递到第二部分的呢?
+=======
+So, how does the information about `this` get passed from the first part to the second one?
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如果把这些操作分离开,那么 `this` 肯定会丢失:
@@ -312,11 +357,19 @@ hi(); // 错误,因为 this 未定义
(user, "hi", true)
```
+<<<<<<< HEAD
当在引用类型上用 `()` 调用时,它们接收到这个对象和它的方法的所有信息,并且设定正确的 `this` 值(这里等于 `user`)。
+=======
+When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this` (`=user` in this case).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`hi = user.hi` 赋值等其他的操作,将引用类型作为一个整体丢弃,只获取 `user.hi`(一个函数)的值进行传递。因此,进一步操作『失去』了 `this`(值)。
+<<<<<<< HEAD
所以如果直接使用点 `obj.method()` 或方括号语法 `obj[method]()`(它们在这里并无差别)调用函数,那么作为结果,`this` 值会以正确的方式进行传递。
+=======
+So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj['method']()` syntax (they do the same here). Later in this tutorial, we will learn various ways to solve this problem such as [func.bind()](/bind#solution-2-bind).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 箭头函数没有自己的 "this"
diff --git a/1-js/04-object-basics/05-object-toprimitive/article.md b/1-js/04-object-basics/05-object-toprimitive/article.md
index 81b2d76bc0..3e13922822 100644
--- a/1-js/04-object-basics/05-object-toprimitive/article.md
+++ b/1-js/04-object-basics/05-object-toprimitive/article.md
@@ -3,6 +3,7 @@
当对象相加 `obj1 + obj2`,相减 `obj1 - obj2`,或者使用 `alert(obj)` 打印时会发生什么?
+<<<<<<< HEAD
在对象中有特殊的方法用来做转换。
在 一章中,我们已经看到了数值,字符串和布尔转换的规则。但是我们给对象的原始值转换留下了一点疑问。正如我们所知道的方法和符号一样,现在我们可以解决这个问题了。
@@ -20,11 +21,30 @@
该算法允许我们使用特殊的对象方法自定义转换。
取决于上下文,转换具有所谓的“暗示”。
+=======
+In that case objects are auto-converted to primitives, and then the operation is carried out.
+
+In the chapter we've seen the rules for numeric, string and boolean conversions of primitives. But we left a gap for objects. Now, as we know about methods and symbols it becomes possible to fill it.
+
+1. All objects are `true` in a boolean context. There are only numeric and string conversions.
+2. The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, `Date` objects (to be covered in the chapter ) can be subtracted, and the result of `date1 - date2` is the time difference between two dates.
+3. As for the string conversion -- it usually happens when we output an object like `alert(obj)` and in similar contexts.
+
+## ToPrimitive
+
+We can fine-tune string and numeric conversion, using special object methods.
+
+The conversion algorithm is called `ToPrimitive` in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive). It's called with a "hint" that specifies the conversion type.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这里有三种变体:
`"string"`
+<<<<<<< HEAD
: 当一个操作期望一个字符串时,对于对象到字符串的转换,比如 `alert`:
+=======
+: For an object-to-string conversion, when we're doing an operation on an object that expects a string, like `alert`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// output
@@ -35,7 +55,11 @@
```
`"number"`
+<<<<<<< HEAD
: 当一个操作需要一个数字时,用于对象到数字的转换,如 `maths`:
+=======
+: For an object-to-number conversion, like when we're doing maths:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// 显式转换
@@ -52,7 +76,11 @@
`"default"`
: 在少数情况下发生,当操作者“不确定”期望的类型时。
+<<<<<<< HEAD
例如,二进制加 `+` 可以和字符串(连接)和数字(相加)发生作用,所以类型是字符串和数字都可以。或者当一个对象用 `==` 与一个字符串、数字或符号进行比较时。
+=======
+ For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them), so both strings and numbers would do. Or when an object is compared using `==` with a string, number or a symbol, it's also unclear which conversion should be done.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
// 二进制加
@@ -159,14 +187,30 @@ alert(user + 500); // toString -> John500
如果没有 `Symbol.toPrimitive` 和 `valueOf`,`toString` 将处理所有原始转换。
+<<<<<<< HEAD
## ToPrimitive 和 ToString/ToNumber
+=======
+## Return types
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
关于所有原始转换方法,有一个重要的点需要知道,就是它们不一定会返回“暗示的”原始值。
没有限制 `toString()` 是否返回字符串,或 `Symbol.toPrimitive` 方法是否为 "number" 暗示返回数字。
+<<<<<<< HEAD
**唯一强制性的事情是:这些方法必须返回一个原始值。**
+=======
+The only mandatory thing: these methods must return a primitive, not an object.
+
+```smart header="Historical notes"
+For historical reasons, if `toString` or `valueOf` returns an object, there's no error, but such value is ignored (like if the method didn't exist). That's because in ancient times there was no good "error" concept in JavaScript.
+
+In contrast, `Symbol.toPrimitive` *must* return a primitive, otherwise there will be an error.
+```
+
+## Further operations
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
发起转换的操作获取该原始值,然后继续使用该原始值,并在必要时应用进一步的转换。
@@ -208,11 +252,14 @@ alert(user + 500); // toString -> John500
alert(obj + 2); // 3 (ToPrimitive 返回布尔值,非字符串 => ToNumber)
```
+<<<<<<< HEAD
```smart header="历史笔记"
由于历史原因,`toString` 或 `valueOf` 方法**应该**返回一个原始值:如果它们中的任何一个返回了一个对象,虽然不会报错,但是该对象被忽略(就像该方法不存在一样)。
相反,`Symbol.toPrimitive` **必须**返回一个原始值,否则会出现错误。
```
+=======
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 概要
diff --git a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/solution.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/solution.md
index 27978ac1f0..4da30203ab 100644
--- a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/solution.md
+++ b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/solution.md
@@ -2,7 +2,11 @@
如果一个函数返回一个对象,那么 `new` 返回那个对象而不是 `this`。
+<<<<<<< HEAD
所以他们可以,例如,返回相同的外部定义的对象 `obj`:
+=======
+So they can, for instance, return the same externally defined object `obj`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run no-beautify
let obj = {};
diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md
index e5583c5d01..86bb65416d 100644
--- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md
+++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md
@@ -1,5 +1,3 @@
-
-
```js run demo
function Calculator() {
diff --git a/1-js/04-object-basics/06-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md
index 5d4b4e0208..64fff0f1a6 100644
--- a/1-js/04-object-basics/06-constructor-new/article.md
+++ b/1-js/04-object-basics/06-constructor-new/article.md
@@ -83,7 +83,15 @@ let user = new function() {
构造函数不能被再次调用,因为它不保存在任何地方,只是被创建和调用。所以这个技巧的目的是封装构建单个对象的代码,而不是将来重用。
````
+<<<<<<< HEAD
## 双语法构造函数:new.target
+=======
+## Constructor mode test: new.target
+
+```smart header="Advanced stuff"
+The syntax from this section is rarely used, skip it unless you want to know everything.
+```
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
在一个函数内部,我们可以使用 `new.target` 属性来检查它被调用时,是否使用了 `new`。
@@ -94,14 +102,32 @@ function User() {
alert(new.target);
}
+<<<<<<< HEAD
// 不带 new:
+=======
+// without "new":
+*!*
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
User(); // undefined
+*/!*
+<<<<<<< HEAD
// 带 new:
+=======
+// with "new":
+*!*
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
new User(); // function User { ... }
+*/!*
```
+<<<<<<< HEAD
这可以使 `new` 和常规语法的工作原理相同:
+=======
+That can be used inside the function to know whether it was called with `new`, "in constructor mode", or without it, "in regular mode".
+
+We can also make both `new` and regular calls to do the same, like this:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
function User(name) {
@@ -116,7 +142,13 @@ let john = User("John"); // 重新调用 new User
alert(john.name); // John
```
+<<<<<<< HEAD
这种方法有时用在库中以使语法更加灵活。但因为省略 `new` 使得它不易阅读,这可不是一件好事。 而通过 `new` 我们可以都知道这个新对象正在创建。
+=======
+This approach is sometimes used in libraries to make the syntax more flexible. So that people may call the function with or without `new`, and it still works.
+
+Probably not a good thing to use everywhere though, because omitting `new` makes it a bit less obvious what's going on. With `new` we all know that the new object is being created.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 构造函数 Return
@@ -215,5 +247,9 @@ JavaScript 为许多内置的对象提供了构造函数:比如日期 Date,
```smart header="Objects, we'll be back!"
在本章中,我们只介绍关于对象和构造函数的基础知识。它们对于在下一章中更多地了解数据类型和函数非常重要。
+<<<<<<< HEAD
在我们了解了这一章之后 我们返回到对象并深入其中,包括继承和类。
+=======
+After we learn that, we return to objects and cover them in-depth in the chapters and .
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
diff --git a/1-js/05-data-types/01-primitives-methods/1-string-new-property/solution.md b/1-js/05-data-types/01-primitives-methods/1-string-new-property/solution.md
index c2be790406..7b2122dbcb 100644
--- a/1-js/05-data-types/01-primitives-methods/1-string-new-property/solution.md
+++ b/1-js/05-data-types/01-primitives-methods/1-string-new-property/solution.md
@@ -6,16 +6,23 @@ let str = "Hello";
str.test = 5; // (*)
-alert(str.test);
+alert(str.test);
```
+<<<<<<< HEAD
这里有两种结果:
1. `undefined`
2. 报错。
+=======
+Depending on whether you have `use strict` or not, the result may be:
+1. `undefined` (no strict mode)
+2. An error (strict mode).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
在 `(*)` 的那一行到底发生了什么呢:
+<<<<<<< HEAD
1. 当访问 `str` 的属性时,创建一个“包装对象”。
2. 当对属性进行操作的时候。这个对象获得了 `test` 属性。
3. 操作结束,“包装对象”消失。
@@ -23,10 +30,21 @@ alert(str.test);
在最后一行,对字符串上的新的包装对象的每个对象操作,`str` 不再追踪这个属性。
一些浏览器进一步限制程序员,并且不允许将属性分配给基本类型。这就是为什么它有点远离规范,但在实践中我们却可以在 `(*)` 行看到错误。
+=======
+1. When a property of `str` is accessed, a "wrapper object" is created.
+2. In strict mode, writing into it is an error.
+3. Otherwise, the operation with the property is carried on, the object gets the `test` property, but after that the "wrapper object" disappears.
+
+So, without strict mode, in the last line `str` has no trace of the property.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
**这个例子清楚地表明,基本类型不是对象。**
+<<<<<<< HEAD
基本类型不能存储数据。
所有的属性/方法操作都是在临时对象的帮助下执行的。
+=======
+They can't store additional data.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md
index 9912266a46..57e4e6e065 100644
--- a/1-js/05-data-types/01-primitives-methods/article.md
+++ b/1-js/05-data-types/01-primitives-methods/article.md
@@ -1,13 +1,22 @@
# 基本类型的方法
+<<<<<<< HEAD
JavaScript 允许我们像对象一样使用基本类型(字符串,数字等)。
基本类型还提供调用方法等。我们会尽快研究这些,但首先我们会看看它是如何工作的,毕竟基本类型不是对象(在这里我们会分析的更加清楚)。
我们来看看基本类型和对象之间的关键区别。
+=======
+JavaScript allows us to work with primitives (strings, numbers, etc.) as if they were objects.
+
+They also provide methods to call as such. We will study those soon, but first we'll see how it works because, of course, primitives are not objects (and here we will make it even clearer).
+
+Let's look at the key distinctions between primitives and objects.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
基本类型
+<<<<<<< HEAD
- 是原始类型中的一种值。
- 在 JavaScript 中有 6 种基本类型:`string`、`number`、`boolean`、`symbol`、`null` 和 `undefined`。
@@ -17,6 +26,17 @@ JavaScript 允许我们像对象一样使用基本类型(字符串,数字等
- 可以使用大括号 `{}` 创建对象,例如:`{name: "John", age: 30}`。JavaScript 中还有其他种类的对象,例如函数就是对象。
关于对象的最好的事情之一是我们可以存储一个函数作为它的一个属性:
+=======
+- Is a value of a primitive type.
+- There are 6 primitive types: `string`, `number`, `boolean`, `symbol`, `null` and `undefined`.
+
+An object
+
+- Is capable of storing multiple values as properties.
+- Can be created with `{}`, for instance: `{name: "John", age: 30}`. There are other kinds of objects in JavaScript: functions, for example, are objects.
+
+One of the best things about objects is that we can store a function as one of its properties.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let john = {
@@ -31,7 +51,11 @@ john.sayHi(); // Hi buddy!
所以我们在这里创建了一个包含 `sayHi` 方法的对象 `john`。
+<<<<<<< HEAD
许多内置对象已经存在,例如那些处理日期,错误,HTML 元素等的内置对象。它们具有不同的属性和方法。
+=======
+Many built-in objects already exist, such as those that work with dates, errors, HTML elements, etc. They have different properties and methods.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
但是,这些特性都是有成本的!
@@ -46,9 +70,15 @@ john.sayHi(); // Hi buddy!
而解决方案看起来多少有点尴尬,如下:
+<<<<<<< HEAD
1. 基本类型仍然是原始数据。如预期相同,提供单个值
2. JavaScript 允许访问字符串,数字,布尔值和符号的方法和属性。
3. 当进行访问时,创建一个特殊的“包装对象”,它提供额外的功能,运行后即被销毁。
+=======
+1. Primitives are still primitive. A single value, as desired.
+2. The language allows access to methods and properties of strings, numbers, booleans and symbols.
+3. In order for that to work, a special "object wrapper" that provides the extra functionality is created, and then is destroyed.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
“包装对象”对于每种基本类型调用都是不同的,如`String`, `Number`, `Boolean` 和 `Symbol`。因此,他们提供了不同的方法。
@@ -92,18 +122,22 @@ alert( n.toFixed(2) ); // 1.23
例如:
```js run
-alert( typeof 1 ); // "number"
+alert( typeof 0 ); // "number"
-alert( typeof new Number(1) ); // "object"!
+alert( typeof new Number(0) ); // "object"!
```
+<<<<<<< HEAD
同样的,`zero`,是一个对象,alert 将显示出来:
+=======
+Objects are always truthy in `if`, so here the alert will show up:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let zero = new Number(0);
if (zero) { // zero is true, because it's an object
- alert( "zero is truthy?!?" );
+ alert( "zero is truthy!?!" );
}
```
diff --git a/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js b/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js
index 219fa8068e..6bd0123dba 100644
--- a/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js
+++ b/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js
@@ -18,7 +18,7 @@ describe("readNumber", function() {
assert.strictEqual(readNumber(), 0);
});
- it("continues the loop unti meets a number", function() {
+ it("continues the loop until meets a number", function() {
prompt.onCall(0).returns("not a number");
prompt.onCall(1).returns("not a number again");
prompt.onCall(2).returns("1");
@@ -35,4 +35,4 @@ describe("readNumber", function() {
assert.isNull(readNumber());
});
-});
\ No newline at end of file
+});
diff --git a/1-js/05-data-types/02-number/8-random-min-max/solution.md b/1-js/05-data-types/02-number/8-random-min-max/solution.md
index 562be1f62f..432e81e1c8 100644
--- a/1-js/05-data-types/02-number/8-random-min-max/solution.md
+++ b/1-js/05-data-types/02-number/8-random-min-max/solution.md
@@ -2,8 +2,13 @@
这可以分两个阶段完成:
+<<<<<<< HEAD
1. 如果我们将 0..1 的随机数乘以 `max-min`,则可能值的间隔从 0..1 增加到 `0..max-min`。
2. 现在,如果我们添加 `min`,则可能的间隔将从 `min` 变为 `max`。
+=======
+1. If we multiply a random number from 0..1 by `max-min`, then the interval of possible values increases `0..1` to `0..max-min`.
+2. Now if we add `min`, the possible interval becomes from `min` to `max`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
函数实现:
diff --git a/1-js/05-data-types/02-number/9-random-int-min-max/task.md b/1-js/05-data-types/02-number/9-random-int-min-max/task.md
index 8ae2b30676..cc697e70f9 100644
--- a/1-js/05-data-types/02-number/9-random-int-min-max/task.md
+++ b/1-js/05-data-types/02-number/9-random-int-min-max/task.md
@@ -12,9 +12,9 @@ importance: 2
功能示例:
```js
-alert( random(1, 5) ); // 1
-alert( random(1, 5) ); // 3
-alert( random(1, 5) ); // 5
+alert( randomInteger(1, 5) ); // 1
+alert( randomInteger(1, 5) ); // 3
+alert( randomInteger(1, 5) ); // 5
```
您可以使用[上一个任务](info:task/random-min-max)的解决方案作为基础。
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 9c7d1a830b..4301e67432 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -1,6 +1,10 @@
# 数字类型
+<<<<<<< HEAD
JavaScript 中的所有数字都以 64 位格式 [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985) 存储,也称为“双精度”。
+=======
+All numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers".
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
让我们回顾一下并展开我们目前了解的内容。
@@ -26,11 +30,16 @@ alert( 7.3e9 ); // 7.3 billions (7,300,000,000)
```js
1e3 = 1 * 1000
-1.23e6 = 1.23 * 1000000
+1.23e6 = 1.23 * 1000000
```
+<<<<<<< HEAD
现在让我们写一些非常小的东西。例如:1 微秒(百万分之一秒):
+=======
+Now let's write something very small. Say, 1 microsecond (one millionth of a second):
+
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let ms = 0.000001;
```
@@ -38,7 +47,7 @@ let ms = 0.000001;
就像以前一样,使用 `"e"` 可以提供帮助。如果我们想避免明确地写零,我们可以说:
```js
-let ms = 1e-6; // six zeroes to the left from 1
+let ms = 1e-6; // six zeroes to the left from 1
```
@@ -152,8 +161,13 @@ alert( num.toString(2) ); // 11111111
alert( Math.floor(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
```
+<<<<<<< HEAD
2. 函数 [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) 将点数后的数字四舍五入到 `n` 个数字并返回结果的字符串表示。
+=======
+2. The method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) rounds the number to `n` digits after the point and returns a string representation of the result.
+
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let num = 12.34;
alert( num.toFixed(1) ); // "12.3"
@@ -170,19 +184,23 @@ alert( num.toString(2) ); // 11111111
```js run
let num = 12.34;
- alert( num.toFixed(5) ); // "12.34000", added zeroes to make exactly 5 digits
+ alert( num.toFixed(5) ); // "12.34000", added zeroes to make exactly 5 digits
```
我们可以使用一元加号或 `Number()` 调用将其转换为数字:`+ num.toFixed(5)`。
## 不精确计算
+<<<<<<< HEAD
在 js 内部,一个数字以 64 位格式 [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985) 表示,所以正好有 64 位可以存储一个数字:其中 52 个被使用存储这些数字,其中 11 个存储小数点的位置(它们对于整数为零),1 位用于符号。
+=======
+Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point (they are zero for integer numbers), and 1 bit is for the sign.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如果一个数字太大,它会溢出 64 位存储,可能会输出无穷大:
```js run
-alert( 1e500 ); // Infinity
+alert( 1e500 ); // Infinity
```
可能不那么明显,但经常会发生精度的损失。
@@ -193,7 +211,11 @@ alert( 1e500 ); // Infinity
alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
```
+<<<<<<< HEAD
没错,如果我们检查 `0.1` 和 `0.2` 的总和是否为 `0.3`,们会得到 `false`。
+=======
+That's right, if we check whether the sum of `0.1` and `0.2` is `0.3`, we get `false`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
奇怪!那么如果不是 `0.3`,那么又是什么呢?
@@ -201,13 +223,23 @@ alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
alert( 0.1 + 0.2 ); // 0.30000000000000004
```
+<<<<<<< HEAD
哎哟!这里的错误有更大的误差。想象一下,你正在制作一个电子购物网站,访问者将 `0.10 美元` 和 `0.20 美元` 商品放入他的图表中。订单总额将是 `$ 0.30000000000000004`。这会让任何人感到惊讶。
+=======
+Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their chart. The order total will be `$0.30000000000000004`. That would surprise anyone.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
但为什么会发生这样的事呢?
+<<<<<<< HEAD
一个数字以二进制形式存储在内存中,一个 1 和 0 的序列。但是像十进制数字系统看起来很简单的 `0.1`,`0.2` 这样的分数实际上是二进制形式的无限分数。
换句话说,什么是 `0.1`?`0.1` 就是把 1 除以 10 `1/10`,即十分之一。在十进制数字系统中,这些数字很容易表示。将它比作三分之一:`1/3`。它变成了无尽的分数 `0.33333(3)`。
+=======
+A number is stored in memory in its binary form, a sequence of bits - ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
+
+In other words, what is `0.1`? It is one divided by ten `1/10`, one-tenth. In decimal numeral system such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
所以,按这种用 `10` 划分可以保证在十进制系统中运行良好,但用 `3` 划分不是。出于同样的原因,在二进制数字系统中,`2` 的幂的分割保证工作,但 `1/10` 变成一个无限的二进制分数。
@@ -227,40 +259,62 @@ alert( 0.1.toFixed(20) ); // 0.10000000000000000555
```smart header="不仅仅是 JavaScript"
许多其他编程语言也存在同样的问题。
+<<<<<<< HEAD
PHP, Java, C, Perl, Ruby 给出完全相同的结果,因为它们基于相同的数字格式。
```
我们能解决这个问题吗?当然,有很多方法:
1. 我们可以在特定函数的帮助下对结果进行四舍五入 [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
+=======
+PHP, Java, C, Perl, Ruby give exactly the same result, because they are based on the same numeric format.
+```
- ```js run
- let sum = 0.1 + 0.2;
- alert( sum.toFixed(2) ); // 0.30
- ```
+Can we work around the problem? Sure, the most reliable method is to round the result with the help of a method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
+```js run
+let sum = 0.1 + 0.2;
+alert( sum.toFixed(2) ); // 0.30
+```
+
+<<<<<<< HEAD
请注意 `toFixed` 总是返回一个字符串。它确保它在小数点后有 2 位数字。如果我们有电子购物并需要显示 `0.30 美元`,这实际上很方便。对于其他情况,我们可以使用一元加号将它强制为一个数字:
+=======
+Please note that `toFixed` always returns a string. It ensures that it has 2 digits after the decimal point. That's actually convenient if we have an e-shopping and need to show `$0.30`. For other cases, we can use the unary plus to coerce it into a number:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- ```js run
- let sum = 0.1 + 0.2;
- alert( +sum.toFixed(2) ); // 0.3
- ```
+```js run
+let sum = 0.1 + 0.2;
+alert( +sum.toFixed(2) ); // 0.3
+```
+<<<<<<< HEAD
2. 我们可以暂时将数字转换为数学整数,然后将其恢复。它是这样工作的:
+=======
+We also can temporarily multiply the numbers by 100 (or a bigger number) to turn them into integers, do the maths, and then divide back. Then, as we're doing maths with integers, the error somewhat decreases, but we still get it on division:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- ```js run
- alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
- ```
+```js run
+alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
+alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
+```
+<<<<<<< HEAD
这是有效的,因为当我们做 `0.1 * 10 = 1` 和 `0.2 * 10 = 2` 时,那么这两个数字就变成了整数,并且没有精度损失。
3. 如果我们在与一家商店打交道,那么最激进的解决方案就是将所有价格存储在美分中,并且根本不使用分数。但是,如果我们应用 30% 的折扣呢?在实践中,完全回避分数是很难实现的,所以上述解决方案有助于避免这种缺陷。
+=======
+So, multiply/divide approach reduces the error, but doesn't remove it totally.
+
+Sometimes we could try to evade fractions at all. Like if we're dealing with a shop, then we can store prices in cents instead of dollars. But what if we apply a discount of 30%? In practice, totally evading fractions is rarely possible. Just round them to cut "tails" when needed.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````smart header="有趣的事情"
尝试运行这个:
```js run
-// Hello! I'm a self-increasing number!
+// Hello! I'm a self-increasing number!
alert( 9999999999999999 ); // shows 10000000000000000
```
@@ -272,7 +326,11 @@ JavaScript 在这种事件中不会触发错误。它尽最大努力使数字符
```samrt header="两个零"
数字内部表示的另一个有趣结果是存在两个零:`0` 和 `-0`。
+<<<<<<< HEAD
这是因为一个符号由一个位表示,所以每个数字可以是正数或负数,包括零。
+=======
+That's because a sign is represented by a single bit, so every number can be positive or negative, including a zero.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
在大多数情况下,这种区别并不明显,因为操作员可以将它们视为相同。
```
@@ -283,8 +341,13 @@ JavaScript 在这种事件中不会触发错误。它尽最大努力使数字符
还记得这两个特殊的数值吗?
+<<<<<<< HEAD
- `Infinite`(和 `-Infinite`)是一个特殊的数值,比任何数值都大(小)。
- `NaN` 代表一个错误。
+=======
+- `Infinity` (and `-Infinity`) is a special numeric value that is greater (less) than anything.
+- `NaN` represents an error.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
它们属于 `数字` 类型,但不是 `普通` 数字,因此有特殊函数可以检查它们:
@@ -326,10 +389,17 @@ alert( isFinite(num) );
有一种特殊的内置方法 [Object.is](mdn:js/Object/is),它可以比较 `===` 等值,但对于两种边缘情况更可靠:
+<<<<<<< HEAD
1. 它适用于 `NaN`: `Object.is(NaN,NaN)=== true`,这是件好事。
2. 值 `0` 和 `-0` 是不同的:`Object.is(0,-0)=== false`,它不是很重要,但这些值在技术上是不同的。
在所有其他情况下,`Object.is(a,b)` 与 `a === b` 相同。
+=======
+1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
+2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's true, because internally the number has a sign bit that may be different even if all other bits are zeroes.
+
+In all other cases, `Object.is(a, b)` is the same as `a === b`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这种比较方式经常用于 JavaScript 规范。当内部算法需要比较两个值完全相同时,它使用 Object.is(内部称为 [SameValue](https://tc39.github.io/ecma262/#sec-samevalue))。
```
@@ -349,7 +419,11 @@ alert( +"100px" ); // NaN
这就是 `parseInt` 和 `parseFloat` 的作用。
+<<<<<<< HEAD
他们从字符串中“读出”一个数字,直到他们可以。如果发生错误,则返回收集的数字。函数 `parseInt` 返回一个整数,而 `parseFloat` 将返回一个浮点数:
+=======
+They "read" a number from a string until they can't. In case of an error, the gathered number is returned. The function `parseInt` returns an integer, whilst `parseFloat` will return a floating-point number:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
alert( parseInt('100px') ); // 100
@@ -417,9 +491,13 @@ JavaScript 有一个内置的 [Math](https://developer.mozilla.org/en/docs/Web/J
对于不同的进制:
+<<<<<<< HEAD
- 可以在十六进制(`0x`),八进制(`0o`)和二进制(`0b`)系统中直接写入数字。
- `parseInt(str,base)` 解析来自任何数字系统的整数,其基数为:`2≤base≤36`。
- `num.toString(base)` 将数字转换为数字系统中具有给定 `base` 的字符串。
+=======
+- Use `parseInt/parseFloat` for the "soft" conversion, which reads a number from a string and then returns the value they could read before the error.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
将 `12pt` 和 `100px` 等值转换为数字:
@@ -427,9 +505,13 @@ JavaScript 有一个内置的 [Math](https://developer.mozilla.org/en/docs/Web/J
分数:
+<<<<<<< HEAD
- 使用 `Math.floor`,`Math.ceil`,`Math.trunc`,`Math.round` 或 `num.toFixed(precision)` 循环。
- 请记住,使用分数时会损失精度。
更多的数学函数:
- 需要时请参阅 [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) 对象,虽然这个文档非常小,但是它可以满足基础的要求。
+=======
+- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small, but can cover basic needs.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/03-string/1-ucfirst/solution.md b/1-js/05-data-types/03-string/1-ucfirst/solution.md
index 3beccff9ff..e709a7d0de 100644
--- a/1-js/05-data-types/03-string/1-ucfirst/solution.md
+++ b/1-js/05-data-types/03-string/1-ucfirst/solution.md
@@ -15,7 +15,7 @@ let newStr = str[0].toUpperCase() + str.slice(1);
这是第二种变体:
-```js run
+```js run demo
function ucFirst(str) {
if (!str) return str;
diff --git a/1-js/05-data-types/03-string/2-check-spam/solution.md b/1-js/05-data-types/03-string/2-check-spam/solution.md
index a65b37dad6..8522336862 100644
--- a/1-js/05-data-types/03-string/2-check-spam/solution.md
+++ b/1-js/05-data-types/03-string/2-check-spam/solution.md
@@ -1,6 +1,10 @@
+<<<<<<< HEAD
为了使搜索不区分大小写,我们将字符串改为小写,然后搜索:
+=======
+To make the search case-insensitive, let's bring the string to lower case and then search:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
-```js run
+```js run demo
function checkSpam(str) {
let lowerStr = str.toLowerCase();
diff --git a/1-js/05-data-types/03-string/2-check-spam/task.md b/1-js/05-data-types/03-string/2-check-spam/task.md
index c330b26879..bfaae8fab9 100644
--- a/1-js/05-data-types/03-string/2-check-spam/task.md
+++ b/1-js/05-data-types/03-string/2-check-spam/task.md
@@ -4,7 +4,11 @@ importance: 5
# 检查 spam
+<<<<<<< HEAD
写一个函数 `checkSpam(str)`,如果 `str` 包含 `viagra` 或 `XXX` 就返回 `true`,否则返回 `false`。
+=======
+Write a function `checkSpam(str)` that returns `true` if `str` contains 'viagra' or 'XXX', otherwise false.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
函数必须不区分大小写:
diff --git a/1-js/05-data-types/03-string/3-truncate/_js.view/test.js b/1-js/05-data-types/03-string/3-truncate/_js.view/test.js
index c252f16bee..9914923315 100644
--- a/1-js/05-data-types/03-string/3-truncate/_js.view/test.js
+++ b/1-js/05-data-types/03-string/3-truncate/_js.view/test.js
@@ -1,5 +1,5 @@
describe("truncate", function() {
- it("truncate the long string to the given lenth (including the ellipsis)", function() {
+ it("truncate the long string to the given length (including the ellipsis)", function() {
assert.equal(
truncate("What I'd like to tell on this topic is:", 20),
"What I'd like to te…"
@@ -13,4 +13,4 @@ describe("truncate", function() {
);
});
-});
\ No newline at end of file
+});
diff --git a/1-js/05-data-types/03-string/3-truncate/solution.md b/1-js/05-data-types/03-string/3-truncate/solution.md
index 9e4860bc51..503e704342 100644
--- a/1-js/05-data-types/03-string/3-truncate/solution.md
+++ b/1-js/05-data-types/03-string/3-truncate/solution.md
@@ -2,10 +2,9 @@
注意省略号实际上有一个 unicode 字符,而不仅仅是三个点。
-```js run
+```js run demo
function truncate(str, maxlength) {
- return (str.length > maxlength) ?
+ return (str.length > maxlength) ?
str.slice(0, maxlength - 1) + '…' : str;
}
```
-
diff --git a/1-js/05-data-types/03-string/4-extract-currency/solution.md b/1-js/05-data-types/03-string/4-extract-currency/solution.md
index 8b13789179..e69de29bb2 100644
--- a/1-js/05-data-types/03-string/4-extract-currency/solution.md
+++ b/1-js/05-data-types/03-string/4-extract-currency/solution.md
@@ -1 +0,0 @@
-
diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md
index 1f104edb6b..fef23b07fc 100644
--- a/1-js/05-data-types/03-string/article.md
+++ b/1-js/05-data-types/03-string/article.md
@@ -132,7 +132,11 @@ alert( `My\n`.length ); // 3
```warn header="`length` is a property"
掌握其他语言的人,有时会错误地调用 `str.length()` 而不是 `str.length`。这是行不通的。
+<<<<<<< HEAD
请注意 `str.length` 是一个数字属性,而不是函数。之后不需要添加括号。
+=======
+Please note that `str.length` is a numeric property, not a function. There is no need to add parenthesis after it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 访问字符。
@@ -275,8 +279,13 @@ while ((pos = str.indexOf(target, pos + 1)) != -1) {
*/!*
```
+<<<<<<< HEAD
```smart header="`str.lastIndexOf(subStr, pos)`"
还有一个类似的方法 [str.lastIndexOf(subStr, pos)](mdn:js/String/lastIndexOf),他从字符串的末尾开始搜索。
+=======
+```smart header="`str.lastIndexOf(substr, position)`"
+There is also a similar method [str.lastIndexOf(substr, position)](mdn:js/String/lastIndexOf) that searches from the end of a string to its beginning.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
它会以相反的顺序列出事件。
```
@@ -451,7 +460,11 @@ JavaScript 中有三种获取字符串的方法:`substring`、`substr` 和 `sl
```smart header="Which one to choose?"
他们可以完成这项工作,形式上,`substr` 有一个小缺点:它不是在 JavaScript 核心规范中描述的,而是在附录 B 中,它涵盖了主要由于历史原因而存在的浏览器特性。因此,非浏览器环境可能无法支持它。但实际上它在任何地方都有效。
+<<<<<<< HEAD
作者发现自己几乎一直在使用 `slice`。
+=======
+The author finds themself using `slice` almost all the time.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
## 比较字符串
@@ -551,7 +564,11 @@ alert( 'Österreich'.localeCompare('Zealand') ); // -1
## 内部,Unicode
```warn header="Advanced knowledge"
+<<<<<<< HEAD
这部分会深入字符串内部。如果你计划处理表情符号、罕见的象形文字字符或其他罕见符号,这些知识会对你有用。
+=======
+The section goes deeper into string internals. This knowledge will be useful for you if you plan to deal with emoji, rare mathematical or hieroglyphic characters or other rare symbols.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如果你不打算支持它们,你可以跳过这一部分。
```
diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js b/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js
index 143ad53451..b44e76fe7e 100644
--- a/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js
+++ b/1-js/05-data-types/04-array/10-maximal-subarray/_js.view/test.js
@@ -30,4 +30,8 @@ describe("getMaxSubSum", function() {
it("maximal subsum of [-1, -2] equals 0", function() {
assert.equal(getMaxSubSum([-1, -2]), 0);
});
-});
\ No newline at end of file
+
+ it("maximal subsum of [2, -8, 5, -1, 2, -3, 2] equals 6", function() {
+ assert.equal(getMaxSubSum([2, -8, 5, -1, 2, -3, 2]), 6);
+ });
+});
diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
index 60cc94afd0..c04fa31a45 100644
--- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
+++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
# 慢的解决方案
+=======
+# Slow solution
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
我们可以计算所有可能的子集的和。
@@ -29,8 +33,13 @@
-9
-9 + 11
+<<<<<<< HEAD
// 从 -11 开始:
-11
+=======
+// Starting from 11
+11
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
这样写出来的代码实际上是一个嵌套循环:外部循环遍历数组所有元素,然后内部循环计算从当前元素之后的所有子数组集的和。
@@ -59,7 +68,11 @@ alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
该方案的时间复杂度是 [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation)。也就是说,如果我们把数组大小增加 2 倍,那么算法的运行时间将会延长4倍。
+<<<<<<< HEAD
对于大型数组(1000,10000 或者更多项)这种算法会导致严重的时间消耗。
+=======
+For big arrays (1000, 10000 or more items) such algorithms can lead to a serious sluggishness.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
# 快的解决方案
@@ -67,7 +80,7 @@ alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
如果文字描述不太好理解,就直接看下面的代码吧,真的很短:
-```js run
+```js run demo
function getMaxSubSum(arr) {
let maxSum = 0;
let partialSum = 0;
diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/task.md b/1-js/05-data-types/04-array/10-maximal-subarray/task.md
index 0f05a0843e..d718723519 100644
--- a/1-js/05-data-types/04-array/10-maximal-subarray/task.md
+++ b/1-js/05-data-types/04-array/10-maximal-subarray/task.md
@@ -8,7 +8,11 @@ importance: 2
任务是:找出连续的 `arr` 的子数组,其里面所有项的和最大。
+<<<<<<< HEAD
写出函数 `getMaxSubSum(arr)`,用其找出并返回最大和。
+=======
+Write the function `getMaxSubSum(arr)` that will return that sum.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -27,4 +31,8 @@ getMaxSubSum([*!*1, 2, 3*/!*]) = 6 (所有项的和)
getMaxSubSum([-1, -2, -3]) = 0
```
+<<<<<<< HEAD
请尝试想出一个快速的解决方案:复杂度可以是 [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation),有能力达到 O(n) 则更好。
+=======
+Please try to think of a fast solution: [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation) or even O(n) if you can.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/04-array/2-create-array/solution.md b/1-js/05-data-types/04-array/2-create-array/solution.md
index eec9055e7c..f032b55f0c 100644
--- a/1-js/05-data-types/04-array/2-create-array/solution.md
+++ b/1-js/05-data-types/04-array/2-create-array/solution.md
@@ -5,6 +5,6 @@ let styles = ["Jazz", "Blues"];
styles.push("Rock-n-Roll");
styles[Math.floor((styles.length - 1) / 2)] = "Classics";
alert( styles.shift() );
-styles.unshift("Rap", "Reggie");
+styles.unshift("Rap", "Reggae");
```
diff --git a/1-js/05-data-types/04-array/array-pop.png b/1-js/05-data-types/04-array/array-pop.png
index 023642fa7c..4d6867b14b 100644
Binary files a/1-js/05-data-types/04-array/array-pop.png and b/1-js/05-data-types/04-array/array-pop.png differ
diff --git a/1-js/05-data-types/04-array/array-pop@2x.png b/1-js/05-data-types/04-array/array-pop@2x.png
index 301fd8f66b..c65ef94467 100644
Binary files a/1-js/05-data-types/04-array/array-pop@2x.png and b/1-js/05-data-types/04-array/array-pop@2x.png differ
diff --git a/1-js/05-data-types/04-array/array-shift.png b/1-js/05-data-types/04-array/array-shift.png
index 5f2cef5dd0..5798a64760 100644
Binary files a/1-js/05-data-types/04-array/array-shift.png and b/1-js/05-data-types/04-array/array-shift.png differ
diff --git a/1-js/05-data-types/04-array/array-shift@2x.png b/1-js/05-data-types/04-array/array-shift@2x.png
index 1bd68b3154..ba95f2651e 100644
Binary files a/1-js/05-data-types/04-array/array-shift@2x.png and b/1-js/05-data-types/04-array/array-shift@2x.png differ
diff --git a/1-js/05-data-types/04-array/array-speed.png b/1-js/05-data-types/04-array/array-speed.png
index 3737e8248f..a400d0c1d8 100644
Binary files a/1-js/05-data-types/04-array/array-speed.png and b/1-js/05-data-types/04-array/array-speed.png differ
diff --git a/1-js/05-data-types/04-array/array-speed@2x.png b/1-js/05-data-types/04-array/array-speed@2x.png
index e45624b502..11a3e67c91 100644
Binary files a/1-js/05-data-types/04-array/array-speed@2x.png and b/1-js/05-data-types/04-array/array-speed@2x.png differ
diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md
index 3336a3b3bb..0932ac5b42 100644
--- a/1-js/05-data-types/04-array/article.md
+++ b/1-js/05-data-types/04-array/article.md
@@ -1,12 +1,24 @@
+<<<<<<< HEAD
# 数组
对象允许存储键值化的集合,这很好。
但很多时候我们需要的是**有序集合**,里面的元素都是按顺序排列的。例如,我们可能需要存储一些列表,比如用户、商品以及 HTML 元素等。
+=======
+# Arrays
+
+Objects allow you to store keyed collections of values. That's fine.
+
+But quite often we find that we need an *ordered collection*, where we have a 1st, a 2nd, a 3rd element and so on. For example, we need that to store a list of something: users, goods, HTML elements etc.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这里使用对象就不是很方便了,因为对象不提供能够管理元素顺序的方法。我们不能在已有的元素“之间”插入一个新的属性。这种场景下对象就不太适用了。
+<<<<<<< HEAD
这时一个特殊的数据结构数组(`Array`)就派上用场了,它能存储有序的集合。
+=======
+There exists a special data structure named `Array`, to store ordered collections.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 声明
@@ -79,12 +91,18 @@ arr[3](); // hello
```
+<<<<<<< HEAD
````smart header="以逗号结尾"
数组和对象一样,都可以在末尾冗余一个逗号:
```js
+=======
+````smart header="Trailing comma"
+An array, just like an object, may end with a comma:
+```js
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
let fruits = [
- "Apple",
- "Orange",
+ "Apple",
+ "Orange",
"Plum"*!*,*/!*
];
```
@@ -95,7 +113,11 @@ let fruits = [
## pop/push, shift/unshift 方法
+<<<<<<< HEAD
[队列](https://en.wikipedia.org/wiki/Queue_(abstract_data_type))是最常见的使用数组的方法之一. 在计算机科学中,这意味着一个有序的元素的集合支持两个操作:
+=======
+A [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) is one of the most common uses of an array. In computer science, this means an ordered collection of elements which supports two operations:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- `push` 在末端添加一个元素.
- `shift` 取出队列最前端的一个元素,整个队列往前移,这样原先排第二的元素现在排在了第一。
@@ -104,9 +126,15 @@ let fruits = [
这两种操作数组都支持.
+<<<<<<< HEAD
队列的应用在实践中经常会碰到,例如需要在屏幕上显示消息队列。
数组还有另一个用例,就是数据结构[栈](https://en.wikipedia.org/wiki/Stack_(abstract_data_type))。
+=======
+In practice we need it very often. For example, a queue of messages that need to be shown on-screen.
+
+There's another use case for arrays -- the data structure named [stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
它支持两种操作:
@@ -121,7 +149,11 @@ let fruits = [
对于栈来说,最后放进去的是最先接收的,也叫做 LIFO(后进先出)法则。而与队列相对应的叫做 FIFO(先进先出)。
+<<<<<<< HEAD
JavaScript 中的数组既可以用作队列,也可以用作栈。它们允许从前端/末端来添加/删除元素。
+=======
+Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements both to/from the beginning or the end.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这在计算机科学中叫做[双端队列](https://en.wikipedia.org/wiki/Double-ended_queue)。
@@ -189,11 +221,19 @@ alert( fruits );
## 内部
+<<<<<<< HEAD
数组是一种特殊的对象。使用方括号来访问属性 `arr[0]` 实际上是来自于对象的语法。这个数字被用作键值。
+=======
+An array is a special kind of object. The square brackets used to access a property `arr[0]` actually come from the object syntax. That's essentially the same as `obj[key]`, where `arr` is the object, while numbers are used as keys.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
他们扩展了对象,提供了特殊的方法来处理有序的数据集合,还添加了 `length` 属性。但是核心还是一个对象。
+<<<<<<< HEAD
记住,在 JavaScript 中只有 7 种基本类型。数组是一个对象因此其行为也像一个对象。
+=======
+Remember, there are only 7 basic types in JavaScript. Array is an object and thus behaves like an object.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如,它是通过引用来复制的:
@@ -203,6 +243,11 @@ let fruits = ["Banana"]
let arr = fruits; // 通过引用复制 (两个变量引用的是相同的数组)
alert( arr === fruits ); // true
+<<<<<<< HEAD
+=======
+
+arr.push("Pear"); // modify the array by reference
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
arr.push("Pear"); // 通过引用修改数组
@@ -229,9 +274,15 @@ fruits.age = 25; // 用任意的名字创建属性
数组误用的几种方式:
+<<<<<<< HEAD
- 添加一个非数字的属性比如 `arr.test = 5`。
- 制造空洞,比如:添加 `arr[0]` 后添加 `arr[1000]` (它们中间什么都没有)。
- 以倒序填充数组, 比如 `arr[1000]`,`arr[999]` 等等。
+=======
+- Add a non-numeric property like `arr.test = 5`.
+- Make holes, like: add `arr[0]` and then `arr[1000]` (and nothing between them).
+- Fill the array in the reverse order, like `arr[1000]`, `arr[999]` and so on.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
请将数组视为作用于**有序数据**的特殊结构,它们为此提供了特殊的方法。数组在 JavaScript 引擎内部是经过特殊调整的,使得更好的作用于连续的有序数据,所以请以这种方式使用数组。如果你需要任意键值,那很有可能实际上你需要的是常规对象 `{}`。
@@ -296,7 +347,7 @@ let fruits = ["Apple", "Orange", "Plum"];
// 迭代数组元素
for (let fruit of fruits) {
- alert( fruit );
+ alert( fruit );
}
```
@@ -320,7 +371,11 @@ for (let key in arr) {
在浏览器和其它环境中有一种“类数组”的对象,它们**看似是数组**,也就是说,它们有 `length` 和索引属性,但是也可能有其它的非数字的属性和方法,这通常是我们不需要的。`for..in` 循环会把它们都列出来。所以如果我们需要处理类数组对象,这些“额外”的属性就会存在问题。
+<<<<<<< HEAD
2. `for..in` 循环适用于普通对象,不适用于数组,而且会慢 10-100 倍。当然即使是这样也依然非常快。只有在遇到瓶颈或者一些不相关的场景增速可能会有问题。但是我们仍然应该了解这其中的不同。
+=======
+2. The `for..in` loop is optimized for generic objects, not arrays, and thus is 10-100 times slower. Of course, it's still very fast. The speedup may only matter in bottlenecks. But still we should be aware of the difference.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
通常来说,我们不应该用 `for..in` 来处理数组。
@@ -338,7 +393,11 @@ fruits[123] = "Apple";
alert( fruits.length ); // 124
```
+<<<<<<< HEAD
要知道的是我们通常不会这样使用数组。
+=======
+Note that we usually don't use arrays like that.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`length` 属性的另一个有意思的点是它是可写的。
@@ -369,7 +428,11 @@ let arr = *!*new Array*/!*("Apple", "Pear", "etc");
如果调用 `new Array` 使用的是一个单独的数字作为参数,那么就会创建一个**指定了长度,却没有任何项**的数组。
+<<<<<<< HEAD
让我们看看如何搬起石头砸自己的脚:
+=======
+Let's see how one can shoot themself in the foot:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let arr = new Array(2); // 会创建一个数组 [2] 吗?
@@ -385,7 +448,11 @@ alert( arr.length ); // length 2
## 多维数组
+<<<<<<< HEAD
数组里的项也可以是数组。我们可以以多维数组的方式存储矩阵:
+=======
+Arrays can have items that are also arrays. We can use it for multidimensional arrays, for example to store matrices:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let matrix = [
@@ -431,7 +498,11 @@ alert( "1,2" + 1 ); // "1,21"
## 总结
+<<<<<<< HEAD
数组是一种特殊的对象,适用于存储和管理有序的数据项。
+=======
+Array is a special kind of object, suited to storing and managing ordered data items.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- 声明:
@@ -443,7 +514,14 @@ alert( "1,2" + 1 ); // "1,21"
let arr = new Array(item1, item2...);
```
+<<<<<<< HEAD
调用 `new Array(number)` 会创建一个指定长度的数组,且不含有任何项。
+=======
+ The call to `new Array(number)` creates an array with the given length, but without elements.
+
+- The `length` property is the array length or, to be precise, its last numeric index plus one. It is auto-adjusted by array methods.
+- If we shorten `length` manually, the array is truncated.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- `length` 属性是数组的长度,准确地说,是它的最后一个数字索引值加一。它由数组方法自动调整。
- 如果我们手动缩短 `length`,那么数组就会被截断。
@@ -455,9 +533,13 @@ alert( "1,2" + 1 ); // "1,21"
- `shift()` 从前端移除并返回该元素。
- `unshift(...items)` 从前端添加项 `items`。
+<<<<<<< HEAD
遍历数组的元素:
- `for (let i=0; i。
+=======
+We will return to arrays and study more methods to add, remove, extract elements and sort arrays in the chapter .
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/04-array/queue.png b/1-js/05-data-types/04-array/queue.png
index 5e1fb640ce..39af3beda4 100644
Binary files a/1-js/05-data-types/04-array/queue.png and b/1-js/05-data-types/04-array/queue.png differ
diff --git a/1-js/05-data-types/04-array/queue@2x.png b/1-js/05-data-types/04-array/queue@2x.png
index 6acfc83d12..75045a51dc 100644
Binary files a/1-js/05-data-types/04-array/queue@2x.png and b/1-js/05-data-types/04-array/queue@2x.png differ
diff --git a/1-js/05-data-types/04-array/stack.png b/1-js/05-data-types/04-array/stack.png
index d1c9cb9afd..7d2599355b 100644
Binary files a/1-js/05-data-types/04-array/stack.png and b/1-js/05-data-types/04-array/stack.png differ
diff --git a/1-js/05-data-types/04-array/stack@2x.png b/1-js/05-data-types/04-array/stack@2x.png
index b3835fa442..16c6225186 100644
Binary files a/1-js/05-data-types/04-array/stack@2x.png and b/1-js/05-data-types/04-array/stack@2x.png differ
diff --git a/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js b/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js
index 024d6d6c2b..490f570ada 100644
--- a/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js
+++ b/1-js/05-data-types/05-array-methods/1-camelcase/_js.view/solution.js
@@ -1,8 +1,10 @@
function camelize(str) {
return str
- .split('-') // my-long-word -> ['my', 'long', 'word']
- .map(
+ .split('-') // splits 'my-long-word' into array ['my', 'long', 'word']
+ .map(
+ // capitalizes first letters of all array items except the first one
+ // converts ['my', 'long', 'word'] into ['my', 'Long', 'Word']
(word, index) => index == 0 ? word : word[0].toUpperCase() + word.slice(1)
- ) // ['my', 'long', 'word'] -> ['my', 'Long', 'Word']
- .join(''); // ['my', 'Long', 'Word'] -> myLongWord
+ )
+ .join(''); // joins ['my', 'Long', 'Word'] into 'myLongWord'
}
diff --git a/1-js/05-data-types/05-array-methods/10-average-age/task.md b/1-js/05-data-types/05-array-methods/10-average-age/task.md
index 5ef6491bb1..089db5828a 100644
--- a/1-js/05-data-types/05-array-methods/10-average-age/task.md
+++ b/1-js/05-data-types/05-array-methods/10-average-age/task.md
@@ -4,7 +4,11 @@ importance: 4
# 获取平均
+<<<<<<< HEAD
编写 `getAverageAge(users)` 函数,该函数获取一个具有 age 属性的对象数组,并获取平均值。
+=======
+Write the function `getAverageAge(users)` that gets an array of objects with property `age` and returns the average age.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
平均的公式是 `(age1 + age2 + ... + ageN) / N`。
@@ -19,4 +23,3 @@ let arr = [ john, pete, mary ];
alert( getAverageAge(arr) ); // (25 + 30 + 29) / 3 = 28
```
-
diff --git a/1-js/05-data-types/05-array-methods/11-array-unique/solution.md b/1-js/05-data-types/05-array-methods/11-array-unique/solution.md
index 65995830dc..9f94804997 100644
--- a/1-js/05-data-types/05-array-methods/11-array-unique/solution.md
+++ b/1-js/05-data-types/05-array-methods/11-array-unique/solution.md
@@ -2,7 +2,7 @@
- 对于每个元素,我们将检查结果数组是否已经有该元素。
- 如果有,则忽略,否则添加结果。
-```js run
+```js run demo
function unique(arr) {
let result = [];
diff --git a/1-js/05-data-types/05-array-methods/2-filter-range/solution.md b/1-js/05-data-types/05-array-methods/2-filter-range/solution.md
index e69de29bb2..73993a07a0 100644
--- a/1-js/05-data-types/05-array-methods/2-filter-range/solution.md
+++ b/1-js/05-data-types/05-array-methods/2-filter-range/solution.md
@@ -0,0 +1,14 @@
+```js run demo
+function filterRange(arr, a, b) {
+ // added brackets around the expression for better readability
+ return arr.filter(item => (a <= item && item <= b));
+}
+
+let arr = [5, 3, 8, 1];
+
+let filtered = filterRange(arr, 1, 4);
+
+alert( filtered ); // 3,1 (matching values)
+
+alert( arr ); // 5,3,8,1 (not modified)
+```
diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js
index 61cda126b6..488db3755b 100644
--- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js
+++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/solution.js
@@ -1,5 +1,4 @@
-
function filterRangeInPlace(arr, a, b) {
for (let i = 0; i < arr.length; i++) {
@@ -12,4 +11,4 @@ function filterRangeInPlace(arr, a, b) {
}
}
-}
\ No newline at end of file
+}
diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md
index e69de29bb2..36e3130ff0 100644
--- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md
+++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/solution.md
@@ -0,0 +1,21 @@
+```js run demo
+function filterRangeInPlace(arr, a, b) {
+
+ for (let i = 0; i < arr.length; i++) {
+ let val = arr[i];
+
+ // remove if outside of the interval
+ if (val < a || val > b) {
+ arr.splice(i, 1);
+ i--;
+ }
+ }
+
+}
+
+let arr = [5, 3, 8, 1];
+
+filterRangeInPlace(arr, 1, 4); // removed the numbers except from 1 to 4
+
+alert( arr ); // [3, 1]
+```
diff --git a/1-js/04-object-basics/06-constructor-new/4-calculator-extendable/_js.view/solution.js b/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js
similarity index 100%
rename from 1-js/04-object-basics/06-constructor-new/4-calculator-extendable/_js.view/solution.js
rename to 1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js
diff --git a/1-js/04-object-basics/06-constructor-new/4-calculator-extendable/_js.view/test.js b/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/test.js
similarity index 100%
rename from 1-js/04-object-basics/06-constructor-new/4-calculator-extendable/_js.view/test.js
rename to 1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/test.js
diff --git a/1-js/04-object-basics/06-constructor-new/4-calculator-extendable/solution.md b/1-js/05-data-types/05-array-methods/6-calculator-extendable/solution.md
similarity index 100%
rename from 1-js/04-object-basics/06-constructor-new/4-calculator-extendable/solution.md
rename to 1-js/05-data-types/05-array-methods/6-calculator-extendable/solution.md
diff --git a/1-js/04-object-basics/06-constructor-new/4-calculator-extendable/task.md b/1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md
similarity index 72%
rename from 1-js/04-object-basics/06-constructor-new/4-calculator-extendable/task.md
rename to 1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md
index 31d72ecb11..99371ddaa2 100644
--- a/1-js/04-object-basics/06-constructor-new/4-calculator-extendable/task.md
+++ b/1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md
@@ -17,7 +17,11 @@ importance: 5
alert( calc.calculate("3 + 7") ); // 10
```
+<<<<<<< HEAD:1-js/04-object-basics/06-constructor-new/4-calculator-extendable/task.md
2. 然后添加 calculate 新操作的方法 `addOperator(name, func)`。它需要运算符 `name` 和实现它的双参数函数 `func(a,b)`。
+=======
+2. Then add the method `addMethod(name, func)` that teaches the calculator a new operation. It takes the operator `name` and the two-argument function `func(a,b)` that implements it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb:1-js/05-data-types/05-array-methods/6-calculator-extendable/task.md
例如,我们添加乘法`*`,除法`/`和求幂`**`:
diff --git a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
index f19ac14aa8..74d8302738 100644
--- a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
+++ b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
@@ -1,17 +1,22 @@
```js run no-beautify
-function sortByName(arr) {
- arr.sort((a, b) => a.name > b.name);
+function sortByAge(arr) {
+ arr.sort((a, b) => a.age > b.age ? 1 : -1);
}
let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };
-let arr = [ john, pete, mary ];
+let arr = [ pete, john, mary ];
-sortByName(arr);
+sortByAge(arr);
+<<<<<<< HEAD
// 现在排序是:[john, mary, pete]
+=======
+// now sorted is: [john, mary, pete]
+alert(arr[0].name); // John
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
alert(arr[1].name); // Mary
+alert(arr[2].name); // Pete
```
-
diff --git a/1-js/05-data-types/05-array-methods/8-sort-objects/task.md b/1-js/05-data-types/05-array-methods/8-sort-objects/task.md
index 7f4b584b47..4012615d4c 100644
--- a/1-js/05-data-types/05-array-methods/8-sort-objects/task.md
+++ b/1-js/05-data-types/05-array-methods/8-sort-objects/task.md
@@ -2,9 +2,15 @@ importance: 5
---
+<<<<<<< HEAD
# 排序对象
编写函数 `sortByName(users)` 获得对象数组 property的属性 `name` 并对它进行排序。
+=======
+# Sort users by age
+
+Write the function `sortByAge(users)` that gets an array of objects with the `age` property and sorts them by `age`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -13,11 +19,12 @@ let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };
-let arr = [ john, pete, mary ];
+let arr = [ pete, john, mary ];
-sortByName(arr);
+sortByAge(arr);
// now: [john, mary, pete]
+alert(arr[0].name); // John
alert(arr[1].name); // Mary
+alert(arr[2].name); // Pete
```
-
diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md
index d9f3963eef..ee5db9fcb3 100644
--- a/1-js/05-data-types/05-array-methods/article.md
+++ b/1-js/05-data-types/05-array-methods/article.md
@@ -36,7 +36,11 @@ alert( arr.length ); // 3
所以应该使用特殊的方法。
+<<<<<<< HEAD
[arr.splice(str)](mdn:js/Array/splice) 方法可以说是数组界的瑞士军刀。它可以做所有事情:添加,删除和插入元素。
+=======
+The [arr.splice(str)](mdn:js/Array/splice) method is a swiss army knife for arrays. It can do everything: insert, remove and replace elements.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
语法是:
@@ -122,7 +126,11 @@ alert( arr ); // 1,2,3,4,5
arr.slice(start, end)
```
+<<<<<<< HEAD
它从所有元素的开始索引 `"start"` 复制到 `"end"` (不包括 `"end"`) 返回一个新的数组。`start` 和 `end` 都可以是负数,在这种情况下,从末尾计算索引。
+=======
+It returns a new array containing all items from index `"start"` to `"end"` (not including `"end"`). Both `start` and `end` can be negative, in that case position from array end is assumed.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
它和字符串的 `str.slice` 有点像,就是把子字符串替换成子数组。
@@ -201,7 +209,40 @@ let arrayLike = {
alert( arr.concat(arrayLike) ); // 1,2,something,else
```
+<<<<<<< HEAD
## 查询数组
+=======
+## Iterate: forEach
+
+The [arr.forEach](mdn:js/Array/forEach) method allows to run a function for every element of the array.
+
+The syntax:
+```js
+arr.forEach(function(item, index, array) {
+ // ... do something with item
+});
+```
+
+For instance, this shows each element of the array:
+
+```js run
+// for each element call alert
+["Bilbo", "Gandalf", "Nazgul"].forEach(alert);
+```
+
+And this code is more elaborate about their positions in the target array:
+
+```js run
+["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
+ alert(`${item} is at index ${index} in ${array}`);
+});
+```
+
+The result of the function (if it returns any) is thrown away and ignored.
+
+
+## Searching in array
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这些是在数组中查询某些内容的方法。
@@ -209,9 +250,15 @@ alert( arr.concat(arrayLike) ); // 1,2,something,else
[arr.indexOf](mdn:js/Array/indexOf)、[arr.lastIndexOf](mdn:js/Array/lastIndexOf) 和 [arr.includes](mdn:js/Array/includes) 方法与字符串操作具有相同的语法,只不过这里是对数组元素而不是字符进行操作:
+<<<<<<< HEAD
- `arr.indexOf(item, from)` 从索引 `from` 查询 `item`,如果找到返回索引,否则返回 `-1`。
- `arr.lastIndexOf(item, from)` — 和上面相同,只是从尾部开始查询。
- `arr.includes(item, from)` — 从索引 `from` 查询 `item`,如果找到则返回 `true`。
+=======
+- `arr.indexOf(item, from)` looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`.
+- `arr.lastIndexOf(item, from)` -- same, but looks for from right to left.
+- `arr.includes(item, from)` -- looks for `item` starting from index `from`, returns `true` if found.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -246,7 +293,12 @@ alert( arr.includes(NaN) );// true (correct)
语法:
```js
let result = arr.find(function(item, index, array) {
+<<<<<<< HEAD
// 如果查询到返回 true
+=======
+ // if true is returned, item is returned and iteration is stopped
+ // for falsy scenario returns undefined
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
});
```
@@ -274,9 +326,15 @@ alert(user.name); // John
在现实生活中,对象数组是很常见,所以`find` 方法非常有用。
+<<<<<<< HEAD
注意在这个例子中我们传给了 `find` 一个单参数函数 `item => item.id == 1`。其他参数 `find` 很少使用。
与 [arr.findIndex](mdn:js/Array/findIndex) 方法本质上是相同的,但它返回找到元素的索引而不是元素本身。
+=======
+Note that in the example we provide to `find` the function `item => item.id == 1` with one argument. Other arguments of this function are rarely used.
+
+The [arr.findIndex](mdn:js/Array/findIndex) method is essentially the same, but it returns the index where the element was found instead of the element itself and `-1` is returned when nothing is found.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
### filter
@@ -284,11 +342,20 @@ alert(user.name); // John
如果需要匹配的有很多,我们可以使用 [arr.filter(fn)](mdn:js/Array/filter)。
+<<<<<<< HEAD
语法与 `find` 大致相同,但是它返回的是所有匹配元素组成的数组:
```js
let results = arr.filter(function(item, index, array) {
// 在元素通过过滤器时返回 true
+=======
+The syntax is similar to `find`, but filter continues to iterate for all array elements even if `true` is already returned:
+
+```js
+let results = arr.filter(function(item, index, array) {
+ // if true item is pushed to results and iteration continues
+ // returns empty array for complete falsy scenario
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
});
```
@@ -329,7 +396,7 @@ let result = arr.map(function(item, index, array) {
例如,在这里我们将每个元素转换为它的字符串长度:
```js run
-let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length)
+let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
alert(lengths); // 5,7,6
```
@@ -416,8 +483,13 @@ alert(arr); // *!*1, 2, 15*/!*
```
````
+<<<<<<< HEAD
````smart header="箭头函数最好"
[箭头函数](info:function-expression#arrow-functions)还记得吗?这里使用箭头函数会更加简洁:
+=======
+````smart header="Arrow functions for the best"
+Remember [arrow functions](info:function-expressions-arrows#arrow-functions)? We can use them here for neater sorting:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
arr.sort( (a, b) => a - b );
@@ -477,7 +549,11 @@ alert( str.split('') ); // t,e,s,t
```
````
+<<<<<<< HEAD
[arr.join(str)](mdn:js/Array/join) 与 `split` 相反。它会在它们之间创建一串由 `str` 粘合的 `arr` 项。
+=======
+The call [arr.join(separator)](mdn:js/Array/join) does the reverse to `split`. It creates a string of `arr` items glued by `separator` between them.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -491,7 +567,11 @@ alert( str ); // Bilbo;Gandalf;Nazgul
### reduce/reduceRight
+<<<<<<< HEAD
当我们需要遍历一个数组时 — 我们可以使用 `forEach`。
+=======
+When we need to iterate over an array -- we can use `forEach`, `for` or `for..of`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
当我们需要迭代并返回每个元素的数据时 — 我们可以使用 `map`。
@@ -500,16 +580,22 @@ alert( str ); // Bilbo;Gandalf;Nazgul
语法是:
```js
-let value = arr.reduce(function(previousValue, item, index, arr) {
+let value = arr.reduce(function(previousValue, item, index, array) {
// ...
}, initial);
```
该函数应用于元素。从第二个参数开始你可能就会觉得很眼熟了:
+<<<<<<< HEAD
- `item` — 当前的数组元素。
- `index` — 当前索引。
- `arr` — 数组本身。
+=======
+- `item` -- is the current array item.
+- `index` -- is its position.
+- `array` -- is the array.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
目前为止,这很像 `forEach/map`。但还有一个参数不同就是:
@@ -539,7 +625,11 @@ alert(result); // 15

+<<<<<<< HEAD
或者以表格的形式出现,每行代表的是下一个数组元素的函数调用:
+=======
+Or in the form of a table, where each row represents a function call on the next array element:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
| |`sum`|`current`|`result`|
|---|-----|---------|---------|
@@ -585,6 +675,7 @@ arr.reduce((sum, current) => sum + current);
[arr.reduceRight](mdn:js/Array/reduceRight) 也一样,但是遍历是从右到左。
+<<<<<<< HEAD
## 迭代:forEach
[arr.forEach](mdn:js/Array/forEach) 方法允许为数组的每个元素运行一个函数。
@@ -613,6 +704,8 @@ arr.forEach(function(item, index, array) {
该函数的结果(如果它返回的话)被抛弃并被忽略。
+=======
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## Array.isArray
数组基于对象。不构成单独的语言类型。
@@ -689,11 +782,22 @@ alert(youngerUsers.length); // 2
- `slice(start, end)` — 它从所有元素的开始索引 `"start"` 复制到 `"end"` (不包括 `"end"`) 返回一个新的数组。
- `concat(...items)` — 返回一个新数组:复制当前数组的所有成员并向其中添加 `items`。如果有任何` items` 是一个数组,那么就取其元素。
+<<<<<<< HEAD
- 查询元素:
- `indexOf/lastIndexOf(item, pos)` — 从 `pos` 找到 `item`,则返回索引否则返回 `-1`。
- `includes(value)` — 如果数组有 `value`,则返回 `true`,否则返回 `false`。
- `find/filter(func)` — 通过函数过滤元素,返回 `true` 条件的符合 find 函数的第一个值或符合 filter 函数的全部值。
- `findIndex` 和 `find` 类似,但返回索引而不是值。
+=======
+- To search among elements:
+ - `indexOf/lastIndexOf(item, pos)` -- look for `item` starting from position `pos`, return the index or `-1` if not found.
+ - `includes(value)` -- returns `true` if the array has `value`, otherwise `false`.
+ - `find/filter(func)` -- filter elements through the function, return first/all values that make it return `true`.
+ - `findIndex` is like `find`, but returns the index instead of a value.
+
+- To iterate over elements:
+ - `forEach(func)` -- calls `func` for every element, does not return anything.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- 转换数组:
- `map(func)` — 从每个元素调用 `func` 的结果创建一个新数组。
@@ -702,11 +806,16 @@ alert(youngerUsers.length); // 2
- `split/join` — 将字符串转换为数组并返回。
- `reduce(func, initial)` — 通过为每个元素调用 `func` 计算数组上的单个值并在调用之间传递中间结果。
+<<<<<<< HEAD
- 迭代元素:
- `forEach(func)` — 为每个元素调用 `func`,不返回任何东西。
- 其他:
- `Array.isArray(arr)` 检查 `arr` 是否是一个数组。
+=======
+- Additionally:
+ - `Array.isArray(arr)` checks `arr` for being an array.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
请注意,`sort`,`reverse` 和 `splice` 方法修改数组本身。
diff --git a/1-js/05-data-types/05-array-methods/reduce.png b/1-js/05-data-types/05-array-methods/reduce.png
index 41476d2aea..7566c4d84c 100644
Binary files a/1-js/05-data-types/05-array-methods/reduce.png and b/1-js/05-data-types/05-array-methods/reduce.png differ
diff --git a/1-js/05-data-types/05-array-methods/reduce@2x.png b/1-js/05-data-types/05-array-methods/reduce@2x.png
index f31647d17b..7c9fd6692b 100644
Binary files a/1-js/05-data-types/05-array-methods/reduce@2x.png and b/1-js/05-data-types/05-array-methods/reduce@2x.png differ
diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md
index ada5f4a6e9..eac7af1310 100644
--- a/1-js/05-data-types/06-iterable/article.md
+++ b/1-js/05-data-types/06-iterable/article.md
@@ -3,9 +3,16 @@
**Iterable** (可迭代对象)是数组的泛化。这个概念是说任何对象都可在 `for..of` 循环中使用。
+<<<<<<< HEAD
数组本身就是可迭代的。但不仅仅是数组。字符串也可以迭代,很多其他内建对象也都可以迭代。
在核心 JavaScript 中,可迭代对象用途广泛。我们将会看到,很多内建的操作和方法都依赖于它。
+=======
+Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, Strings are iterable also. As we'll see, many built-in operators and methods rely on them.
+
+If an object represents a collection (list, set) of something, then `for..of` is a great syntax to loop over it, so let's see how to make it work.
+
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## Symbol.iterator
@@ -27,10 +34,17 @@ let range = {
为了让 `range` 对象可迭代(也就让 `for..of` 可以运行)我们需要为对象添加一个名为 `Symbol.iterator` 的方法(一个特殊的内置标记)。
+<<<<<<< HEAD
- 当 `for..of` 循环开始,它将会调用这个方法(如果没找到,就会报错)。
- 这个方法必须返回一个迭代器 —— 一个有 `next` 方法的对象。
- 当 `for..of` 循环希望取得下一个数值,它就调用这个对象的 `next()` 方法。
- `next()` 返回结果的格式必须是 `{done: Boolean, value: any}`,当 `done=true` 时,表示迭代结束,否则 `value` 必须是一个未被迭代的新值。
+=======
+1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`.
+2. Onward, `for..of` works *only with that returned object*.
+3. When `for..of` wants the next value, it calls `next()` on that object.
+4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` must be the new value.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
这是 `range` 的全部实现:
@@ -43,7 +57,12 @@ let range = {
// 1. 使用 for..of 将会首先调用它:
range[Symbol.iterator] = function() {
+<<<<<<< HEAD
// 2. ...它返回一个迭代器:
+=======
+ // ...it returns the iterator object:
+ // 2. Onward, for..of works only with this iterator, asking it for next values
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
return {
current: this.from,
last: this.to,
@@ -66,10 +85,17 @@ for (let num of range) {
}
```
+<<<<<<< HEAD
这段代码中有几点需要着重关注:
- `range` 自身没有 `next()` 方法。
- 相反,是调用 `range[Symbol.iterator]()` 时将会被创建的另一个所谓的“迭代器”对象,将会处理迭代操作。
+=======
+Please note the core feature of iterables: an important separation of concerns:
+
+- The `range` itself does not have the `next()` method.
+- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and it handles the whole iteration.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
所以,迭代器对象和迭代的对象其实是分离的。
@@ -101,10 +127,19 @@ for (let num of range) {
}
```
+<<<<<<< HEAD
现在 `range[Symbol.iterator]()` 返回了 `range` 对象自身:它包括了必需的 `next()` 方法并通过 `this.current` 记忆了当前迭代进程。有时候,这样也可以。但缺点是,现在不可能同时在 `range` 上运行两个 `for..of` 循环了:这两个循环将会共享迭代状态,因为仅有一个迭代器 —— 也就是对象自身。
```smart header="Infinite iterators"
无穷迭代也是可行的。例如,`range` 设置为 `range.to = Infinity` 则成为无穷迭代。或者我们可以创建一个可迭代对象,它生成一个伪随机数无穷序列。也是可用的。
+=======
+Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too.
+
+The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, even in async scenarios.
+
+```smart header="Infinite iterators"
+Infinite iterators are also possible. For instance, the `range` becomes infinite for `range.to = Infinity`. Or we can make an iterable object that generates an infinite sequence of pseudorandom numbers. Also can be useful.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`next` 没有什么限制,它可以返回越来越多的值,这也很常见。
@@ -120,11 +155,20 @@ for (let num of range) {
```js run
for (let char of "test") {
+<<<<<<< HEAD
alert( char ); // t,然后 e,然后 s,然后 t
}
```
对于 UTF-16 的扩展字符,它也能正常工作!
+=======
+ // triggers 4 times: once for each character
+ alert( char ); // t, then e, then s, then t
+}
+```
+
+And it works correctly with surrogate pairs!
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let str = '𝒳😂';
@@ -139,7 +183,11 @@ for (let char of str) {
但是为了更深层的了解知识概念,我们来看看如何显式的创建迭代器。
+<<<<<<< HEAD
我们将会采用与 `for..of` 一样的方法迭代字符串,但是是直接的调用。这段代码将会获取字符串的迭代器,然后“手动”调用它。
+=======
+We'll iterate over a string in exactlly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually":
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let str = "Hello";
@@ -165,7 +213,13 @@ while (true) {
- **Iterables** 是应用于 `Symbol.iterator` 方法的对象,像上文所述。
- **Array-likes** 是有索引和 `length` 属性的对象,所以它们很像数组。
+<<<<<<< HEAD
很自然的,这些属性都可以结合起来。例如,字符串既是可迭代对象(`for..of` 可以迭代字符串)也是类数组对象(它们有数字索引也有 `length` 属性)。
+=======
+When we use JavaScript for practical tasks in browser or other environments, we may meet objects that are iterables or array-likes, or both.
+
+For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
但是一个可迭代对象也许不是类数组对象。反之亦然,一个类数组对象可能也不可迭代。
@@ -186,11 +240,19 @@ for (let item of arrayLike) {}
*/!*
```
+<<<<<<< HEAD
它们有什么共同点?可迭代对象和类数组对象通常都不是数组,他们没有 `push`,`pop` 等等方法。如果我们有一个这样的对象并且想像数组那样操作它,这就有些不方便了。
## Array.from
有一个全局方法 [Array.from](mdn:js/Array/from) 可以把它们全都结合起来。它以一个可迭代对象或者类数组对象作为参数并返回一个真正的 `Array` 数组。然后我们就可以用该对象调用数组的方法了。
+=======
+Both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. E.g. we would like to work with `range` using array methods. How to achieve that?
+
+## Array.from
+
+There's a universal method [Array.from](mdn:js/Array/from) that takes an iterable or array-like value and makes a "real" `Array` from it. Then we can call array methods on it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -222,7 +284,11 @@ alert(arr); // 1,2,3,4,5 (数组的 toString 转化函数生效)
Array.from(obj[, mapFn, thisArg])
```
+<<<<<<< HEAD
第二个参数 `mapFn` 应是一个在元素被添加到数组前,施加于每个元素的方法,`thisArg` 允许设置方法的 `this` 对象。
+=======
+The optional second argument `mapFn` can be a function that will be applied to each element before adding to the array, and `thisArg` allows to set `this` for it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
diff --git a/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md b/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md
index 101ad46b9f..28dc38acef 100644
--- a/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md
+++ b/1-js/05-data-types/07-map-set-weakmap-weakset/02-filter-anagrams/solution.md
@@ -59,7 +59,7 @@ map.set(sorted, word);
这就是答案:
-```js run
+```js run demo
function aclean(arr) {
let obj = {};
@@ -68,7 +68,7 @@ function aclean(arr) {
obj[sorted] = arr[i];
}
- return Array.from(Object.values(obj));
+ return Object.values(obj);
}
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
diff --git a/1-js/05-data-types/07-map-set-weakmap-weakset/03-iterable-keys/task.md b/1-js/05-data-types/07-map-set-weakmap-weakset/03-iterable-keys/task.md
index c86540e3d8..a8f8203955 100644
--- a/1-js/05-data-types/07-map-set-weakmap-weakset/03-iterable-keys/task.md
+++ b/1-js/05-data-types/07-map-set-weakmap-weakset/03-iterable-keys/task.md
@@ -16,7 +16,11 @@ map.set("name", "John");
let keys = map.keys();
*!*
+<<<<<<< HEAD
// 错误:numbers.push 不是一个函数
+=======
+// Error: keys.push is not a function
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
keys.push("more");
*/!*
```
diff --git a/1-js/05-data-types/07-map-set-weakmap-weakset/article.md b/1-js/05-data-types/07-map-set-weakmap-weakset/article.md
index 00c3a3722a..dc5f9db1d3 100644
--- a/1-js/05-data-types/07-map-set-weakmap-weakset/article.md
+++ b/1-js/05-data-types/07-map-set-weakmap-weakset/article.md
@@ -47,7 +47,11 @@ alert( map.size ); // 3
```js run
let john = { name: "John" };
+<<<<<<< HEAD
// 存下每个用户的来访次数
+=======
+// for every user, let's store their visits count
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
let visitsCountMap = new Map();
// john 是 map 的键
@@ -159,6 +163,7 @@ for (let entry of recipeMap) { // 和 recipeMap.entries() 一样
另外,`Map` 有一个内建的 `forEach` 方法,和 `Array` 很像:
```js
+// runs the function for each (key, value) pair
recipeMap.forEach( (value, key, map) => {
alert(`${key}: ${value}`); // cucumber: 500 等等
});
@@ -223,7 +228,11 @@ set.forEach((value, valueAgain, set) => {
注意到这里有个有趣得事情。`forEach` 函数用于 `Set` 时有三个参数:value,然后又一个 value,之后是目标对象。确实,相同值的 value 在参数中出现了两次。
+<<<<<<< HEAD
这是为了兼容 `Map`,它在使用 `forEach` 方法时也包括三个参数。
+=======
+That's for compatibility with `Map` where `forEach` has three arguments. Looks a bit strange, for sure. But may help to replace `Map` with `Set` in certain cases with ease, and vice versa.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
适用于 `Map` 的迭代方法 set 也同样支持:
@@ -253,9 +262,33 @@ john = null;
通常情况下,当某数据存在于内存中时,对象的属性或者数组的元素或其他的数据结构将被认为是可以获取的并留存于内存。
+<<<<<<< HEAD
在一个正常 `Map` 中,我们将某对象存储为键还是值并不重要。它将会被一直保留在内存中,就算已经没有指向它的引用。
例如:
+=======
+For instance, if we put an object into an array, then while the array is alive, the object will be alive as well, even if there are no other references to it.
+
+Like this:
+
+```js
+let john = { name: "John" };
+
+let array = [ john ];
+
+john = null; // overwrite the reference
+
+*!*
+// john is stored inside the array, so it won't be garbage-collected
+// we can get it as array[0]
+*/!*
+```
+
+Or, if we use an object as the key in a regular `Map`, then while the `Map` exists, that object exists as well. It occupies memory and may not be garbage collected.
+
+For instance:
+
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let john = { name: "John" };
@@ -265,12 +298,19 @@ map.set(john, "...");
john = null; // 覆盖引用
*!*
+<<<<<<< HEAD
// john 被保存在 map 中
// 我们可以通过 map.keys() 得到它
+=======
+// john is stored inside the map,
+// we can get it by using map.keys()
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
*/!*
```
+`WeakMap/WeakSet` are fundamentally different in this aspect. They do not prevent garbage-collection of key objects.
+<<<<<<< HEAD
除了 `WeakMap/WeakSet`。
**`WeakMap/WeakSet` 不会阻止内存移除对象。**
@@ -278,6 +318,11 @@ john = null; // 覆盖引用
我们从 `WeakMap` 开始。
它和 `Map` 的第一个区别是它的键必须是对象,不能是基础类型的值:
+=======
+Let's explain it starting with `WeakMap`.
+
+The first difference from `Map` is that `WeakMap` keys must be objects, not primitive values:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let weakMap = new WeakMap();
@@ -287,7 +332,12 @@ let obj = {};
weakMap.set(obj, "ok"); // 运行正常(对象作为键)
*!*
+<<<<<<< HEAD
weakMap.set("test", "Whoops"); // 错误,因为“test”是原始类型
+=======
+// can't use a string as the key
+weakMap.set("test", "Whoops"); // Error, because "test" is not an object
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
*/!*
```
@@ -306,21 +356,32 @@ john = null; // 覆盖引用
把它和上面普通 `Map` 的例子对比一下。现在,如果 `john` 仅作为 `WeakMap` 的键 —— 它将会被自动删除。
+<<<<<<< HEAD
...并且 `WeakMap` 并不支持方法 `keys()`,`values()`,`entries()`,我们不能对它进行迭代。所以没有办法获取它的所有键值。
+=======
+`WeakMap` does not support iteration and methods `keys()`, `values()`, `entries()`, so there's no way to get all keys or values from it.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`WeakMap` 仅有如下方法:
- `weakMap.get(key)`
- `weakMap.set(key, value)`
-- `weakMap.delete(key, value)`
+- `weakMap.delete(key)`
- `weakMap.has(key)`
+<<<<<<< HEAD
为什么会有这些限制?这是处于一些技术原因。如果一个对象没有任何引用(就像上面代码中的 `john`),那么它将会被自动删除。但是从技术上讲,它没有完全指定**什么时候清理会发生**。
JavaScript 引擎将会决定何时清理。它可能会选择马上清理内存或者等待:当更多需要删除操作发生的时候再删除。所以,技术上说,目前 `WeakMap` 中元素个数并不可知。引擎可能已经清理,也可能没有,也可能只进行了部分的清理。处于这个原因,允许访问 `WeakMap` 整体的方法并不支持。
+=======
+Why such a limitation? That's for technical reasons. If an object has lost all other references (like `john` in the code above), then it is to be garbage-collected automatically. But technically it's not exactly specified *when the cleanup happens*.
+
+The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically the current element count of a `WeakMap` is not known. The engine may have cleaned it up or not, or did it partially. For that reason, methods that access `WeakMap` as a whole are not supported.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
现在,我们在哪里需要这样的结构?
+<<<<<<< HEAD
`WeakMap` 的目的是,我们可以当且仅当该对象存在时,为对象存储一些内容。但我们并不会因为存储了对象的一些内容,就强制对象一直保留在内存中。
```js
@@ -329,12 +390,28 @@ weakMap.put(john, "secret documents");
```
当我们对对象有个主存储区,并且需要保存仅当对象活跃时候才相关的附加信息时,这一点就很有用了。
+=======
+The idea of `WeakMap` is that we can store something for an object that should exist only while the object exists. But we do not force the object to live by the mere fact that we store something for it.
+
+```js
+weakMap.set(john, "secret documents");
+// if john dies, secret documents will be destroyed automatically
+```
+
+That's useful for situations when we have a main storage for the objects somewhere and need to keep additional information, that is only relevant while the object lives.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
让我们看一个例子。
+<<<<<<< HEAD
例如,我们写了一段代码来保存每个用户的访问次数。信息保存在一个 map 中:用户是键,访问次数是值。当用户离开了,我们也就不再需要保存他的访问次数了。
有一个方法可以追踪离开的游客并手动清理记录:
+=======
+For instance, we have code that keeps a visit count for each user. The information is stored in a map: a user is the key and the visit count is the value. When a user leaves, we don't want to store their visit count anymore.
+
+One way would be to keep track of users, and when they leave -- clean up the map manually:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let john = { name: "John" };
@@ -352,7 +429,11 @@ john = null;
// 但是记录依旧在 map 中,我们需要清理它!
*/!*
alert( visitsCountMap.size ); // 1
+<<<<<<< HEAD
// 它还在内存中,因为 Map 将它作为键
+=======
+// and john is also in the memory, because Map uses it as the key
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```
另一个方法是使用 `WeakMap`:
@@ -371,17 +452,33 @@ john = null;
// 所以这个对象会自动的从内存和 visitsCountMap 中删除
```
+<<<<<<< HEAD
使用普通的 `Map`,用户离开后的数据清理是一很乏味的任务:我们不仅要从主存储区移除用户(可能是变量或者数组),还需要将附加的数据存储例如 `visitsCountMap` 也清除。当用户在代码的一个位置进行管理,而附加结构位于另一个位置,并且没有获取有关清除的信息这样的复杂的情况下,这种操作就很笨重。
`WeakMap` 能让事情简单很多,因为它能够自动清理。它里面诸如上面的例子中来访次数这样的信息,当且仅当对象键存在的时候才存在。
+=======
+With a regular `Map`, cleaning up after a user has left becomes a tedious task: we not only need to remove the user from its main storage (be it a variable or an array), but also need to clean up the additional stores like `visitsCountMap`. And it can become cumbersome in more complex cases when users are managed in one place of the code and the additional structure is in another place and is getting no information about removals.
+
+```summary
+`WeakMap` can make things simpler, because it is cleaned up automatically. The information in it like visits count in the example above lives only while the key object exists.
+```
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
`WeakSet` 的行为类似:
+<<<<<<< HEAD
- 它和 `Set` 类似,但是我们仅能将对象添加进 `WeakSet`(不可以是基础类型)
- 仅当对象存在其他位置的引用时它才存在于 set 中。
- 就像 `Set` 一样,它支持 `add`,`has` 和 `delete`,不支持 `size`,`keys()` 也不支持迭代器。
例如,我们可以用它来追踪一个项目是否被检查过:
+=======
+- It is analogous to `Set`, but we may only add objects to `WeakSet` (not primitives).
+- An object exists in the set while it is reachable from somewhere else.
+- Like `Set`, it supports `add`, `has` and `delete`, but not `size`, `keys()` and no iterations.
+
+For instance, we can use it to keep track of whether a message is read:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
let messages = [
@@ -393,22 +490,45 @@ let messages = [
// 用数组的元素来填充(3 个元素)
let unreadSet = new WeakSet(messages);
+<<<<<<< HEAD
// 我们可以使用 unreadSet 来看一个 message 是否未读
alert(unreadSet.has(messages[1])); // true
// 读过之后就将它从 set 中移除
+=======
+// use unreadSet to see whether a message is unread
+alert(unreadSet.has(messages[1])); // true
+
+// remove it from the set after reading
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
unreadSet.delete(messages[1]); // true
// 当我们对消息列表做 shift 操作,set 就会自动清理
messages.shift();
+<<<<<<< HEAD
// 不需要清理 unreadSet,它现在还有两个元素
// 可惜并没有方法可以获取元素数目,所以无法显示出来
```
`WeakMap` 和 `WeakSet` 最显著的限制就是没有迭代器,也不能获取当前所有内容。这可能会有点不方便,但是实际上并不妨碍 `WeakMap/WeakSet` 的主要任务 —— 作为对象的附加存储,该对象在其他位置被保存或管理。
+=======
+
+*!*
+// no need to clean unreadSet, it now has 2 items
+*/!*
+// (though technically we don't know for sure when the JS engine clears it)
+```
+
+The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterations, and inability to get all current content. That may appear inconvenient, but does not prevent `WeakMap/WeakSet` from doing their main job -- be an "additional" storage of data for objects which are stored/managed at another place.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 总结
+<<<<<<< HEAD
- `Map` —— 是一个键值对集合
+=======
+Regular collections:
+- `Map` -- is a collection of keyed values.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
和普通 `Object` 的区别:
@@ -421,7 +541,13 @@ messages.shift();
- 和 array 不同,set 不允许元素重新排序。
- 保持插入的顺序。
+<<<<<<< HEAD
- `WeakMap` —— `Map` 的一个变体,仅允许对象作为键,并且当对象由于其他原因不可引用的时候将其删除。
+=======
+Collections that allow garbage-collection:
+
+- `WeakMap` -- a variant of `Map` that allows only objects as keys and removes them once they become inaccessible by other means.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- 它不支持整体的操作:没有 `size` 属性,没有 `clear()` 方法,没有迭代器。
@@ -429,4 +555,8 @@ messages.shift();
- 同样不支持 `size/clear()` 和迭代器。
+<<<<<<< HEAD
`WeakMap` 和 `WeakSet` 被用作主要对象存储的次要数据结构补充。一旦对象从存储移除,那么存在于 `WeakMap/WeakSet` 的数据将会被自动清除。
+=======
+`WeakMap` and `WeakSet` are used as "secondary" data structures in addition to the "main" object storage. Once the object is removed from the main storage, if it is only found in the `WeakMap/WeakSet`, it will be cleaned up automatically.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md b/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md
index e69de29bb2..27a7b418ab 100644
--- a/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md
+++ b/1-js/05-data-types/08-keys-values-entries/01-sum-salaries/solution.md
@@ -0,0 +1,29 @@
+```js run demo
+function sumSalaries(salaries) {
+
+ let sum = 0;
+ for (let salary of Object.values(salaries)) {
+ sum += salary;
+ }
+
+ return sum; // 650
+}
+
+let salaries = {
+ "John": 100,
+ "Pete": 300,
+ "Mary": 250
+};
+
+alert( sumSalaries(salaries) ); // 650
+```
+Or, optionally, we could also get the sum using `Object.values` and `reduce`:
+
+```js
+// reduce loops over array of salaries,
+// adding them up
+// and returns the result
+function sumSalaries(salaries) {
+ return Object.values(salaries).reduce((a, b) => a + b, 0) // 650
+}
+```
diff --git a/1-js/05-data-types/08-keys-values-entries/article.md b/1-js/05-data-types/08-keys-values-entries/article.md
index 3ba7685ac0..ece5862c49 100644
--- a/1-js/05-data-types/08-keys-values-entries/article.md
+++ b/1-js/05-data-types/08-keys-values-entries/article.md
@@ -45,7 +45,7 @@ let user = {
};
```
-- `Object.keys(user) = [name, age]`
+- `Object.keys(user) = ["name", "age"]`
- `Object.values(user) = ["John", 30]`
- `Object.entries(user) = [ ["name","John"], ["age",30] ]`
diff --git a/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md b/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md
index f3e3704324..b2213323ac 100644
--- a/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md
+++ b/1-js/05-data-types/09-destructuring-assignment/1-destruct-user/task.md
@@ -2,9 +2,9 @@ importance: 5
---
-# 解构赋值
+# Destructuring assignment
-有以下对象:
+We have an object:
```js
let user = {
@@ -13,18 +13,18 @@ let user = {
};
```
-写一个解构赋值语句使得:
+Write the destructuring assignment that reads:
-- `name` 属性赋值给变量 `name`。
-- `years` 属性赋值给 `age`。
-- `isAdmin` 属性赋值给变量 `isAdmin`(如果属性缺失则赋值为 false)。
+- `name` property into the variable `name`.
+- `years` property into the variable `age`.
+- `isAdmin` property into the variable `isAdmin` (false if absent)
-赋值语句后的值必须是:
+The values after the assignment should be:
```js
let user = { name: "John", years: 30 };
-// 等号左侧是你的代码
+// your code to the left side:
// ... = user
alert( name ); // John
diff --git a/1-js/05-data-types/09-destructuring-assignment/6-max-salary/_js.view/solution.js b/1-js/05-data-types/09-destructuring-assignment/6-max-salary/_js.view/solution.js
index d95cf1b1e5..f4bd5c761c 100644
--- a/1-js/05-data-types/09-destructuring-assignment/6-max-salary/_js.view/solution.js
+++ b/1-js/05-data-types/09-destructuring-assignment/6-max-salary/_js.view/solution.js
@@ -3,7 +3,7 @@ function topSalary(salaries) {
let max = 0;
let maxName = null;
- for(let [name, salary] of Object.entries(salaries)) {
+ for(const [name, salary] of Object.entries(salaries)) {
if (max < salary) {
max = salary;
maxName = name;
diff --git a/1-js/05-data-types/09-destructuring-assignment/article.md b/1-js/05-data-types/09-destructuring-assignment/article.md
index 5e7e7b42b6..15eea1cb57 100644
--- a/1-js/05-data-types/09-destructuring-assignment/article.md
+++ b/1-js/05-data-types/09-destructuring-assignment/article.md
@@ -31,8 +31,13 @@ alert(surname); // Kantor
let [firstName, surname] = "Ilya Kantor".split(' ');
```
+<<<<<<< HEAD
````smart header="\"解构\"并不意味着\"破坏\""
这种语法叫做“解构赋值”,因为它通过将结构中的各元素复制到变量中来达到“解构”的目的。但数组本身是没有被修改的。
+=======
+````smart header="\"Destructuring\" does not mean \"destructive\"."
+It's called "destructuring assignment," because it "destructurizes" by copying items into variables. But the array itself is not modified.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
也就是以下代码的更精简写法而已:
```js
@@ -42,6 +47,7 @@ let surname = arr[1];
```
````
+<<<<<<< HEAD
````smart header="忽略第一个元素"
数组中不想要的元素也可以通过添加额外的逗号来把它丢弃:
@@ -49,12 +55,25 @@ let surname = arr[1];
*!*
// 不需要第一个和第二个元素
let [, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
+=======
+````smart header="Ignore elements using commas"
+Unwanted elements of the array can also be thrown away via an extra comma:
+
+```js run
+*!*
+// second element is not needed
+let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
*/!*
alert( title ); // Consul
```
+<<<<<<< HEAD
在以上的代码中,数组的第一个和第二个元素被跳过,第三个元素被赋值给了 `title` 变量,剩下的元素也被跳过了。
+=======
+In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array is also skipped.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
````
````smart header="用于等号右侧的任何可迭代对象"
@@ -128,6 +147,7 @@ alert(name1); // Julius
alert(name2); // Caesar
*!*
+// Note that type of `rest` is Array.
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2
@@ -146,6 +166,7 @@ let [firstName, surname] = [];
*/!*
alert(firstName); // undefined
+alert(surname); // undefined
```
如果我们想要提供一个“默认值”给未赋值的变量,我们可以使用 `=` 来提供:
@@ -335,7 +356,11 @@ let title, width, height;
}
```
+<<<<<<< HEAD
为了告诉 JavaScript 这不是一个代码块,我们可以把整个赋值表达式用括号 `(...)` 包起来:
+=======
+To show JavaScript that it's not a code block, we can wrap the whole assignment in parentheses `(...)`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let title, width, height;
@@ -383,6 +408,8 @@ alert(item2); // Donut
除了 `extra` 属性的整个 `options` 对象都能被赋值给对应的变量。
+Note that `size` and `items` itself is not destructured.
+

最终,我们得到了 `width`、`height`、`item1`、`item2` 和具有默认值的 `title` 变量。
@@ -407,7 +434,11 @@ function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
}
```
+<<<<<<< HEAD
现实情况下的问题就是你怎么记得住这么多参数的顺序,通常集成开发环境工具(IDE)会尽力帮助我们,特别是当代码有良好的文档注释的时候,但… 另一个问题就是当大部分的参数采用默认值就好的情况下,怎么调用这个函数。
+=======
+In real-life, the problem is how to remember the order of arguments. Usually IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
难道像这样?
@@ -503,7 +534,11 @@ showMenu(); // Menu 100 200
let {prop : varName = default, ...} = object
```
+<<<<<<< HEAD
这表示属性 `prop` 会被赋值给变量 `varName`,如果没有这个属性的话,就会使用 `default` 的值。
+=======
+ This means that property `prop` should go into the variable `varName` and, if no such property exists, then the `default` value should be used.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- 解构数组的语法:
@@ -511,6 +546,10 @@ showMenu(); // Menu 100 200
let [item1 = default, item2, ...rest] = array
```
+<<<<<<< HEAD
数组的第一个元素赋值给 `item1`,第二个元素赋值给 `item2`,剩下的所有组成另一个数组 `rest`。
+=======
+ The first item goes to `item1`; the second goes into `item2`, all the rest makes the array `rest`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- 更多复杂的案例情况下,等号左侧必须和等号右侧有相同的结构。
diff --git a/1-js/05-data-types/09-destructuring-assignment/destructuring-complex.png b/1-js/05-data-types/09-destructuring-assignment/destructuring-complex.png
index 50c4ffc93a..c46bf6e45c 100644
Binary files a/1-js/05-data-types/09-destructuring-assignment/destructuring-complex.png and b/1-js/05-data-types/09-destructuring-assignment/destructuring-complex.png differ
diff --git a/1-js/05-data-types/09-destructuring-assignment/destructuring-complex@2x.png b/1-js/05-data-types/09-destructuring-assignment/destructuring-complex@2x.png
index bb908281df..26032a3d62 100644
Binary files a/1-js/05-data-types/09-destructuring-assignment/destructuring-complex@2x.png and b/1-js/05-data-types/09-destructuring-assignment/destructuring-complex@2x.png differ
diff --git a/1-js/05-data-types/10-date/2-get-week-day/solution.md b/1-js/05-data-types/10-date/2-get-week-day/solution.md
index 3ffff7c6e7..8c76ef6384 100644
--- a/1-js/05-data-types/10-date/2-get-week-day/solution.md
+++ b/1-js/05-data-types/10-date/2-get-week-day/solution.md
@@ -2,7 +2,7 @@
我们创建一个星期数组,这样可以通过它的序号得到名称:
-```js run
+```js run demo
function getWeekDay(date) {
let days = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];
diff --git a/1-js/05-data-types/10-date/3-weekday/solution.md b/1-js/05-data-types/10-date/3-weekday/solution.md
index 58f81bb35d..6b1e67d005 100644
--- a/1-js/05-data-types/10-date/3-weekday/solution.md
+++ b/1-js/05-data-types/10-date/3-weekday/solution.md
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
```js run
function getLocalDay(date) {
@@ -12,3 +13,5 @@ function getLocalDay(date) {
alert( getLocalDay(new Date(2012, 0, 3)) ); // 2
```
+=======
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/10-date/3-weekday/task.md b/1-js/05-data-types/10-date/3-weekday/task.md
index 353a34ba1e..1c043ceb4e 100644
--- a/1-js/05-data-types/10-date/3-weekday/task.md
+++ b/1-js/05-data-types/10-date/3-weekday/task.md
@@ -4,7 +4,11 @@ importance: 5
# 欧洲的星期表示方法
+<<<<<<< HEAD
欧洲国家的星期计算是从星期一(数字 1)开始,然后星期二(数字 2),直到星期日(数字 7)。写一个函数 `getLocalDay(date)`,返回日期的欧洲式星期数。
+=======
+European countries have days of week starting with Monday (number 1), then Tuesday (number 2) and till Sunday (number 7). Write a function `getLocalDay(date)` that returns the "European" day of week for `date`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js no-beautify
let date = new Date(2012, 0, 3); // 3 Jan 2012
diff --git a/1-js/05-data-types/10-date/4-get-date-ago/solution.md b/1-js/05-data-types/10-date/4-get-date-ago/solution.md
index 08f5d35784..b5afa2980a 100644
--- a/1-js/05-data-types/10-date/4-get-date-ago/solution.md
+++ b/1-js/05-data-types/10-date/4-get-date-ago/solution.md
@@ -11,7 +11,7 @@ function getDateAgo(date, days) {
要实现这一点,我们可以复制这个日期,就像这样:
-```js run
+```js run demo
function getDateAgo(date, days) {
let dateCopy = new Date(date);
diff --git a/1-js/05-data-types/10-date/5-last-day-of-month/solution.md b/1-js/05-data-types/10-date/5-last-day-of-month/solution.md
index 65f61c5bae..4f642536e1 100644
--- a/1-js/05-data-types/10-date/5-last-day-of-month/solution.md
+++ b/1-js/05-data-types/10-date/5-last-day-of-month/solution.md
@@ -1,5 +1,5 @@
Let's create a date using the next month, but pass zero as the day:
-```js run
+```js run demo
function getLastDayOfMonth(year, month) {
let date = new Date(year, month + 1, 0);
return date.getDate();
diff --git a/1-js/05-data-types/10-date/6-get-seconds-today/solution.md b/1-js/05-data-types/10-date/6-get-seconds-today/solution.md
index 2af9ae5802..583a1f4976 100644
--- a/1-js/05-data-types/10-date/6-get-seconds-today/solution.md
+++ b/1-js/05-data-types/10-date/6-get-seconds-today/solution.md
@@ -22,5 +22,5 @@ alert( getSecondsToday() );
function getSecondsToday() {
let d = new Date();
return d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
-};
+}
```
diff --git a/1-js/05-data-types/10-date/8-format-date-relative/solution.md b/1-js/05-data-types/10-date/8-format-date-relative/solution.md
index 124c143190..34dc3f4092 100644
--- a/1-js/05-data-types/10-date/8-format-date-relative/solution.md
+++ b/1-js/05-data-types/10-date/8-format-date-relative/solution.md
@@ -1,6 +1,6 @@
为获取 `date` 距离当前时间的间隔 —— 我们将两个日期相减。
-```js run
+```js run demo
function formatDate(date) {
let diff = new Date() - date; // 差值用毫秒表示
@@ -57,12 +57,18 @@ function formatDate(date) {
let diffSec = Math.round(diffMs / 1000);
let diffMin = diffSec / 60;
let diffHour = diffMin / 60;
+<<<<<<< HEAD
// 格式化
year = year.toString().slice(-2);
+=======
+
+ // formatting
+ year = year.toString().slice(-2);
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
month = month < 10 ? '0' + month : month;
dayOfMonth = dayOfMonth < 10 ? '0' + dayOfMonth : dayOfMonth;
-
+
if (diffSec < 1) {
return 'right now';
} else if (diffMin < 1) {
diff --git a/1-js/05-data-types/10-date/article.md b/1-js/05-data-types/10-date/article.md
index 8fed5dfb9d..3dbf9b98a2 100644
--- a/1-js/05-data-types/10-date/article.md
+++ b/1-js/05-data-types/10-date/article.md
@@ -2,7 +2,11 @@
让我一起探讨一个新的内置对象:[日期](mdn:js/Date)。该对象存储日期、时间以及提供管理它们的方法。
+<<<<<<< HEAD
举个例子,我们可以使用它来存储创建、修改事件的时间,或者用来度量时间开销,再或者用来打印当前时间。
+=======
+For instance, we can use it to store creation/modification times, to measure time, or just to print out the current date.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## 创建
@@ -39,7 +43,13 @@
```js run
let date = new Date("2017-01-26");
- alert(date); // Thu Jan 26 2017 ...
+ alert(date);
+ // The time portion of the date is assumed to be midnight GMT and
+ // is adjusted according to the timezone the code is run in
+ // So the result could be
+ // Thu Jan 26 2017 11:00:00 GMT+1100 (Australian Eastern Daylight Time)
+ // or
+ // Wed Jan 25 2017 16:00:00 GMT-0800 (Pacific Standard Time)
```
`new Date(year, month, date, hours, minutes, seconds, ms)`
@@ -108,7 +118,11 @@ alert( date.getHours() );
alert( date.getUTCHours() );
```
+<<<<<<< HEAD
在以上给出的方法中,有两个与众不同的,它们没有 UTC 版本:
+=======
+Besides the given methods, there are two special ones that do not have a UTC-variant:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
[getTime()](mdn:js/Date/getTime)
: 返回日期的时间戳 —— 从 1970-1-1 00:00:00 UTC+0 开始的毫秒数。
@@ -418,4 +432,8 @@ alert(`Loading started ${performance.now()}ms ago`);
// 小数点后超过 3 位是错误,只有前三位是正确的
```
+<<<<<<< HEAD
Node.JS 拥有 `microtime` 模块以及其他方法。从技术上来说,任何设备和环境都允许获取更精确的数值,不只是 `Date` 对象。
+=======
+Node.js has `microtime` module and other ways. Technically, any device and environment allows to get more precision, it's just not in `Date`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/11-json/article.md b/1-js/05-data-types/11-json/article.md
index e7127b9c0e..adfa1f7fe0 100644
--- a/1-js/05-data-types/11-json/article.md
+++ b/1-js/05-data-types/11-json/article.md
@@ -66,10 +66,17 @@ alert(json);
方法 `JSON.stringify(student)` 接受对象并将其转换为一个字符串。
+<<<<<<< HEAD
得到的 `json` 字符串是一个被称为 **JSON 编码**或者**序列化**或者**字符串化**或者**编组**的对象。我们准备好通过网线传输或存储。
请注意,JSON 编码的对象与对象字面量有几个重要的区别:
+=======
+The resulting `json` string is called a *JSON-encoded* or *serialized* or *stringified* or *marshalled* object. We are ready to send it over the wire or put into a plain data store.
+
+
+Please note that a JSON-encoded object has several important differences from the object literal:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
- 字符串使用双引号。JSON 中没有单引号或反引号。所以 `'John'` 转成 `"John"`。
- 对象属性名称也是双引号的。这是强制性的。所以 `age:30` 转成 `"age":30`。
@@ -131,7 +138,7 @@ let meetup = {
title: "Conference",
*!*
room: {
- number: 123,
+ number: 23,
participants: ["john", "ann"]
}
*/!*
@@ -190,7 +197,11 @@ replacer
space
: 文本添加缩进、空格和换行符
+<<<<<<< HEAD
大部分情况,`JSON.stringify` 仅与第一个参数一起使用。但是,如果我们需要微调替换过程,比如过滤掉循环引用,我们可以使用 `JSON.stringify` 的第二个参数。
+=======
+Most of the time, `JSON.stringify` is used with the first argument only. But if we need to fine-tune the replacement process, like to filter out circular references, we can use the second argument of `JSON.stringify`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
如果我们传递一组属性给它,只有这一组属性会被编码
@@ -244,7 +255,11 @@ alert( JSON.stringify(meetup, *!*['title', 'participants', 'place', 'name', 'num
幸运的是,我们也可以使用一个函数作为 `replacer`。
+<<<<<<< HEAD
该函数将调用每个 `(key,value)` 对,并且返回 “replacement” 值,它将被用来代替原来的值。
+=======
+The function will be called for every `(key, value)` pair and should return the "replaced" value, which will be used instead of the original one.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
在我们的例子中,除 `occupiedBy` 外我们都可以按照原样返回 `value`。要忽略 `occupiedBy`,下面的代码返回 `undefined`:
@@ -281,7 +296,11 @@ number: 23
请注意 `replacer` 函数获取包括嵌套对象和数组项的每个键/值对。它被递归地应用。`replacer` 里面 `this` 的值是包含当前属性的对象。
+<<<<<<< HEAD
第一个调用很特别。它是使用特殊的“包装对象”制作的: `{"": meetup}`。换句话说,第一个 `(key,value)` 对是空键,并且该值是整个目标对象。这就是为什么上面的例子中第一行是 `":[object Object]"` 的原因。
+=======
+The first call is special. It is made using a special "wrapper object": `{"": meetup}`. In other words, the first `(key, value)` pair has an empty key, and the value is the target object as a whole. That's why the first line is `":[object Object]"` in the example above.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
基于这个理念为 `replacer` 提供了更强大的功能:如有必要,它有机会分析和替换/跳过整个对象。
@@ -332,7 +351,11 @@ alert(JSON.stringify(user, null, 2));
## 定制 "toJSON"
+<<<<<<< HEAD
像 `toString` 进行字符串转换,对象可以提供 `toJSON` 方法来进行 JSON 转换。如果可用,`JSON.stringify` 会自动调用它。
+=======
+Like `toString` for string conversion, an object may provide method `toJSON` for to-JSON conversion. `JSON.stringify` automatically calls it if available.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -361,7 +384,11 @@ alert( JSON.stringify(meetup) );
在这里我们可以看到 `date` `(1)` 变成了一个字符串。这是因为所有日期都有一个内置的 `toJSON` 方法来返回这种类型的字符串。
+<<<<<<< HEAD
现在让我们为对象 `room` 添加一个自定义的 `toJSON`:
+=======
+Now let's add a custom `toJSON` for our object `room` `(2)`:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let room = {
@@ -409,7 +436,11 @@ str
: JSON 字符串解析。
reviver
+<<<<<<< HEAD
: 将为每个 `(key,value)` 对调用的可选函数(键,值)进行转换。
+=======
+: Optional function(key,value) that will be called for each `(key, value)` pair and can transform the value.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
例如:
@@ -520,8 +551,16 @@ alert( schedule.meetups[1].date.getDate() ); // works!
## 总结
+<<<<<<< HEAD
- JSON 是一种数据格式,对于大多数编程语言都有自己的独立标准和库。
- JSON 支持 objects,arrays,strings,numbers,booleans 和 `null`。
- JavaScript 提供序列化成 JSON 的方法 [JSON.stringify](mdn:js/JSON/stringify)和解析 JSON 方法 [JSON.parse](mdn:js/JSON/parse)。
- 这两种方法都支持用于智能读/写的转换函数。
- 如果一个对象具有 `toJSON`,那么它可被 `JSON.stringify` 调用。
+=======
+- JSON is a data format that has its own independent standard and libraries for most programming languages.
+- JSON supports plain objects, arrays, strings, numbers, booleans, and `null`.
+- JavaScript provides methods [JSON.stringify](mdn:js/JSON/stringify) to serialize into JSON and [JSON.parse](mdn:js/JSON/parse) to read from JSON.
+- Both methods support transformer functions for smart reading/writing.
+- If an object has `toJSON`, then it is called by `JSON.stringify`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
diff --git a/1-js/05-data-types/11-json/json-meetup.png b/1-js/05-data-types/11-json/json-meetup.png
index 0a26e0a679..2686664249 100644
Binary files a/1-js/05-data-types/11-json/json-meetup.png and b/1-js/05-data-types/11-json/json-meetup.png differ
diff --git a/1-js/05-data-types/11-json/json-meetup@2x.png b/1-js/05-data-types/11-json/json-meetup@2x.png
index b5f6a40129..a8f2cd6094 100644
Binary files a/1-js/05-data-types/11-json/json-meetup@2x.png and b/1-js/05-data-types/11-json/json-meetup@2x.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.png b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.png
index c45418ff4d..d0d37e35e7 100644
Binary files a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.png and b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree@2x.png b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree@2x.png
index 6fc39ae130..3a937c64cd 100644
Binary files a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree@2x.png and b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree@2x.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index bcc4af5f7e..62ce4dfa52 100644
--- a/1-js/06-advanced-functions/01-recursion/article.md
+++ b/1-js/06-advanced-functions/01-recursion/article.md
@@ -318,9 +318,15 @@ let company = {
或者说,一家公司有很多部门。
+<<<<<<< HEAD
- 一个部门有员工列表,比如,`销售`部有 2 名员工:John 和 Alice。
- 或者一个部门可能划分为几个子部门,比如`开发`有两个分支:`网站`和`内部`,它们都有自己的员工。
- 当一个子部门增长时,它可能会划分为子部门(或者团队)。
+=======
+- A department may have an array of staff. For instance, `sales` department has 2 employees: John and Alice.
+- Or a department may split into subdepartments, like `development` has two branches: `sites` and `internals`. Each of them has their own staff.
+- It is also possible that when a subdepartment grows, it divides into subsubdepartments (or teams).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
比如,`网站`部门在未来可能会分为`网站 A` 和 `网站 B`。它们可能还会再分,没有图示,脑补一下吧。
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-0.png b/1-js/06-advanced-functions/01-recursion/linked-list-0.png
index 000a80da8c..c694e7021f 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list-0.png and b/1-js/06-advanced-functions/01-recursion/linked-list-0.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-0@2x.png b/1-js/06-advanced-functions/01-recursion/linked-list-0@2x.png
index 5a2368694f..1fe50ace43 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list-0@2x.png and b/1-js/06-advanced-functions/01-recursion/linked-list-0@2x.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.png b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.png
index 477989ad8a..b4c89ecdf0 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.png and b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1@2x.png b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1@2x.png
index 41de7661c4..6b5b95a0fa 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1@2x.png and b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1@2x.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-split.png b/1-js/06-advanced-functions/01-recursion/linked-list-split.png
index ac22034905..310a360665 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list-split.png and b/1-js/06-advanced-functions/01-recursion/linked-list-split.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-split@2x.png b/1-js/06-advanced-functions/01-recursion/linked-list-split@2x.png
index 201c66f150..2de39ca4f5 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list-split@2x.png and b/1-js/06-advanced-functions/01-recursion/linked-list-split@2x.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list.png b/1-js/06-advanced-functions/01-recursion/linked-list.png
index 64b6fb2b72..80fabffc6a 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list.png and b/1-js/06-advanced-functions/01-recursion/linked-list.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list@2x.png b/1-js/06-advanced-functions/01-recursion/linked-list@2x.png
index c28fa82594..1e6dc14839 100644
Binary files a/1-js/06-advanced-functions/01-recursion/linked-list@2x.png and b/1-js/06-advanced-functions/01-recursion/linked-list@2x.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/recursion-pow.png b/1-js/06-advanced-functions/01-recursion/recursion-pow.png
index 30577f89c2..354f012714 100644
Binary files a/1-js/06-advanced-functions/01-recursion/recursion-pow.png and b/1-js/06-advanced-functions/01-recursion/recursion-pow.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/recursion-pow@2x.png b/1-js/06-advanced-functions/01-recursion/recursion-pow@2x.png
index c19973420d..22ae944108 100644
Binary files a/1-js/06-advanced-functions/01-recursion/recursion-pow@2x.png and b/1-js/06-advanced-functions/01-recursion/recursion-pow@2x.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/recursive-salaries.png b/1-js/06-advanced-functions/01-recursion/recursive-salaries.png
index 2b90154090..b40783a9b4 100644
Binary files a/1-js/06-advanced-functions/01-recursion/recursive-salaries.png and b/1-js/06-advanced-functions/01-recursion/recursive-salaries.png differ
diff --git a/1-js/06-advanced-functions/01-recursion/recursive-salaries@2x.png b/1-js/06-advanced-functions/01-recursion/recursive-salaries@2x.png
index 261ab144ed..e37597128f 100644
Binary files a/1-js/06-advanced-functions/01-recursion/recursive-salaries@2x.png and b/1-js/06-advanced-functions/01-recursion/recursive-salaries@2x.png differ
diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md
index a5c7457f0d..37b93d09d8 100644
--- a/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md
+++ b/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md
@@ -61,8 +61,13 @@ function showName(firstName, lastName, ...titles) {
showName("Julius", "Caesar", "Consul", "Imperator");
```
+<<<<<<< HEAD
````warn header="Rest 参数必须放到参数列表的末尾"
Rest 参数会收集参数列表中剩余的所有参数,所以下面这种用法是行不通的:
+=======
+````warn header="The rest parameters must be at the end"
+The rest parameters gather all remaining arguments, so the following does not make sense and causes an error:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js
function f(arg1, ...rest, arg2) { // ...rest 后面还有个 arg2?!
@@ -119,7 +124,13 @@ function f() {
f(1); // 1
```
+<<<<<<< HEAD
我们已经知道箭头函数自身是没有 `this` 的,现在我们更进一步还知道它缺少 `arguments` 这个特殊的对象。
+=======
+````
+
+As we remember, arrow functions don't have their own `this`. Now we know they don't have the special `arguments` object either.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
## Spread 操作符(展开操作符) [#spread-operator]
@@ -135,7 +146,11 @@ alert( Math.max(3, 5, 1) ); // 5
假如我们已有数组 `[3, 5, 1]`,我们该如何用它调用 `Math.max` 呢?
+<<<<<<< HEAD
直接把数组“原样”传入是不会奏效的,因为 `Math.max` 期待你传入一系列的数值型参数,而不是单一的数组:
+=======
+Passing it "as is" won't work, because `Math.max` expects a list of numeric arguments, not a single array:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js run
let arr = [3, 5, 1];
@@ -145,7 +160,11 @@ alert( Math.max(arr) ); // NaN
*/!*
```
+<<<<<<< HEAD
毫无疑问我们不可能手动地去一一设置参数 `Math.max(arg[0], arg[1], arg[2])`,因为我们不确定需要设置多少个参数。待代码最终执行时,这个参数数组可能很大,也可能啥也没用。这样手动设置实为下策。
+=======
+And surely we can't manually list items in the code `Math.max(arr[0], arr[1], arr[2])`, because we may be unsure how many there are. As our script executes, there could be a lot, or there could be none. And that would get ugly.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
**Spread 操作符** 来拯救你了!它看起来和 Rest 参数操作符很像,都表示为 `...`,但是二者完全做了相反的事。
diff --git a/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md b/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md
index 87ac80b37d..cd18e62bdc 100644
--- a/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md
+++ b/1-js/06-advanced-functions/03-closure/4-closure-sum/solution.md
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
为了使第二个括号有效,第一个(括号)必须返回一个函数。
+=======
+For the second parentheses to work, the first ones must return a function.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
就像这样:
diff --git a/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md b/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md
index 0f9c9a3c8a..bd8525ede7 100644
--- a/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md
+++ b/1-js/06-advanced-functions/03-closure/4-closure-sum/task.md
@@ -6,7 +6,11 @@ importance: 4
编写一个像 `sum(a)(b) = a+b` 这样工作的 `sum` 函数。
+<<<<<<< HEAD
是的,就是这种通过双括号的方式(并不是错误)。
+=======
+Yes, exactly this way, using double parentheses (not a mistype).
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子:
diff --git a/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md b/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md
index 020d44ac62..c191c1ad96 100644
--- a/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md
+++ b/1-js/06-advanced-functions/03-closure/6-filter-through-function/solution.md
@@ -14,7 +14,7 @@ alert( arr.filter(inBetween(3, 6)) ); // 3,4,5,6
# inArray 筛选器
-```js run
+```js run demo
function inArray(arr) {
return function(x) {
return arr.includes(x);
diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy.png b/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy.png
index d51e8167f8..8e39564ffe 100644
Binary files a/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy.png and b/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy.png differ
diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy@2x.png b/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy@2x.png
index e70edbd6d4..39cc13a422 100644
Binary files a/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy@2x.png and b/1-js/06-advanced-functions/03-closure/8-make-army/lexenv-makearmy@2x.png differ
diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/solution.md b/1-js/06-advanced-functions/03-closure/8-make-army/solution.md
index ff1370eff6..065450c953 100644
--- a/1-js/06-advanced-functions/03-closure/8-make-army/solution.md
+++ b/1-js/06-advanced-functions/03-closure/8-make-army/solution.md
@@ -55,9 +55,13 @@ function makeArmy() {
作为结果,所有的 `shooter` 都是从外部词法环境获得同样一个值最后的 `i=10`。
+<<<<<<< HEAD
修改起来是很简单的:
+=======
+We can fix it by moving the variable definition into the loop:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
-```js run
+```js run demo
function makeArmy() {
let shooters = [];
@@ -80,9 +84,15 @@ army[0](); // 0
army[5](); // 5
```
+<<<<<<< HEAD
现在正常工作了,因为`for (..) {...}` 内的代码块每次执行都会创建一个新的词法环境,其中具有对应的 `i` 的值。
所以,现在 `i` 值的距离(显示数字的地方更近了。现在它不是在 `makeArmy()` 词法环境中,而是在对应的当前循环迭代的词法环境中。`shooter` 从它创建的位置获得值。
+=======
+Now it works correctly, because every time the code block in `for (let i=0...) {...}` is executed, a new Lexical Environment is created for it, with the corresponding variable `i`.
+
+So, the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds the current loop iteration. That's why now it works.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb

@@ -90,7 +100,6 @@ army[5](); // 5
其他技巧也是可以的,让我们了解一下,以便让我们更好地理解这个问题:
-
```js run
function makeArmy() {
let shooters = [];
diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md
index 3dc10afabf..49e8fee7d5 100644
--- a/1-js/06-advanced-functions/03-closure/article.md
+++ b/1-js/06-advanced-functions/03-closure/article.md
@@ -1,9 +1,15 @@
# 闭包
+<<<<<<< HEAD
JavaScript 是一种非常面向函数的语言。它给我们很大的发挥空间。函数创建后,可以赋值给其他变量或作为参数传递给另一个函数,并在完全不同的位置进行调用。
我们知道函数可以访问其外部变量;这是一个常用的特性。
+=======
+JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created dynamically, copied to another variable or passed as an argument to another function and called from a totally different place later.
+
+We know that a function can access variables outside of it, this feature is used quite often.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
但是当外部变量变化时会发生什么呢?函数获得的是最新的值还是创建时的值呢?
@@ -63,33 +69,59 @@ JavaScript 是一种非常面向函数的语言。它给我们很大的发挥空
要了解究竟发生了什么,首先我们要来讨论一下『变量』究竟是什么?
+<<<<<<< HEAD
在 JavaScript 中,每个运行的函数、代码块或整个程序,都有一个称为**词法环境(Lexical Environment)**的关联对象。
+=======
+In JavaScript, every running function, code block `{...}`, and the script as a whole have an internal (hidden) associated object known as the *Lexical Environment*.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
词法环境对象由两部分组成:
+<<<<<<< HEAD
1. **环境记录(Environment Record)**—— 一个把所有局部变量作为其属性(包括一些额外信息,比如 `this` 值)的对象。
2. **外部词法环境(outer lexical environment)**的引用 —— 通常是嵌套当前代码(当前花括号之外)之外代码的词法环境。
所以,『变量』只是环境记录这个特殊内部对象的属性。『访问或修改变量』意味着『访问或改变词法环境的一个属性』。
+=======
+1. *Environment Record* -- an object that stores all local variables as its properties (and some other information like the value of `this`).
+2. A reference to the *outer lexical environment*, the one associated with the outer code.
+
+**So, a "variable" is just a property of the special internal object, `Environment Record`. "To get or change a variable" means "to get or change a property of that object".**
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
举个例子,这段简单的代码中只有一个词法环境:

+<<<<<<< HEAD
这是一个所谓的与整个程序关联的全局词法环境。在浏览器中,所有的 `
```
+<<<<<<< HEAD
4. 而且,虽然是小问题但仍然重要的一点是:全局范围内 `this` 的值是 `window`。
+=======
+4. And, a minor thing, but still: the value of `this` in the global scope is `window`.
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```js untrusted run no-strict refresh
alert(this); // window
```
+<<<<<<< HEAD
为什么这样做?在语言创建时,将多个方面合并到单一 `window` 对象中的想法就是“简化”,但此后许多事情发生了变化,小型脚本变成了需要恰当构架的大型应用程序。
不同脚本(可能来自不同的源)之间的变量可以互相访问好不好?
@@ -84,6 +144,21 @@ window.alert("Hello");
如果我们在 `
```
+<<<<<<< HEAD
- 两个模块的变量彼此不可见:
+=======
+- Two modules that do not see variables of each other:
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```html run
```
- 然后最后一个小问题是,模块中 `this` 的顶级值是 `undefined`(为什么它一定得是 `window` ?):
+=======
+ alert(x); // Error: undeclared variable
+
+ ```
+
+- And, the last minor thing, the top-level value of `this` in a module is `undefined` (why should it be `window` anyway?):
+>>>>>>> a0266c574c0ab8a0834dd38ed65e7e4ee27f9cdb
```html run
```
+<<<<<<< HEAD
**使用 `
-
-
-
-