1
- ## Constructors
1
+ ## 构造函数
2
2
3
- Constructors in JavaScript are yet again different from many other languages. Any
4
- function call that is preceded by the ` new ` keyword acts as a constructor.
3
+ JavaScript 中的构造函数和其它语言中的构造函数是不同的。
4
+ 通过 ` new ` 关键字方式调用的函数都被认为是构造函数。
5
5
6
- Inside the constructor - the called function - the value of ` this ` refers to a
7
- newly created ` Object ` . The [ ` prototype ` ] ( #object.prototype ) of this ** new**
8
- object is set to the ` prototype ` of the function object that was invoked as the
9
- constructor.
6
+ 在构造函数内部 - 也就是被调用的函数内 - ` this ` 指向新创建的对象 ` Object ` 。
7
+ 这个** 新创建** 的对象的 [ ` prototype ` ] ( #object.prototype ) 被指向到构造函数的 ` prototype ` 。
10
8
11
- If the function that was called has no explicit ` return ` statement, then it
12
- implicitly returns the value of ` this ` - the new object.
9
+ 如果被调用的函数没有显式的 ` return ` 表达式,则隐式的会返回 ` this ` 对象 - 也就是新创建的对象。
13
10
14
11
function Foo() {
15
12
this.bla = 1;
@@ -21,41 +18,48 @@ implicitly returns the value of `this` - the new object.
21
18
22
19
var test = new Foo();
23
20
24
- The above calls ` Foo ` as constructor and sets the ` prototype ` of the newly
25
- created object to ` Foo.prototype ` .
21
+ 上面代码把 ` Foo ` 作为构造函数调用,并设置新创建对象的 ` prototype ` 为 ` Foo.prototype ` 。
26
22
27
- In case of an explicit ` return ` statement the function returns the value
28
- specified that statement, ** but only** if the return value is an ` Object ` .
23
+ 显式的 ` return ` 表达式将会影响返回结果,但** 仅限** 于返回的是一个对象。
29
24
30
25
function Bar() {
31
26
return 2;
32
27
}
33
- new Bar(); // a new object
34
-
28
+ new Bar(); // 返回新创建的对象
29
+
30
+ // 译者注:new Bar() 返回的是新创建的对象,而不是数字的字面值 2。
31
+ // 因此 new Bar().constructor === Bar
32
+ // 但是如果返回的是数字对象,结果就不同了
33
+ // function Bar() {
34
+ // return new Number(2);
35
+ // }
36
+ // new Bar().constructor === Number
37
+
38
+
35
39
function Test() {
36
40
this.value = 2;
37
41
38
42
return {
39
43
foo: 1
40
44
};
41
45
}
42
- new Test(); // the returned object
46
+ new Test(); // 返回的对象
47
+ // 译者注:这里得到的是函数返回的对象,而不是通过 new 关键字新创建的对象
48
+ // 所有 (new Test()).value 为 undefined,但是 (new Test()).foo === 1。
43
49
44
- When the ` new ` keyword is omitted, the function will ** not ** return a new object.
50
+ 如果 ` new ` 被遗漏了,则函数 ** 不会 ** 返回新创建的对象。
45
51
46
52
function Foo() {
47
- this.bla = 1; // gets set on the global object
53
+ this.bla = 1; // 获取设置全局参数
48
54
}
49
55
Foo(); // undefined
50
56
51
- While the above example might still appear to work in some cases, due to the
52
- workings of [ ` this ` ] ( #function.this ) in JavaScript, it will use the
53
- * global object* as the value of ` this ` .
57
+ 虽然上例在有些情况下也能正常运行,但是由于 JavaScript 中 [ ` this ` ] ( #function.this ) 的工作原理,
58
+ 这里的 ` this ` 指向* 全局对象* 。
54
59
55
- ### Factories
60
+ ### 工厂模式( Factories)
56
61
57
- In order to be able to omit the ` new ` keyword, the constructor function has to
58
- explicitly return a value.
62
+ 为了不使用 ` new ` 关键字,构造函数必须显式的返回一个值。
59
63
60
64
function Bar() {
61
65
var value = 1;
@@ -72,25 +76,30 @@ explicitly return a value.
72
76
new Bar();
73
77
Bar();
74
78
75
- Both calls to ` Bar ` return the exact same thing, a newly create object which
76
- has a property called ` method ` on it, that is a
77
- [ Closure ] ( #function.closures ) .
79
+ 上面两种对 ` Bar ` 函数的调用返回的值完全相同,一个新创建的拥有 ` method ` 属性的对象被返回,
80
+ 其实这里创建了一个 [ 闭包 ] ( #function.closures ) 。
81
+
78
82
79
- It is also to note that the call ` new Bar() ` does ** not** affect the prototype
80
- of the returned object. While the prototype will be set on the newly created
81
- object, ` Bar ` never returns that new object.
83
+ 还需要注意,` new Bar() ` 并** 不会** 改变返回对象的原型(译者注:也就是返回对象的原型不会指向 Bar.prototype)。
84
+ 因为构造函数的原型会被指向到刚刚创建的新对象,而这里的 ` Bar ` 没有把这个新对象返回(译者注:而是返回了一个包含 ` method ` 属性的自定义对象)。
82
85
83
- In the above example, there is no functional difference between using and
84
- not using the ` new ` keyword.
86
+ 在上面的例子中,使用或者不使用 ` new ` 关键字没有功能性的区别。
85
87
88
+ // 译者注:上面两种方式创建的对象不能访问 Bar 原型链上的属性
89
+ var bar1 = new Bar();
90
+ typeof(bar1.method); // "function"
91
+ typeof(bar1.foo); // "undefined"
92
+
93
+ var bar2 = Bar();
94
+ typeof(bar2.method); // "function"
95
+ typeof(bar2.foo); // "undefined"
86
96
87
- ### Creating new objects via factories
88
97
89
- An often made recommendation is to ** not** use ` new ` since forgetting its use
90
- may lead to bugs.
98
+ ### 通过工厂模式创建新对象(Creating new objects via factories)
91
99
92
- In order to create new object, one should rather use a factory and construct a
93
- new object inside of that factory.
100
+ 我们常听到的一条忠告是** 不要** 使用 ` new ` 关键字来调用函数,因为如果忘记使用它就会导致错误。
101
+
102
+ 为了创建新对象,我们可以创建一个工厂方法,并且在方法内构造一个新对象。
94
103
95
104
function Foo() {
96
105
var obj = {};
@@ -107,22 +116,16 @@ new object inside of that factory.
107
116
return obj;
108
117
}
109
118
110
- While the above is robust against a missing ` new ` keyword and certainly makes
111
- the use of [ private variables ] ( #function.closures ) easier, it comes with some
112
- downsides.
119
+ 虽然上面的方式比起 ` new ` 的调用方式不容易出错,并且可以充分利用 [ 私有变量 ] ( #function.closures ) 带来的便利,
120
+ 但是随之而来的是一些不好的地方。
121
+
113
122
114
- 1 . It uses more memory since the created objects do ** not** share the methods
115
- on a prototype.
116
- 2 . In order to inherit the factory needs to copy all the methods from another
117
- object or put that object on the prototype of the new object.
118
- 3 . Dropping the prototype chain just because of a left out ` new ` keyword
119
- somehow goes against the spirit of the language.
123
+ 1 . 会占用更多的内存,因为新创建的对象** 不能** 共享原型上的方法。
124
+ 2 . 为了实现继承,工厂方法需要从另外一个对象拷贝所有属性,或者把一个对象作为新创建对象的原型。
125
+ 3 . 放弃原型链仅仅是因为防止遗漏 ` new ` 带来的问题,这似乎和语言本身的思想相违背。
120
126
121
- ### In conclusion
127
+ ### 总结( In conclusion)
122
128
123
- While omitting the ` new ` keyword might lead to bugs, it is certainly ** not** a
124
- reason to drop the use of prototypes altogether. In the end it comes down to
125
- which solution is better suited for the needs of the application, it is
126
- especially important to choose a specific style of object creation ** and stick**
127
- with it.
129
+ 虽然遗漏 ` new ` 关键字可能会导致问题,但这并** 不是** 放弃使用原型链的借口。
130
+ 最终使用哪种方式取决于应用程序的需求,选择一种代码书写风格并** 坚持** 下去才是最重要的。
128
131
0 commit comments