Наследование объекта через Object.create?

Проблема в том, что в следующем коде, anotherDocument.location.pathname предопределяет Document.location.pathname (но при этом, не предопределяет в Location). Нужно, чтобы Document.location не изменялся при изменении в anotherDocument.location.

Как я понял, создается новый экземпляр Document.location, но при этом, location передается ссылкой.

Как это сделать самым новым способом?

var http = require('http'),
	util = require('util');

var Location = {
	get hash() {
		if (typeof this._hash !== 'undefined') {
			return '#' + this._hash;
		}
		else {
			return '';
		}
	},
	set hash(hash) {
		delete this._href;

		Object.defineProperty(this, '_hash', {
			value: hash,
			configurable: true
		})
	},
	get host() {
		if (typeof this._host === 'undefined') {
			host = '';

			if (this.hostname !== '') {
				host += this.hostname + this.port;
			}

			Object.defineProperty(this, '_host', {
				value: host,
				configurable: true
			});
		}
		return this._host;
	},
	get hostname() {
		if (typeof this._hostname !== 'undefined') {
			return this._hostname;
		}
		else {
			return '';
		}
	},
	set hostname(hostname) {
		delete this._href;
		delete this._host;
		delete this._origin;

		Object.defineProperty(this, '_hostname', {
			value: hostname,
			configurable: true
		});
	},
	get href() {
		if (typeof this._href === 'undefined') {
			href = this.origin + this.pathname + this.search + this.hash;

			Object.defineProperty(this, '_href', {
				value: href,
				configurable: true
			});
		}
		return this._href;
	},
	get origin() {
		if (typeof this._origin === 'undefined') {
			origin = '';

			if (this.host !== '') {
				origin += this.protocol + this.host;
			}

			Object.defineProperty(this, '_origin', {
				value: origin,
				configurable: true
			});
		}
		return this._origin;
	},
	get pathname() {
		if (typeof this._pathname !== 'undefined') {
			return '/' + this._pathname;
		}
		else {
			return '/';
		}
	},
	set pathname(pathname) {
		delete this._href;

		Object.defineProperty(this, '_pathname', {
			value: pathname,
			configurable: true
		});
	},
	get search() {
		if (typeof this._search !== 'undefined') {
			return '?' + this._search;
		}
		else {
			return '';
		}
	},
	set search(search) {
		delete this._href;

		Object.defineProperty(this, '_search', {
			value: search,
			configurable: true
		});
	},
	get port() {
		if (typeof this._port !== 'undefined') {
			return ':' + this._port;
		}
		else {
			return '';
		}
	},
	set port(port) {
		delete this._href;

		Object.defineProperty(this, '_port', {
			value: port,
			configurable: true
		});
	},
	get protocol() {
		if (typeof this._protocol !== 'undefined') {
			return this._protocol + '://';
		}
		else {
			return '//';
		}
	},
	set protocol (protocol) {
		delete this._href;
		delete this._origin;
		delete this._host;

		Object.defineProperty(this, '_protocol', {
			value: protocol,
			configurable: true
		});
	}
}

var Document = {
	location: Object.create(Location)
}
Document.location.protocol = 'http';
Document.location.hostname = 'arturkohut.com';

var anotherDocument = Object.create(Document);
anotherDocument.location.pathname = 'take-me-home';

http.createServer(function(request, response) {
	response.writeHead(200);
	response.write(util.inspect(Document.location.href));
	response.end();
}).listen(80, '127.0.0.1');
  • Вопрос задан
  • 197 просмотров
Пригласить эксперта
Ответы на вопрос 1
IonDen
@IonDen
JavaScript developer. IonDen.com
Не так. Object.create(); создает новый объект и первым аргументом туда передается некий другой объект, который станет прототипом для этого объекта.

По этому создание нового объекта location через Object.create(Location) - совершенно нормально. Оригинальный объект при этом никак не меняется. Он только становится прототипом для нового объекта.

Пара примеров:
var a = Object.create(null); // создаст голый объект который не унаследует ничего
var b = Object.create(Object.prototype); // эквивалент var b = {};

var foo = {
    name: 'Yes'
};

var bar = Object.create(foo);
console.log(bar.name); // 'Yes' - возьмет из прототипа (foo)

// переопределим name
bar.name = 'No';
console.log(bar.name); // 'No'
console.log(foo.name); // 'Yes' - оригинал остался нетронутым
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы