1- ## Constructors
1+ ## 构造函数
22
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 ` 关键字方式调用的函数都被认为是构造函数。
55
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 ` 。
108
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 ` 对象 - 也就是新创建的对象。
1310
1411 function Foo() {
1512 this.bla = 1;
@@ -21,41 +18,48 @@ implicitly returns the value of `this` - the new object.
2118
2219 var test = new Foo();
2320
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 ` 。
2622
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 ` 表达式将会影响返回结果,但** 仅限** 于返回的是一个对象。
2924
3025 function Bar() {
3126 return 2;
3227 }
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+
3539 function Test() {
3640 this.value = 2;
3741
3842 return {
3943 foo: 1
4044 };
4145 }
42- new Test(); // the returned object
46+ new Test(); // 返回的对象
47+ // 译者注:这里得到的是函数返回的对象,而不是通过 new 关键字新创建的对象
48+ // 所有 (new Test()).value 为 undefined,但是 (new Test()).foo === 1。
4349
44- When the ` new ` keyword is omitted, the function will ** not ** return a new object.
50+ 如果 ` new ` 被遗漏了,则函数 ** 不会 ** 返回新创建的对象。
4551
4652 function Foo() {
47- this.bla = 1; // gets set on the global object
53+ this.bla = 1; // 获取设置全局参数
4854 }
4955 Foo(); // undefined
5056
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 ` 指向* 全局对象* 。
5459
55- ### Factories
60+ ### 工厂模式( Factories)
5661
57- In order to be able to omit the ` new ` keyword, the constructor function has to
58- explicitly return a value.
62+ 为了不使用 ` new ` 关键字,构造函数必须显式的返回一个值。
5963
6064 function Bar() {
6165 var value = 1;
@@ -72,25 +76,30 @@ explicitly return a value.
7276 new Bar();
7377 Bar();
7478
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+
7882
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 ` 属性的自定义对象)。
8285
83- In the above example, there is no functional difference between using and
84- not using the ` new ` keyword.
86+ 在上面的例子中,使用或者不使用 ` new ` 关键字没有功能性的区别。
8587
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"
8696
87- ### Creating new objects via factories
8897
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)
9199
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+ 为了创建新对象,我们可以创建一个工厂方法,并且在方法内构造一个新对象。
94103
95104 function Foo() {
96105 var obj = {};
@@ -107,22 +116,16 @@ new object inside of that factory.
107116 return obj;
108117 }
109118
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+
113122
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 ` 带来的问题,这似乎和语言本身的思想相违背。
120126
121- ### In conclusion
127+ ### 总结( In conclusion)
122128
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+ 最终使用哪种方式取决于应用程序的需求,选择一种代码书写风格并** 坚持** 下去才是最重要的。
128131
0 commit comments