Функция Object.create. Конфигурация свойств объектов

Последнее обновление: 25.10.2023

Функция Object.create

Еще один способ создания объекта предоставляет функция Object.create, которая принимает два параметра. Первый параметр - прототип, на основе которого будет создаваться объект, а второй параметр - определение свойств и методов объекта:

const tom = Object.create(прототип, {  свойства и методы });

Например:

const tom = Object.create(Object.prototype, {  
	name: {    
		value: "Tom" 
	},  
	age: { 
		value: 39  
	},  
	print: {    
		value: function() { console.log(`Name: ${this.name}  Age: ${this.age}`);   
	}  
}});

console.log(tom.name);	// Tom
console.log(tom.age);	// 39
tom.print(); 			// Name: Tom  Age: 39

Здесь в качестве прототипа в функцию Object.create() передается прототип Object - Object.prototype. Второй параметр функции - определение свойств вида:

имя_свойства/метода: {
    value: значение_свойства/метода
}

Имени свойства/метода сопоставляется объект, в котором есть свойство value - это свойство собственно и хранит значение свойства/метода. Например, свойство age равно 39:

age: { 
	value: 39  
}

Для метода значением выступает определение функции.

После создания объекта мы можем обращаться к его свойствам и методам, как и в общем случае:

console.log(tom.age);	// 39

Подобный способ создания объектов может показаться чересчур громоздким и избыточным. Тем не менее он позволяет чуть детальнее настроить конфигурацию свойств. Так, кроме поля value при конфигурации свойства мы можем задать дополнительные поля:

  • writeable: хранит логическое значение, которое указывает, доступно ли это свойство для записи, то есть можно ли ему присвоить новое значение. По умолчанию этот атрибут имеет значение false.

  • enumerable: хранит логическое значение, которое указывает, является ли соответствующее свойство перечислимым, то есть включается ли это свойство при переборе свойств соответствующего объекта (например, с использованием цикла for...in). По умолчанию имеет значение false.

  • configurable: хранит логическое значение, которое указывает, можно ли изменить сам атрибут для соответствующего свойства, то есть можно ли впоследствии настроить свойство с помощью атрибутов. Значение по умолчанию для этого атрибута также равно false

  • set: определяет, какая функция вызывается при изменении значения свойства

  • get: определяет, какая функция вызывается при чтении значения свойства

Применим некоторые из этих атрибутов:

const tom = Object.create(Object.prototype, {  
	name: {    
		value: "Tom",
		enumerable: true,		// доступно для перебора
		writable: false		// НЕ доступно для записи
	},  
	age: { 
		value: 39,
		enumerable: true,		// доступно для перебора
		writable: true		// доступно для записи
	},  
	print: {    
		value: function() { console.log(`Name: ${this.name}  Age: ${this.age}`);},
		enumerable: false,		// не доступно для перебора
		writable: false,		// НЕ доступно для записи
	}  
});

console.log(tom.name);	// Tom
tom.name = "Tomas";
console.log(tom.name);	// Tom - свойство name не доступно для изменения

console.log(tom.age);	// 39
tom.age = 22;
console.log(tom.age);	// 22 - свойство age доступно для изменения 

tom.print(); 			// Name: Tom  Age: 22

// перебор объекта
for(prop in tom){
	console.log(prop);
}
// Консольный вывод:
// name
// age

В примере выше функция Object.create использует много кода для создания объекта. Но что, если у нас есть куча свойств и методов, но некоторая конфигурация (например, сделать свойство доступно только для чтения) нужна только для одного свойства? В этом случае мы можем создать объект стандартным образом, а все дополнительные свойства, которые требуют конфигурации, определить с помощью функции Object.defineProperty:

const tom = {
	age:39, 
	print: function() { console.log(`Name: ${this.name}  Age: ${this.age}`);}
};
Object.defineProperty(tom, "name", {    
		value: "Tom",
		writable: false		// НЕ доступно для записи
});

console.log(tom.name);	// Tom
tom.name = "Tomas";
console.log(tom.name);	// Tom - свойство name не доступно для изменения

tom.print(); 			// Name: Tom  Age: 22

Функция Object.defineProperty() принимает три параметра. Первый параметр - объект, для которого определяется свойство. Второй параметр - название свойства. Третий параметр - конфигурационный объект. То есть в данном случае доопределяем для объекта tom свойство name, которое будет достпуно только для чтения.

Если надо подобным образом доопределить несколько свойств, то применяется функция Object.defineProperties, которая принимает объект и набор конфигурационных настроек для добавляемых свойств:

const tom = { age:39 };
//  доопределяем свойства для объекта tom
Object.defineProperties(tom, {    
	name: {    				// определяем свойство name
		value: "Tom",		
		writable: false		// НЕ доступно для записи
	}, 
	print: {    	// определяем метод print
		value: function() { console.log(`Name: ${this.name}  Age: ${this.age}`);},
		writable: false,		// НЕ доступно для записи
	}  
});

tom.name = "Tomas"; // свойство name не доступно для изменения
tom.print = function(){console.log("Hello Word");}	// метод print не доступен для изменения

tom.print(); 			// Name: Tom  Age: 39

Стоит отметить, что подобным образом мы можем не только добавлять новые свойства, но и переопределять конфигурацию уже существующих свойств. Например:

const tom = {name: "Tom"};
// для свойства name запрещаем изменение
Object.defineProperty(tom, "name", { writable: false});
tom.name = "Tomas";
console.log(tom.name);	// Tom - значение свойства не изменилось
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850