Skip to content

Commit

Permalink
UPDATE deepfreeze
Browse files Browse the repository at this point in the history
  • Loading branch information
serapath committed Sep 6, 2016
1 parent 88316a1 commit 324e83c
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 27 deletions.
46 changes: 34 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
# deepfreeze
recursively Object.freeze() on objects and functions including prototype chain
recursively Object.freeze() on objects and functions with properties

# usage
```js
var deepfreeze = require('deepfreeze')

;(function(){ "use strict"; deepFreeze(function(){}) })()
/* WILL NOT THROW => TypeError:
'caller', 'callee', and 'arguments' properties
may not be accessed on strict mode functions or
the arguments objects for calls to them
*/
/*******************************************************/
Person.prototype.say=function(){console.log('hi')}
Person.prototype.bye=function(){console.log('bye')}
function Person (name) {
return { __proto__: Person.prototype, name: name }
}
Barterer.prototype.__proto__ = Person.prototype
Barterer.prototype.clear=function(){this.inventory=[]}
function Barterer (name, inventory) {
var o = Person(name)
o.__proto__ = Barterer.prototype
o.inventory = inventory
return o
}
/*******************************************************/
var tom = new Barterer('tom', [{sugar:1},{salt:2}])

deepfreeze(tom)

tom.name = 'bill'
console.log(tom.name) // => 'tom'
tom.inventory = ['m3h']
console.log(tom.inventory) // [{sugar:1},{salt:2}]
tom.inventory.push({x:3}) // throws

deepfreeze(tom.__proto__)

tom.__proto__.clear=function (){ return 7}
tom.clear() // => 'clear'
tom.__proto__.say=function (){ return 6 }
tom.say() // => 'say'
tom.__proto__.bye=function (){ return 5 }
tom.bye() // => 'bye'

deepfreeze(Buffer)
Buffer.x = 5
console.log(Buffer.x === undefined)
Buffer.prototype.z = 3
console.log(Buffer.prototype.z === undefined)
```
17 changes: 6 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
var xObject = require('x-is-object')
var xFunction = require('x-is-function')
module.exports = deepfreeze
function deepfreeze (o) {
if (xObject(o)) {
if (!Object.isFrozen(o)) Object.freeze(o)
var isFN = xFunction(o)
deepFreeze(o.__proto__)
for (prop in o)
if (isFN && ({ caller: true, callee: true, arguments: true}[prop])) {}
else deepFreeze(o[prop])
module.exports = function deepfreeze (o) {
if (o===Object(o)) {
Object.isFrozen(o) || Object.freeze(o)
Object.getOwnPropertyNames(o).forEach(function (prop) {
prop==='constructor'||deepfreeze(o[prop])
})
}
return o
}
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "deepfreeze",
"version": "1.0.0",
"description": "recursively Object.freeze() on objects and functions including prototype chain",
"version": "2.0.0",
"description": "recursively Object.freeze() on objects and functions with properties",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "tape test.js"
},
"repository": {
"type": "git",
Expand All @@ -30,7 +30,9 @@
},
"homepage": "https://github.com/serapath/deepfreeze#readme",
"dependencies": {
"x-is-function": "^1.0.2",
"x-is-object": "^0.1.0"
},
"devDependencies": {
"tape": "^4.6.0"
}
}
50 changes: 50 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
var test = require('tape')

var deepfreeze = require('./')

test('deepfreeze', function (t) {
t.plan(6)

Person.prototype.say=function(){ return 'say'}
Person.prototype.bye=function(){ return 'bye' }
function Person (name) {
return { __proto__: Person.prototype, name: name }
}
Barterer.prototype.__proto__ = Person.prototype
Barterer.prototype.clear=function(){ return 'clear' }
function Barterer (name, inventory) {
var o = Person(name)
o.__proto__ = Barterer.prototype
o.inventory = inventory
return o
}
/*******************************************************/
var tom = Barterer('tom', [{sugar:1},{salt:2}])

deepfreeze(tom)

var x = tom.name
tom.name = 'bill'
t.equal(tom.name, x, 'name did not change')

x = tom.inventory
tom.inventory = ['m3h']
t.deepEqual(tom.inventory, x, 'inventory did not change')

try { tom.inventory.push({x:3}) }
catch (e) { t.ok(e, 'couldnt push to inventory') }

deepfreeze(tom.__proto__)
x = tom.clear()
tom.__proto__.clear=function (){console.log(7)}
t.equal(tom.clear(), x, 'clear() did not change')

x = tom.say()
tom.__proto__.say=function (){console.log(6)}
t.equal(tom.say(), x, 'say() did not change')

x = tom.bye()
tom.__proto__.bye=function (){console.log(5)}
t.equal(tom.bye(), x, 'bye() did not change')

})

0 comments on commit 324e83c

Please sign in to comment.