-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmixins.js
191 lines (141 loc) · 4.56 KB
/
mixins.js
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// В традиционных языках программирования
// Миксины это классы, которые легко могут быть
// наследованы саб-классами с целью их расширения
// В javascript миксины применяются очень часто и
// представляют из себя по сути создание объектов
// путем копирования свойств и методов других объектов
var _ = require('lodash');
function mix() {
var arg, prop, child = {};
for (arg = 0; arg < arguments.length; arg += 1) {
for (prop in arguments[arg]) {
if (arguments[arg].hasOwnProperty(prop)) {
child[prop] = arguments[arg][prop];
}
}
}
return child;
}
/*========== Пример 1 ==========*/
function Cat(name) {
this.name = name || '';
}
Cat.prototype.meow = function() {
return this.name + ' meows';
}
function Bird(name) {
this.name = name || '';
}
Bird.prototype.fly = function() {
return this.name + ' flies';
}
function CatBird(name) {
this.name = name || '';
}
CatBird.prototype = mix(Cat.prototype, Bird.prototype);
var catBird = new CatBird('FooCat');
console.log(catBird.meow());
console.log(catBird.fly());
/*========== Пример 2 ==========*/
// Объект, который мы будем встраивать
var myMixins = {
moveUp: function(){
return "move up";
},
moveDown: function(){
return "move down";
},
stop: function(){
return "stop! in the name of love!";
}
};
// A skeleton carAnimator constructor
function CarAnimator(){
this.moveLeft = function(){
return "move left";
};
}
// A skeleton personAnimator constructor
function PersonAnimator(){
this.moveRandomly = function(){ /*..*/ };
}
// Extend both constructors with our Mixin
_.extend( CarAnimator.prototype, myMixins );
_.extend( PersonAnimator.prototype, myMixins );
// Create a new instance of carAnimator
var myAnimator = new CarAnimator();
console.log(myAnimator.moveLeft());
console.log(myAnimator.moveDown());
console.log(myAnimator.stop());
// Outputs:
// move left
// move down
// stop! in the name of love!
/*========== Пример 3 ==========*/
// В данном пример у нас есть возможность
// брать из миксинов только те свойства и методы,
// которые нам нужны
// Define a simple Car constructor
var Car = function ( settings ) {
this.model = settings.model || "no model provided";
this.color = settings.color || "no colour provided";
};
// Mixin
var Mixin = function () {};
Mixin.prototype = {
driveForward: function () {
console.log( "drive forward" );
},
driveBackward: function () {
console.log( "drive backward" );
},
driveSideways: function () {
console.log( "drive sideways" );
}
};
// Extend an existing object with a method from another
function augment( receivingClass, givingClass ) {
// only provide certain methods
if ( arguments[2] ) {
for ( var i = 2, len = arguments.length; i < len; i++ ) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
}
// provide all methods
else {
for ( var methodName in givingClass.prototype ) {
// check to make sure the receiving class doesn't
// have a method of the same name as the one currently
// being processed
if ( !Object.hasOwnProperty.call(receivingClass.prototype, methodName) ) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
// Alternatively (check prototype chain as well):
// if ( !receivingClass.prototype[methodName] ) {
// receivingClass.prototype[methodName] = givingClass.prototype[methodName];
// }
}
}
}
// Расширяем прототим класса Car методами driveForvard и driveBackward
augment( Car, Mixin, "driveForward", "driveBackward" );
// Create a new Car
var myCar = new Car({
model: "Ford Escort",
color: "blue"
});
// Test to make sure we now have access to the methods
myCar.driveForward();
myCar.driveBackward();
// Outputs:
// drive forward
// drive backward
// В даннном пример мы берем все методы их миксина
augment( Car, Mixin );
var mySportsCar = new Car({
model: "Porsche",
color: "red"
});
mySportsCar.driveSideways();
// Outputs:
// drive sideways