Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
**Error**!
**错误**!

Try it:
试一下:

```js run
let user = {
Expand All @@ -11,19 +11,19 @@ let user = {
(user.go)() // error!
```

The error message in most browsers does not give understanding what went wrong.
大多数浏览器中的错误信息并不能说明出现了什么问题。

**The error appears because a semicolon is missing after `user = {...}`.**
**出现此错误是因为在 `user = {...}` 之后遗漏了一个分号。**

JavaScript does not assume a semicolon before a bracket `(user.go)()`, so it reads the code like:
JavaScript 不会在括号 `(user.go)()` 前自动插入分号,所以解析的代码如下:

```js no-beautify
let user = { go:... }(user.go)()
```

Then we can also see that such a joint expression is syntactically a call of the object `{ go: ... }` as a function with the argument `(user.go)`. And that also happens on the same line with `let user`, so the `user` object has not yet even been defined, hence the error.
那么,我们可以看到这样一个连接的表达式,在语法构成上,把对象 `{ go: ... }` 作为一个方法调用,并且传递的参数为 `(user.go)`。并且让 `let user`在同一行赋值,因此 `user` 没被定义(之前)就会出现错误

If we insert the semicolon, all is fine:
如果我们插入该分号,一切都会正常:

```js run
let user = {
Expand All @@ -34,7 +34,7 @@ let user = {
(user.go)() // John
```

Please note that brackets around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters.
要注意的是 `(user.go)` 内的括号没有什么意义。通常用它们来设置操作的顺序,但在这里点 `.` 总是会先执行,所以并没有什么影响。分号是唯一重要的。



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 2

---

# Syntax check
# 检查语法

What is the result of this code?
这段代码的结果是什么?


```js no-beautify
Expand All @@ -16,4 +16,4 @@ let user = {
(user.go)()
```

P.S. There's a pitfall :)
提示:有一个陷阱哦 :)
16 changes: 8 additions & 8 deletions 1-js/04-object-basics/04-object-methods/3-why-this/solution.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@

Here's the explanations.
这里是解释。

1. That's a regular object method call.
1. 它是一个常规的方法调用。

2. The same, brackets do not change the order of operations here, the dot is first anyway.
2. 同样,括号没有改变执行的顺序,点总是首先执行。

3. Here we have a more complex call `(expression).method()`. The call works as if it were split into two lines:
3. 这里我们有一个更复杂的 `(expression).method()` 调用。这个调用就像被分成了两行(代码)一样:

```js no-beautify
f = obj.go; // calculate the expression
f(); // call what we have
```

Here `f()` is executed as a function, without `this`.
   这里的 `f()` 是作为一个没有(设定)`this` 的函数执行的。

4. The similar thing as `(3)`, to the left of the dot `.` we have an expression.
4. `(3)` 相类似,在点 `.` 的左边也有一个表达式。

To explain the behavior of `(3)` and `(4)` we need to recall that property accessors (dot or square brackets) return a value of the Reference Type.
要解释 `(3)` `(4)` 的原因,我们需要回顾一下属性访问器(点或方括号)返回的值是引用类型的。

Any operation on it except a method call (like assignment `=` or `||`) turns it into an ordinary value, which does not carry the information allowing to set `this`.
除了方法调用之外的任何操作(如赋值 `=` `||` 等)把它变为了一个没有设定 `this` 信息的普通值。

6 changes: 3 additions & 3 deletions 1-js/04-object-basics/04-object-methods/3-why-this/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 3

---

# Explain the value of "this"
# 解释 "this" 的值

In the code below we intend to call `user.go()` method 4 times in a row.
在下面的代码中,我们试图连续调用 4 次 `user.go()` 方法。

But calls `(1)` and `(2)` works differently from `(3)` and `(4)`. Why?
但是 `(1)` `(2)` `(3)` `(4)` 调用结果不同,为什么呢?

```js run no-beautify
let obj, method;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
**Answer: an error.**
**答案:一个错误。**

Try it:
试一下:
```js run
function makeUser() {
return {
Expand All @@ -14,15 +14,15 @@ let user = makeUser();
alert( user.ref.name ); // Error: Cannot read property 'name' of undefined
```

That's because rules that set `this` do not look at object literals.
这是因为设置的 `this` 的规则并没有找到对象字面量。

Here the value of `this` inside `makeUser()` is `undefined`, because it is called as a function, not as a method.
这里 `makeUser()` 中的 `this` 值是 `undefined`,因为它是被作为函数调用的,而不是方法调用。

And the object literal itself has no effect on `this`. The value of `this` is one for the whole function, code blocks and object literals do not affect it.
对象字面量本身对于 `this` 没有影响。`this` 的值是整个函数,代码段和对象字面量对它没有影响。

So `ref: this` actually takes current `this` of the function.
所以,`ref: this` 实际上取的是该函数当前的 `this`

Here's the opposite case:
这里有个反例:

```js run
function makeUser() {
Expand All @@ -41,6 +41,6 @@ let user = makeUser();
alert( user.ref().name ); // John
```

Now it works, because `user.ref()` is a method. And the value of `this` is set to the object before dot `.`.
现在正常了,因为 `user.ref()` 是一个方法。`this` 的值设置为点 `.` 之前的这个对象。


Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Using "this" in object literal
# 在对象字面量中使用 "this"

Here the function `makeUser` returns an object.
这里 `makeUser` 函数返回了一个对象。

What is the result of accessing its `ref`? Why?
访问 `ref` 的结果是什么?为什么?

```js
function makeUser() {
Expand Down
10 changes: 5 additions & 5 deletions 1-js/04-object-basics/04-object-methods/7-calculator/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ importance: 5

---

# Create a calculator
# 创建一个计算器(对象)

Create an object `calculator` with three methods:
创建一个有三个方法的 `calculator` 对象:

- `read()` prompts for two values and saves them as object properties.
- `sum()` returns the sum of saved values.
- `mul()` multiplies saved values and returns the result.
- `read()` 提示输入两个值,将其保存为对象属性。
- `sum()` 返回保存的值的和。
- `mul()` 将保存的值相乘并返回其结果。

```js
let calculator = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The solution is to return the object itself from every call.
解决方案就是在每次调用后返回这个对象本身。

```js run
let ladder = {
Expand Down Expand Up @@ -26,7 +26,7 @@ let ladder = {
ladder.up().up().down().up().down().showStep(); // 1
```

We also can write a single call per line. For long chains it's more readable:
我们也可以每行一个调用。对于长链接它更具可读性:

```js
ladder
Expand Down
10 changes: 5 additions & 5 deletions 1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 2

---

# Chaining
# 链式(调用)

There's a `ladder` object that allows to go up and down:
有一个可以上下移动的 `ladder` 对象:

```js
let ladder = {
Expand All @@ -21,7 +21,7 @@ let ladder = {
};
```

Now, if we need to make several calls in sequence, can do it like this:
现在如果我们要依次执行几次调用,可以这样做:

```js
ladder.up();
Expand All @@ -30,10 +30,10 @@ ladder.down();
ladder.showStep(); // 1
```

Modify the code of `up` and `down` to make the calls chainable, like this:
修改 `up` `down` 的代码让调用可以链接,就像这样:

```js
ladder.up().up().down().showStep(); // 1
```

Such approach is widely used across JavaScript libraries.
此种方法在 JavaScript 库中被广泛使用。
Loading