TLENS » 2014.02.19 20:35

У меня есть класс Video мне нужны потомки этого класса YouTube и Vkontakte.

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
var localBase = require('./localBase');
var chpurl = require('libs/chpurl');
var secToMin = require('libs/secToMin');
/**
*
* @param property
* @returns {*}
* @constructor
* @description Хранит в себе информацию о видеофайлах.
*/
var Video = function (property) {
// Проверка на существование параметров.
if (typeof property == "object") {
// Два свойства которые обьязательно должны быть для составления уникального ид
// см. геттер key. (Object.defineProperty(Video.prototype, 'key'...)
if (typeof property.type == "string" && typeof property.id == "string") {
this.id = property.id; // ид ролика с источника.
this.type = property.type; // "v", "y", "m", "o"...
// Запрашиваем видео с кэша дабы не плодить обьекты.
if (typeof (video = localBase.isVideo(this.key)) == "object")
{
// Возвращаем ссылку на обьект видеофайла
return video;
}
// Далее заполнение обьекта данными
if (typeof property.title == "string")
this.title = property.title;
 
if (typeof property.duration == "number")
this.duration = property.duration;
 
if (typeof property.description == "string")
this.description = property.description;
 
if (typeof property.duration == "string") {
property.duration = parseInt(property.duration);
if (!isNaN(property.duration))
this.duration = property.duration;
}
// Передаем ссылку на обьект в локальную базу
localBase.setVideo(this);
} else {
//console.log(property);
}
}
};
 
// Далее обьявляем обьщие методы (Прототипы)
 
 
// Составление уникального ключа с типа и ид
Object.defineProperty(Video.prototype, 'key', {
get: function () {
if (!(typeof this.type == "string" && typeof this.id == "string"))
return;
if (typeof this._tmp != "object") {
this._tmp = {};
}
if (typeof this._tmp.key != "string") {
this._tmp.key = this.type + '_' + this.id;
}
return this._tmp.key;
},
configurable: true,
enumerable: true
});
 
// Получение строкового отображения продолжительности видеофайла
Object.defineProperty(Video.prototype, 'strTime', {
get: function () {
if (typeof this._tmp != "object") {
this._tmp = {};
}
if (typeof this._tmp.strTime != "string") {
this._tmp.strTime = secToMin(this.duration);
}
return this._tmp.strTime;
},
configurable: true,
enumerable: true
});
 
// Генерация сылка на данный видеофайл. С дальнейшим кешированием в _tmp
Object.defineProperty(Video.prototype, 'url', {
get: function () {
if (!(typeof this.type == "string" && typeof this.id == "string"))
return '/404';
if (typeof this.title != "string")
this.title = 'video';
if (typeof this._tmp != "object") {
this._tmp = {};
}
if (typeof this._tmp.url != "string" || this._tmp.url == '')
this._tmp.url = '/' + chpurl.titleToUrl(this.title) + '/' + this.type + '_' + this.id;
//console.log(this);
return this._tmp.url;
 
},
configurable: true,
enumerable: true
});
module.exports = Video;

Вся проблема в том что Я нихрена не врубаюсь как сделать потомка этого класса что бы он вызывал конструктор с Video потом инициализировал свои свойства и методы.
В общем что у меня получилось.

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var Video = require('module/Video');
function VKVideo (properties) {
var video = new Video(properties);
if (typeof properties.image == "string")
video.image = properties.image;
if (typeof properties.hash == "string")
video.hash = properties.hash;
 
Object.defineProperty(video.__proto__, 'originalImage', {
get: function () {
return this.image;
},
configurable: true,
enumerable: true
});
return video;
};

И

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var YouTubeVideo = function (properties) {
var video = new Video(properties);
Object.defineProperty(video.__proto__, 'originalImage', {
get: function () {
if (typeof this._tmp != "object") {
this._tmp = {};
}
if (typeof this._tmp.originalImage != "string" || this._tmp.originalImage == '')
this._tmp.originalImage = 'https://i.ytimg.com/vi/' + this.id + '/hqdefault.jpg';
return this._tmp.originalImage;
 
},
configurable: true,
enumerable: true
});
return video;
};

Но только что Я обнаружил что данный вид присваивания геттера originalImage в одном так названом потоке хотя там конструктор превращаеться в обычную функцию и поэтому будет перекрывать этот геттер в другом потомке.
Те в  VKVideo мне нужно всего вернуть переменную this.image но в потомке YouTube не нужно свойство image так как ссылку на скрин можно сгенерировать зная ид.
Но после обьявления прототипа метода в YouTube он автоматически меняется в Vkontakte. Это связано с тем что Я не нашел способа как унаследовать правильно. И решил просто сделать функцию создающую внутри обьект Video далее инициализирует нужные свойства.
Пробовал использовать внутри конструктора Video.apply(this, properties); Но Я так и не понял как им пользоваться.

TLENS » 2014.02.19 21:50

Разобрался. Короче. Не пойму почему при Video.apply Не создавались свойства в потомке. В общем заюзал Video.call и все сработало. А проблему с перекрытием методов между потомками решил с помощью:
YouTubeVideo.prototype = Object.create(Video.prototype);
Теперь у меня получаеться такая хрень.

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var Video = require('module/Video');
 
var YouTubeVideo = function (properties) {
var video = Video.call(this,properties);
if (typeof video == 'object')
return video;
};
 
var VKVideo = function (properties) {
var video = Video.call(this,properties);
if (typeof video == 'object')
return video;
};
 
YouTubeVideo.prototype = Object.create(Video.prototype);
VKVideo.prototype = Object.create(Video.prototype);

В общем спасибо за внимание. Иногда несколько чашечек кофе делают чудеса)))

Gemorroj » 2014.02.19 23:48

ты помечай что речь о Node.js =)

TLENS » 2014.02.20 00:10

Gemorroj Да Я особо никакой разницы не вижу. Ну разве что подключение других скриптов. "require"