| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | --- | 
					
						
							|  |  |  | id: 587d7db2367417b2b2512b8a | 
					
						
							| 
									
										
										
										
											2021-02-06 04:42:36 +00:00
										 |  |  | title: >- | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  |   使用闭包保护对象内的属性不被外部修改 | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | challengeType: 1 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | forumTopicId: 18234 | 
					
						
							| 
									
										
										
										
											2021-01-13 03:31:00 +01:00
										 |  |  | dashedName: >- | 
					
						
							|  |  |  |   use-closure-to-protect-properties-within-an-object-from-being-modified-externally | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 00:37:30 -07:00
										 |  |  | # --description--
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | 在上一次挑战中,`bird` 有一个公共属性 `name`。 公共属性的定义就是:它可以在 `bird` 的定义范围之外被访问和更改。 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | bird.name = "Duffy"; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | 因此,代码的任何地方都可以轻松地将 `bird` 的 name 属性更改为任意值。 想想密码和银行账户之类的东西,如果代码库的任何部分都可以轻易改变他们。 那么将会引起很多问题。 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | 使属性私有化最简单的方法就是在构造函数中创建变量。 可以将该变量范围限定在构造函数中,而不是全局可用。 这样,属性只能由构造函数中的方法访问和更改。 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function Bird() { | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  |   let hatchedEgg = 10; | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   this.getHatchedEggCount = function() {  | 
					
						
							|  |  |  |     return hatchedEgg; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | let ducky = new Bird(); | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | ducky.getHatchedEggCount(); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | 这里的 `getHatchedEggCount` 是一种特权方法,因为它可以访问私有属性 `hatchedEgg`。 这是因为 `hatchedEgg` 是在与 `getHatchedEggCount` 相同的上下文中声明的。 在 JavaScript 中,函数总是可以访问创建它的上下文。 这就叫做 `closure`。 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 00:37:30 -07:00
										 |  |  | # --instructions--
 | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | 更改在 `Bird` 函数中声明的 `weight` 方法,使其成为私有变量。 然后,创建一个返回 `weight` 值 15 的 `getWeight` 方法。 | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 00:37:30 -07:00
										 |  |  | # --hints--
 | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | `weight` 属性应该是一个私有变量,值应该是 `15`。 | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 00:37:30 -07:00
										 |  |  | ```js | 
					
						
							|  |  |  | assert(code.match(/(var|let|const)\s+weight\s*\=\s*15\;?/g)); | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | 你的代码应该在 `Bird` 中创建一个名为 `getWeight` 方法,该方法返回私有变量 `weight`。 | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2021-02-06 04:42:36 +00:00
										 |  |  | assert(new Bird().getWeight() === 15); | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-14 21:20:39 -06:00
										 |  |  | 你的 `getWeight` 函数应该返回私有变量 `weight`。 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | ```js | 
					
						
							| 
									
										
										
										
											2020-12-16 00:37:30 -07:00
										 |  |  | assert(code.match(/((return\s+)|(\(\s*\)\s*\=\>\s*))weight\;?/g)); | 
					
						
							| 
									
										
										
										
											2018-10-10 18:03:03 -04:00
										 |  |  | ``` | 
					
						
							| 
									
										
										
										
											2020-08-04 15:15:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 03:31:00 +01:00
										 |  |  | # --seed--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## --seed-contents--
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function Bird() { | 
					
						
							|  |  |  |   this.weight = 15; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 00:37:30 -07:00
										 |  |  | # --solutions--
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 03:31:00 +01:00
										 |  |  | ```js | 
					
						
							|  |  |  | function Bird() { | 
					
						
							|  |  |  |   let weight = 15; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this.getWeight = () => weight; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` |