UNPKG

argencoders-notevil

Version:

Evaluate javascript like the built-in eval() method but safely

112 lines (95 loc) 2.64 kB
var names = ['Object', 'String', 'Boolean', 'Number', 'RegExp', 'Date', 'Array', 'Function'] var immutable = {string: 'String', boolean: 'Boolean', number: 'Number' } var primitives = names.map(getGlobal) var protos = primitives.map(getProto) var protoReplacements = {} module.exports = Primitives function Primitives(context){ if (this instanceof Primitives){ this.context = context for (var i=0;i<names.length;i++){ if (!this.context[names[i]]){ this.context[names[i]] = wrap(primitives[i]) } } } else { return new Primitives(context) } } Primitives.prototype.replace = function(value){ var primIndex = primitives.indexOf(value) var protoIndex = protos.indexOf(value) if (~primIndex){ var name = names[primIndex] return this.context[name] } else if (~protoIndex) { var name = names[protoIndex] return this.context[name].prototype } else { return value } } Primitives.prototype.getPropertyObject = function(object, property){ if (immutable[typeof object]){ return this.getPrototypeOf(object) } return object } Primitives.prototype.isPrimitive = function(value){ return !!~primitives.indexOf(value) || !!~protos.indexOf(value) } Primitives.prototype.getPrototypeOf = function(value){ if (value == null){ // handle null and undefined return value } var immutableType = immutable[typeof value] if (immutableType){ var proto = this.context[immutableType].prototype } else { var proto = Object.getPrototypeOf(value) } if (!proto || proto === Object.prototype){ return null } else { var replacement = this.replace(proto) if (replacement === value){ replacement = this.replace(Object.prototype) } return replacement } } Primitives.prototype.applyNew = function(func, args){ if (func.wrapped){ var prim = Object.getPrototypeOf(func) var instance = new (Function.prototype.bind.apply(prim, arguments)) setProto(instance, func.prototype) return instance } else { return new (Function.prototype.bind.apply(func, arguments)) } } function getProto(func){ return func.prototype } function getGlobal(str){ return global[str] } function setProto(obj, proto){ obj.__proto__ = proto } function wrap(prim){ var proto = Object.create(prim.prototype) var result = function() { if (this instanceof result){ prim.apply(this, arguments) } else { var instance = prim.apply(null, arguments) setProto(instance, proto) return instance } } setProto(result, prim) result.prototype = proto result.wrapped = true return result }