174 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			174 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|   | --- | |||
|  | title: Classes | |||
|  | localeTitle: Классы | |||
|  | --- | |||
|  | ## Классы
 | |||
|  | 
 | |||
|  | JavaScript не имеет понятия классов по своей сути. | |||
|  | 
 | |||
|  | Но мы могли бы имитировать функциональность класса, используя прототипный характер JavaScript. | |||
|  | 
 | |||
|  | В этой статье предполагается, что у вас есть базовое понимание [прототипов](/src/pages/javascript/prototypes/index.md) . | |||
|  | 
 | |||
|  | Для ясности предположим, что мы хотим создать класс, который может сделать следующее | |||
|  | 
 | |||
|  | ```javascript | |||
|  | var p = new Person('James','Bond'); // create a new instance of Person class  | |||
|  |     p.log() // Output: 'I am James Bond' // Accessing a function in the class  | |||
|  |     // Using setters and getters  | |||
|  |     p.profession = 'spy'  | |||
|  |     p.profession // output: James bond is a spy  | |||
|  | ``` | |||
|  | 
 | |||
|  | ### Использование ключевого слова class
 | |||
|  | 
 | |||
|  | Как и на любом другом языке программирования, теперь вы можете использовать ключевое слово `class` для создания класса. | |||
|  | 
 | |||
|  | Это не поддерживается в старых браузерах и было представлено в ECMAScript 2015. | |||
|  | 
 | |||
|  | ```javascript | |||
|  | class Person {  | |||
|  |     constructor(firstName, lastName) {  | |||
|  |         this._firstName = firstName;  | |||
|  |         this._lastName = lastName;  | |||
|  |     }  | |||
|  |   | |||
|  |     log() {  | |||
|  |         console.log('I am', this._firstName, this._lastName);  | |||
|  |     }  | |||
|  |   | |||
|  |     // setters  | |||
|  |     set profession(val) {  | |||
|  |         this._profession = val;  | |||
|  |     }  | |||
|  |     // getters  | |||
|  |     get profession() {  | |||
|  |         console.log(this._firstName, this._lastName, 'is a', this._profession);  | |||
|  |     }  | |||
|  |   | |||
|  |  }  | |||
|  | ``` | |||
|  | 
 | |||
|  |    | |||
|  |    | |||
|  | 
 | |||
|  | `class` - это просто синтаксический сахар над существующей моделью наследования на основе прототипов JavaScript. | |||
|  | 
 | |||
|  | В общем, программисты используют следующие способы создания класса в JavaScript. | |||
|  | 
 | |||
|  | ### Использование методов, добавленных в прототипы:
 | |||
|  | 
 | |||
|  | Здесь все методы добавляются к прототипу | |||
|  | 
 | |||
|  | ```javascript | |||
|  | function Person(firstName, lastName) {  | |||
|  |     this._firstName = firstName;  | |||
|  |     this._lastName = lastName;  | |||
|  |  }  | |||
|  |   | |||
|  |  Person.prototype.log = function() {  | |||
|  |     console.log('I am', this._firstName, this._lastName);  | |||
|  |  }  | |||
|  |   | |||
|  |  // This line adds getters and setters for the profession object. Note that in general you could just write your own get and set functions like the 'log' method above.  | |||
|  |  // Since in this example we are trying the mimic the class above, we try to use the getters and setters property provided by JavaScript  | |||
|  |  Object.defineProperty(Person.prototype, 'profession', {  | |||
|  |     set: function(val) {  | |||
|  |         this._profession = val;  | |||
|  |     },  | |||
|  |     get: function() {  | |||
|  |         console.log(this._firstName, this._lastName, 'is a', this._profession);  | |||
|  |     }  | |||
|  |  })  | |||
|  | ``` | |||
|  | 
 | |||
|  | Вы также можете написать прототипы для функции `Person` как `Person` ниже | |||
|  | 
 | |||
|  | ```javascript | |||
|  | Person.prototype = {  | |||
|  |     log: function() {  | |||
|  |         console.log('I am ', this._firstName, this._lastName);  | |||
|  |     }  | |||
|  |     set profession(val) {  | |||
|  |         this._profession = val;  | |||
|  |     }  | |||
|  |   | |||
|  |     get profession() {  | |||
|  |         console.log(this._firstName, this._lastName, 'is a', this._profession);  | |||
|  |     }  | |||
|  |   | |||
|  |  }  | |||
|  | ``` | |||
|  | 
 | |||
|  | ### Использование встроенных методов
 | |||
|  | 
 | |||
|  | Здесь методы добавляются внутренне вместо прототипа | |||
|  | 
 | |||
|  | ```javascript | |||
|  | function Person(firstName, lastName) {  | |||
|  |     this._firstName = firstName;  | |||
|  |     this._lastName = lastName;  | |||
|  |   | |||
|  |     this.log = function() {  | |||
|  |         console.log('I am ', this._firstName, this._lastName);  | |||
|  |     }  | |||
|  |   | |||
|  |     Object.defineProperty(this, 'profession', {  | |||
|  |         set: function(val) {  | |||
|  |             this._profession = val;  | |||
|  |         },  | |||
|  |         get: function() {  | |||
|  |             console.log(this._firstName, this._lastName, 'is a', this._profession);  | |||
|  |         }  | |||
|  |     })  | |||
|  |  }  | |||
|  | ``` | |||
|  | 
 | |||
|  | ### Скрытие деталей в классах с символами
 | |||
|  | 
 | |||
|  | Чаще всего некоторые свойства и методы должны быть скрыты для предотвращения доступа извне функции. С помощью классов, чтобы получить эту функциональность, один из способов сделать это - использовать символы. Символ - это новый встроенный тип JavaScript, который можно вызвать, чтобы дать новое значение символа. Каждый символ уникален и может использоваться как ключ на объекте. Таким образом, один случай использования символов состоит в том, что вы можете добавить что-то к объекту, который у вас может не быть, и вы можете не захотеть столкнуться с любыми другими ключами объекта, поэтому создание нового и добавление как свойство этого объекта с использованием символа является самым безопасным , Кроме того, когда значение символа добавляется к объекту; никто другой не узнает, как это получить. | |||
|  | 
 | |||
|  | ```javascript | |||
|  | class Person {  | |||
|  |     constructor(firstName, lastName) {  | |||
|  |         this._firstName = firstName;  | |||
|  |         this._lastName = lastName;  | |||
|  |     }  | |||
|  |   | |||
|  |     log() {  | |||
|  |         console.log('I am', this._firstName, this._lastName);  | |||
|  |     }  | |||
|  |   | |||
|  |     // setters  | |||
|  |     set profession(val) {  | |||
|  |         this._profession = val;  | |||
|  |     }  | |||
|  |     // getters  | |||
|  |     get profession() {  | |||
|  |         console.log(this._firstName, this._lastName, 'is a', this._profession);  | |||
|  |     }  | |||
|  |  // With the above code, even though we can access the properties outside the function to change their content what if we don't want that.  | |||
|  |  // Symbols come to rescue.  | |||
|  |  let s_firstname  = new Symbol();  | |||
|  |   | |||
|  |  class Person {  | |||
|  |     constructor(firstName, lastName) {  | |||
|  |         this[s_firstName] = firstName;  | |||
|  |         this._lastName = lastName;  | |||
|  |     }  | |||
|  |   | |||
|  |     log() {  | |||
|  |         console.log('I am', this._firstName, this._lastName);  | |||
|  |     }  | |||
|  |   | |||
|  |     // setters  | |||
|  |     set profession(val) {  | |||
|  |         this._profession = val;  | |||
|  |     }  | |||
|  |     // getters  | |||
|  |     get profession() {  | |||
|  |         console.log(this[s_firstName], this._lastName, 'is a', this._profession);  | |||
|  |     }  | |||
|  | ``` | |||
|  | 
 | |||
|  | #### Дополнительная информация:
 |