-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathset-prototype-of.ts
More file actions
107 lines (85 loc) · 2.77 KB
/
set-prototype-of.ts
File metadata and controls
107 lines (85 loc) · 2.77 KB
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
/**
* This module just installs a polyfill for Object.setPrototypeOf
* if it is not available natively. It also wraps Object.getPrototypeOf
* to work in conjunction with it. If this is not done Babel
* transpiled code will not work in IE<10.
*/
/***/
'setPrototypeOf' in Object || '__proto__' in {} || install();
//////////
/**
* Installs the polyfill.
*/
function install() {
var getPrototypeOf = Object['getPrototypeOf'];
Object.defineProperty(Object, 'getPrototypeOf', {
enumerable: false,
value(obj) {
return '__proto__' in obj ? obj.__proto__ : getPrototypeOf(obj);
}
});
Object.defineProperty(Object, 'setPrototypeOf', {
enumerable: false,
value: setPrototypeOf
});
//////////
/**
* Sets the prototype of an object.
*/
function setPrototypeOf(obj, proto) {
if (proto === Function) {
return obj;
}
var keys = Object.getOwnPropertyNames(proto),
key = keys[0],
i = 0,
descriptor;
while (key) {
if (!Object.getOwnPropertyDescriptor(obj, key)) {
descriptor = Object.getOwnPropertyDescriptor(proto, key);
if (typeof descriptor.get === 'function') {
bindKey(obj, key, descriptor);
} else if (typeof proto[key] === 'function') {
obj[key] = bindMethod(proto[key]);
} else {
bindKey(obj, key, null);
}
}
key = keys[++i];
}
proto.hasOwnProperty('__proto__') && setPrototypeOf(obj, proto.__proto__);
Object.defineProperty(obj, '__proto__', {enumerable: false, configurable: true, value: proto});
return obj;
}
/**
* Creates a wrapper method that invokes the super method.
*/
function bindMethod(method) {
return () => {
return method.apply(this, arguments);
}
}
/**
* Creates a getter and setter for proxying to the super property.
* @todo: Test this
*/
function bindKey(obj, key, descriptor) {
descriptor = descriptor || {
get: function() {
return obj.__proto__[key];
},
set: function(value) {
Object.defineProperty(obj, key, {
configurable: true,
writable: true,
value: value
});
}
};
Object.defineProperty(obj, key, {
configurable: true,
get: descriptor.get.bind(obj),
set: descriptor.set ? descriptor.set.bind(obj) : void 0
});
}
}