Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.05.2019, 09:58
Аспирант
Отправить личное сообщение для DarkPhoenix Посмотреть профиль Найти все сообщения от DarkPhoenix
 
Регистрация: 11.05.2019
Сообщений: 30

Функция - конструктор Person
function Person(firstname, lastname, age){
this.firstname = firstname;
this.lastname = lastname;
this.age = age;

}
const person = new Person('Vince', 'Vicked', 55);
console.log(person);

Тут все сделал.
Загвоздка в ограничениях.

- firstname и lastname всегда должны быть строки от 3 до 20 символов, содержащие только латинские буквы
- age всегда должно быть числом в диапазоне (0, 150) включительно
- если что-либо из перечисленного не выполнено, выкиньте ошибку

Куда их вставлять? И через что? if или что другое? Буду рад помощи, или коду. Спасибо

Последний раз редактировалось DarkPhoenix, 21.05.2019 в 15:18.
Ответить с цитированием
  #2 (permalink)  
Старый 21.05.2019, 11:44
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Вариант №1
class Person {
	constructor(firstName, lastName, age) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;

		Object.freeze(this);
	}

	set firstName(value) {
		if(value instanceof String === false && typeof value !== "string")
			throw new TypeError(`No instance for ‘${Object(value).constructor.name}’ arising from a use of ‘firstName’`);

		if(value.length < 3 || value.length > 20)
			throw new RangeError(`Invalid first name length`);

		if(!/^[a-zçéäëïöü'’‘–—-]{3,20}$/i.test(value))
			throw new Error(`Invalid first name`);

		this._firstName = value;
	}

	get firstName() {
		return this._firstName;
	}

	set lastName(value) {
		if(value instanceof String === false && typeof value !== "string")
			throw new TypeError(`No instance for ‘${Object(value).constructor.name}’ arising from a use of ‘lastName’`);

		if(value.length < 3 || value.length > 20)
			throw new RangeError(`Invalid last name length`);

		if(!/^[a-zçéäëïöü'’‘–—-]{3,20}$/i.test(value))
			throw new Error(`Invalid last name`);

		this._lastName = value;
	}

	get lastName() {
		return this._lastName;
	}

	set age(value) {
		if(value instanceof Number === false && typeof value !== "number")
			throw new TypeError(`No instance for ‘${Object(value).constructor.name}’ arising from a use of ‘age’`);

		if(value < 0 || value > 150)
			throw new RangeError(`Invalid age`);

		this._age = value;
	}

	get age() {
		return this._age;
	}
}


Вариант №2
class Person {
	constructor(firstName, lastName, age) {
		function validateName(type, name) {
			if(name instanceof String === false && typeof name !== "string")
				throw new TypeError(`No instance for ‘${Object(name).constructor.name}’ arising from a use of ‘${type}’`);

			if(name.length < 3 || name.length > 20)
				throw new RangeError(`Invalid length of ‘${type}’`);

			if(!/^[a-zçéäëïöü'’‘–—-]{3,20}$/i.test(name))
				throw new Error(`Invalid name of ‘${type}’`);
		}

		// names validation
		validateName("firstName", firstName);
		validateName("lastName", lastName);

		// age validation
		if(age instanceof Number === false && typeof age !== "number")
			throw new TypeError(`No instance for ‘${Object(age).constructor.name}’ arising from a use of ‘age’`);

		if(age < 0 || age > 150)
			throw new RangeError(`Invalid age`);

		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;

		Object.freeze(this);
	}
}


UPD Если вы хотите использовать синтаксис функции для объявления класса, то не забудьте проверить, чтобы this был инициализирован соответствующим образом! Поскольку если вы вызовете Person как функцию, то this указывает на глобальный объект/на другой this, если вызов в контексте и т. д. Вариант №3, похожий на ваш
function Person(firstName, lastName, age) {
	if(!new.target)
		throw new TypeError("Constructor ‘Person’ requires ‘new’");

	// проверки аргументов, например, как в примерах выше

	this.firstName = firstName;
	this.lastName = lastName;
	this.age = age;
	
	Object.freeze(this);
}

Последний раз редактировалось Malleys, 21.05.2019 в 12:11.
Ответить с цитированием
  #3 (permalink)  
Старый 21.05.2019, 15:51
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Сообщение от Malleys
if(value instanceof String === false && typeof value !== "string")
почему недостаточно typeof ?
Ответить с цитированием
  #4 (permalink)  
Старый 21.05.2019, 16:07
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от рони
почему недостаточно typeof ?
А если представитель наследует от String? А если new String("name")?
Ответить с цитированием
  #5 (permalink)  
Старый 21.05.2019, 16:08
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,004

Сообщение от рони
почему недостаточно typeof ?
На случай, если прилетит объектная обертка, для которой typeof будет 'object'
Сообщение от Malleys
if(!new.target)
Пока что мало поддерживается браузерами. А там где это есть, можно и class использовать без всяких бабелей.
Ответить с цитированием
  #6 (permalink)  
Старый 21.05.2019, 16:32
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от Alexandroppolus
На случай, если прилетит объектная обертка, для которой typeof будет 'object'
На самом деле на случай, когда будет передана примитивная строка.

На самом же деле можно всё проще сделать: например, возраст можно рассматривать как тип Age, который является подмножеством Number. Тоже самое с именем, тип Name является подмножеством типа String. Т. е. не каждое число является возрастом, но любой возраст является числом!

Вот, наверное, самый лучший вариант...
class Age extends Number {
	constructor(age) {
		super(age);

		if(super.constructor.isNaN(this) || this < 0 || this > 150)
			throw new TypeError("Invalid age");
	}
}

class Name extends String {
	constructor(name) {
		super(name);

		if(this.length < 3 || this.length > 20 || !/^[a-zçéäëïöü'’‘–—-]{3,20}$/i.test(this))
			throw new TypeError("Invalid name");
	}
}

class Person {
	constructor(firstName, lastName, age) {
		this.firstName = new Name(firstName);
		this.lastName  = new Name(lastName);
		this.age       = new Age(age);

		Object.freeze(this);
	}
}


Сообщение от Alexandroppolus
Пока что [new.target] мало поддерживается браузерами.
на самом деле поддерживается очень хорошо!

Последний раз редактировалось Malleys, 21.05.2019 в 16:40.
Ответить с цитированием
  #7 (permalink)  
Старый 21.05.2019, 16:49
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,004

Сообщение от Malleys
Вот, наверное, самый лучший вариант...
Будут обертки вместо примитивных типов. Рано или поздно наткнемся на функцию, которая проверяет только typeof (без instanceof). Лучше всегда примитивы юзать.
Сообщение от Malleys
на самом деле поддерживается очень хорошо!
Действительно. Я эту страницу на русском смотрел, видимо, она устаревшая

Последний раз редактировалось Alexandroppolus, 21.05.2019 в 16:51.
Ответить с цитированием
  #8 (permalink)  
Старый 21.05.2019, 17:15
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Malleys
this > 150
Всем бы столько жить. )
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Функция вызывается несколько раз KiberQ Общие вопросы Javascript 11 01.03.2017 15:45
не вызывается функция при изменении option soft4you Общие вопросы Javascript 1 23.07.2014 17:41
AJAX функция для новых html-элементов broadcast77 AJAX и COMET 25 03.03.2014 14:01
Практика: Функция конструктор и геттер. Magneto Общие вопросы Javascript 2 07.07.2013 14:01
хитросплетения Global,контекст,this,Reference kefi Общие вопросы Javascript 109 20.11.2009 23:34