Last active
July 1, 2017 21:46
-
-
Save think49/283b7374e352e09fc131 to your computer and use it in GitHub Desktop.
es6-weakmap.js: ECMA-262 6th Edition (ECMAScript 2015) WeakMap polyfill
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* es6-weakmap.js | |
* WeakMap (ECMA-262 6th Edition / ECMAScript 2015) | |
* | |
* | |
* @version 0.9.2 | |
* @author think49 | |
* @url https://gist.github.com/think49/283b7374e352e09fc131 | |
* @license http://www.opensource.org/licenses/mit-license.php (The MIT License) | |
* @see <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-weakmap-constructor">23.3.1 The WeakMap Constructor – ECMA-262 6th Edition</a> | |
*/ | |
'use strict'; | |
if (typeof WeakMap !== 'function' && typeof Object.defineProperties === 'function') { | |
var WeakMap = (function (Object, isArray) { | |
var weakMapDataList = []; // [[WeakMapData]] internal slot | |
function WeakMap (/* [iterable] */) { | |
weakMapDataList.push([this, []]); | |
} | |
Object.defineProperties(WeakMap.prototype, { | |
get: { | |
writable: true, | |
enumerable: false, | |
configurable: true, | |
value: function get (key) { | |
if (Object(this) !== this) { // 2. If Type(thisArg) is not Object, throw a TypeError exception. | |
throw new TypeError('Method WeakMap.prototype.get called on incompatible receiver ' + this); | |
} | |
var i = 0, | |
l = weakMapDataList.length, | |
weakMapData, map, data; | |
while (i < l) { | |
weakMapData = weakMapDataList[i++]; | |
if (weakMapData[0] === this) { | |
if (Object(key) !== key) { // 5. If Type(key) is not Object, return undefined. | |
return; | |
} | |
map = weakMapData[1]; | |
i = 0, | |
l = map.length; | |
while (i < l) { | |
data = map[i++]; | |
if (data[0] === key) { | |
return data[1]; | |
} | |
} | |
return; | |
} | |
} | |
throw new TypeError('Method WeakMap.prototype.get called on incompatible receiver ' + this); // 3. If thisArg does not have a [[WeakMapData]] internal slot, throw a TypeError exception. | |
} | |
}, | |
set: { | |
writable: true, | |
enumerable: false, | |
configurable: true, | |
value: function set (key, value) { | |
if (Object(this) !== this) { // 2. If Type(thisArg) is not Object, throw a TypeError exception. | |
throw new TypeError('Method WeakMap.prototype.set called on incompatible receiver ' + this); | |
} | |
var i = 0, | |
l = weakMapDataList.length, | |
weakMapData, map, data; | |
while (i < l) { | |
weakMapData = weakMapDataList[i++]; | |
if (weakMapData[0] === this) { | |
if (Object(key) !== key) { // 5. If Type(key) is not Object, throw a TypeError exception. | |
throw new TypeError('Invalid value used as weak map key'); | |
} | |
map = weakMapData[1]; | |
i = 0, | |
l = map.length; | |
while (i < l) { | |
data = map[i++]; | |
if (data[0] === key) { | |
data[1] = value; | |
return this; | |
} | |
} | |
map.push([key, value]); | |
return this; | |
} | |
} | |
throw new TypeError('Method WeakMap.prototype.set called on incompatible receiver ' + this); // 3. If thisArg does not have a [[WeakMapData]] internal slot, throw a TypeError exception. | |
} | |
}, | |
has: { | |
writable: true, | |
enumerable: false, | |
configurable: true, | |
value: function has (key) { | |
if (Object(this) !== this) { // 2. If Type(thisArg) is not Object, throw a TypeError exception.exception. | |
throw new TypeError('Method WeakMap.prototype.has called on incompatible receiver ' + this); | |
} | |
var i = 0, | |
l = weakMapDataList.length, | |
weakMapData, map; | |
while (i < l) { | |
weakMapData = weakMapDataList[i++]; // [[WeakMapData]] internal slot | |
if (weakMapData[0] === this) { | |
if (Object(key) !== key) { // 5. If Type(key) is not Object, return false. | |
return false; | |
} | |
map = weakMapData[1]; | |
i = 0, | |
l = map.length; | |
while (i < l) { | |
if (map[i++][0] === key) { | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
throw new TypeError('Method WeakMap.prototype.has called on incompatible receiver ' + this); // 3. If thisArg does not have a [[WeakMapData]] internal slot, throw a TypeError exception. | |
} | |
}, | |
delete: { | |
writable: true, | |
enumerable: false, | |
configurable: true, | |
value: function delete_ (key) { // Note: If you specify the "delete" for SyntaxError occurs, it is replaced by "delete_" | |
if (Object(this) !== this) { // 2. If Type(thisArg) is not Object, throw a TypeError exception. | |
throw new TypeError('Method WeakMap.prototype.delete called on incompatible receiver ' + this); | |
} | |
var i = 0, | |
l = weakMapDataList.length, | |
weakMapData, map; | |
while (i < l) { | |
weakMapData = weakMapDataList[i++]; // [[WeakMapData]] internal slot | |
if (weakMapData[0] === this) { | |
if (Object(key) !== key) { // 5. If Type(key) is not Object, return false. | |
return false; | |
} | |
map = weakMapData[1]; | |
i = 0, | |
l = map.length; | |
while (i < l) { | |
if (map[i++][0] === key) { | |
weakMapData[1] = map.slice(0, i - 1).concat(map.slice(i)); | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
throw new TypeError('Method WeakMap.prototype.delete called on incompatible receiver ' + this); // 3. If thisArg does not have a [[WeakMapData]] internal slot, throw a TypeError exception. | |
} | |
} | |
}); | |
return WeakMap; | |
}(Object, Array.isArray)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ECMA-262 6th Edition