type-of-is
Advanced tools
Comparing version 2.0.0 to 3.0.0
111
example.js
@@ -1,42 +0,83 @@ | ||
var type = require('.'); | ||
var Type = require('./'); | ||
console.log(type.of('hi there ok')); // [Function: String] | ||
console.log(type.of(342)); // [Function: Number] | ||
console.log(type.of({})); // [Function: Object] | ||
console.log(type.of([1, 2, 3])); // [Function: Array] | ||
console.log(type.of(null)); // null | ||
console.log(type.of(undefined)); // undefined | ||
console.log(type.of(true)); // [Function: Boolean] | ||
console.log(type.of(function () {})); // [Function: Function] | ||
console.log(type.of(/abcd/)); // [Function: RegExp] | ||
console.log(type.of(new Date())); // [Function: Date] | ||
console.log(type.of(new Error())); // [Function: Error] | ||
// Type.of(arg) and Type(one_argument) return constructor of type | ||
console.log(Type.of('hi there ok')); // [Function: String] | ||
console.log(Type.of(342)); // [Function: Number] | ||
console.log(Type.of({})); // [Function: Object] | ||
console.log(Type.of([1, 2, 3])); // [Function: Array] | ||
console.log(Type.of(null)); // null | ||
console.log(Type.of(undefined)); // undefined | ||
console.log(Type(true)); // [Function: Boolean] | ||
console.log(Type(function () {})); // [Function: Function] | ||
console.log(Type(/abcd/)); // [Function: RegExp] | ||
console.log(Type(new Date())); // [Function: Date] | ||
console.log(Type(new Error())); // [Function: Error] | ||
console.log(type.ofs('hi there ok')); // "String" | ||
console.log(type.ofs(342)); // "Number" | ||
console.log(type.ofs({})); // "Object" | ||
console.log(type.ofs([1, 2, 3])); // "Array" | ||
console.log(type.ofs(null)); // "Null" | ||
console.log(type.ofs(undefined)); // "Undefined" | ||
console.log(type.ofs(true)); // "Boolean" | ||
console.log(type.ofs(function () {})); // "Function" | ||
console.log(type.ofs(/abcd/)); // "RegExp" | ||
console.log(type.ofs(new Date())); // "Date" | ||
console.log(type.ofs(new Error())); // "Error" | ||
// Type.string(arg) returns the string name of constructor | ||
console.log(Type.string('hi there ok')); // "String" | ||
console.log(Type.string(342)); // "Number" | ||
console.log(Type.string({})); // "Object" | ||
console.log(Type.string([1, 2, 3])); // "Array" | ||
console.log(Type.string(null)); // "Null" | ||
console.log(Type.string(undefined)); // "Undefined" | ||
console.log(Type.string(true)); // "Boolean" | ||
console.log(Type.string(function () {})); // "Function" | ||
console.log(Type.string(/abcd/)); // "RegExp" | ||
console.log(Type.string(new Date())); // "Date" | ||
console.log(Type.string(new Error())); // "Error" | ||
console.log(type.is(true, Boolean)); // true | ||
console.log(type.is("1231", Number)); // false | ||
console.log(type.is("1231", String)); // true | ||
console.log(type.is("1231", "String")); // true | ||
console.log(type.is("1231", Object)); // false | ||
console.log(type.is([], Object)); // false | ||
console.log(type.is({}, Object)); // true | ||
console.log(type.is([], Array)); // true | ||
console.log(type.is(new Date(), Date)); // true | ||
console.log(type.is(new Date(), Object)); // false | ||
// Type.is(object, type) and Type(object, type) tests object type | ||
console.log(Type.is(true, Boolean)); // true | ||
console.log(Type.is("1231", Number)); // false | ||
console.log(Type.is("1231", String)); // true | ||
console.log(Type.is("1231", "String")); // true | ||
console.log(Type.is("1231", Object)); // false | ||
console.log(Type([], Object)); // false | ||
console.log(Type({}, Object)); // true | ||
console.log(Type([], Array)); // true | ||
console.log(Type(new Date(), Date)); // true | ||
console.log(Type(new Date(), Object)); // false | ||
var s = "hihihi"; | ||
var Stringy = type.of(s); | ||
var Stringy = Type.of(s); | ||
var t = new Stringy("hihihi"); | ||
console.log((s == t)); // true | ||
console.log((s === t)); // false | ||
console.log((s === t)); // false | ||
// User defined objects should be instances of Objects but also can get actual constructor type | ||
function Person (name) { | ||
this.name = name; | ||
} | ||
Person.prototype.barf = function () { | ||
return this.name + " just barfed!"; | ||
}; | ||
var ralph = new Person('Ralph'); | ||
console.log(Type.of(ralph)); // [Function: Person] | ||
console.log(Type.is(ralph, Person)); // true | ||
console.log(Type.is(ralph, Object)); // false | ||
console.log(Type.instance(ralph, Person)); // true | ||
console.log(Type.instance(ralph, Object)); // true | ||
// arguments is weird edge case, there's no Arguments global but typeof arguments is "arguments" | ||
// type returned is Object, but not sure what would be preferable | ||
(function () { | ||
console.log(Type.of(arguments)); // [Function: Object] | ||
})(); | ||
// other built-ins | ||
console.log(Type.of(Infinity)); // [Function: Number] | ||
console.log(Type.of(-Infinity)); // [Function: Number] | ||
console.log(Type.of(NaN)); // [Function: Number] | ||
console.log(Type.of(Math)); // {} | ||
console.log(Type.of(JSON)); // {} | ||
// Returning constructor as type allows it to be used to create new objects i.e. | ||
var s = "s"; | ||
var t = new Type.of(s)("t"); | ||
console.log(t); // "t" |
62
index.js
@@ -1,6 +0,41 @@ | ||
function string(obj) { | ||
return {}.toString.call(obj).slice(1, -1).split(' ').pop(); | ||
} | ||
var isBuiltIn = (function () { | ||
var built_ins = [ | ||
Object, | ||
Function, | ||
Array, | ||
String, | ||
Boolean, | ||
Number, | ||
Date, | ||
RegExp, | ||
Error | ||
]; | ||
return function (_constructor) { | ||
return (built_ins.indexOf(_constructor) != -1); | ||
}; | ||
})(); | ||
function construct(obj) { | ||
var stringType = (function () { | ||
var _toString = ({}).toString; | ||
return function (obj) { | ||
// [object Blah] -> Blah | ||
var stype = _toString.call(obj).slice(8, -1); | ||
if ((obj === null) || (obj === undefined)) { | ||
return stype.toLowerCase(); | ||
} | ||
var ctype = of(obj); | ||
if (ctype && !isBuiltIn(ctype)) { | ||
return ctype.name; | ||
} else { | ||
return stype; | ||
} | ||
}; | ||
})(); | ||
function of (obj) { | ||
if ((obj === null) || (obj === undefined)) { | ||
@@ -13,10 +48,14 @@ return obj; | ||
function is(obj, type) { | ||
var typer = (construct(type) === String) ? string : construct | ||
return (typer(obj) === type); | ||
function is (obj, test) { | ||
var typer = (of(test) === String) ? stringType : of; | ||
return (typer(obj) === test); | ||
}; | ||
function instance (obj, test) { | ||
return (obj instanceof test); | ||
} | ||
module.exports = function (obj, type) { | ||
if (arguments.length == 1) { | ||
return construct(obj); | ||
return of(obj); | ||
} else { | ||
@@ -27,4 +66,5 @@ return is(obj, type); | ||
module.exports.string = string; | ||
module.exports.is = is; | ||
module.exports.of = construct; | ||
module.exports.instance = instance; | ||
module.exports.string = stringType; | ||
module.exports.of = of; | ||
module.exports.is = is; |
{ | ||
"name": "type-of-is", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "Determine and test types using constructor or {}.toString", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
182
README.md
# Description | ||
Determine and test types using constructor or Object.toString | ||
Sensible / unsurprising JavaScript type detection and comparison using a combination of ({}).toString and constructors. | ||
### Built in objects / primitives | ||
| obj | Type.of(obj) | Type.is(...) === true | | ||
| ------------------------- |:-------------:| ----------------------------- | | ||
| ```{ x : 2 }``` | Object | ```Type.is(obj, Object)``` | | ||
| ```function () {}``` | Function | ```Type.is(obj, Function)``` | | ||
| ```[1, 2, 3]``` | Array | ```Type.is(obj, Array)``` | | ||
| ```"barf"``` | String | ```Type.is(obj, String)``` | | ||
| ```true``` | Boolean | ```Type.is(obj, Boolean)``` | | ||
| ```10``` | Number | ```Type.is(obj, Number)``` | | ||
| ```new Date()``` | Date | ```Type.is(obj, Date)``` | | ||
| ```/abc/``` | RegExp | ```Type.is(obj, RegExp)``` | | ||
| ```new Error("barf!")``` | Error | ```Type.is(obj, Error)``` | | ||
### Objects created via new | ||
```javascript | ||
function Person (name) { | ||
this.name = name; | ||
} | ||
Person.prototype.barf = function () { | ||
return this.name + " just barfed!"; | ||
}; | ||
var ralph = new Person('Ralph'); | ||
Type.of(ralph); // [Function: Person] | ||
Type.is(ralph, Person); // true | ||
Type.is(ralph, Object); // false | ||
Type.instance(ralph, Person); // true | ||
Type.instance(ralph, Object); // true | ||
``` | ||
# Latest Version | ||
2.0.0 | ||
3.0.0 | ||
# Installation | ||
``` | ||
@@ -20,3 +58,3 @@ npm install type-of-is | ||
"dependencies": { | ||
"type-of-is": "2.0.0" | ||
"type-of-is": "3.0.0" | ||
} | ||
@@ -26,27 +64,39 @@ } | ||
# Usage | ||
``` | ||
```javascript | ||
var Type = require('type-of-is'); | ||
Type(obj) provides constructor type of an object | ||
Type.string(obj) provides type as String from {}.toString | ||
Type.is(obj, type) tests whether obj is of type (constructor or String) | ||
Type.of(obj); // returns constructor type of an object | ||
Type.string(obj); // provides type as String | ||
Type.is(obj, type); // tests whether obj is of type (constructor or String) | ||
Type.instance(obj, type); // wrapper of "obj instanceof type" | ||
// The top level Type export delegates to Type.of or Type.is based on argument count | ||
Type(obj) === Type.of(obj); | ||
Type(obj, type) === Type.is(obj, type); | ||
``` | ||
``` | ||
# More examples | ||
```javascript | ||
var Type = require('type-of-is'); | ||
console.log(Type('hi there ok')); // [Function: String] | ||
console.log(Type(342)); // [Function: Number] | ||
console.log(Type(342)); // [Function: Number] | ||
console.log(Type({})); // [Function: Object] | ||
console.log(Type([1, 2, 3])); // [Function: Array] | ||
console.log(Type(null)); // null | ||
console.log(Type(undefined)); // undefined | ||
console.log(Type(true)); // [Function: Boolean] | ||
console.log(Type(function () {})); // [Function: Function] | ||
console.log(Type(/abcd/)); // [Function: RegExp] | ||
console.log(Type(new Date())); // [Function: Date] | ||
console.log(Type(new Error())); // [Function: Error] | ||
// Type.of(arg) and Type(one_argument) return constructor of type | ||
console.log(Type.of('hi there ok')); // [Function: String] | ||
console.log(Type.of(342)); // [Function: Number] | ||
console.log(Type.of({})); // [Function: Object] | ||
console.log(Type.of([1, 2, 3])); // [Function: Array] | ||
console.log(Type.of(null)); // null | ||
console.log(Type.of(undefined)); // undefined | ||
console.log(Type(true)); // [Function: Boolean] | ||
console.log(Type(function () {})); // [Function: Function] | ||
console.log(Type(/abcd/)); // [Function: RegExp] | ||
console.log(Type(new Date())); // [Function: Date] | ||
console.log(Type(new Error())); // [Function: Error] | ||
// Type.string(arg) returns the string name of constructor | ||
console.log(Type.string('hi there ok')); // "String" | ||
@@ -64,2 +114,3 @@ console.log(Type.string(342)); // "Number" | ||
// Type.is(object, type) and Type(object, type) tests object type | ||
console.log(Type.is(true, Boolean)); // true | ||
@@ -70,10 +121,10 @@ console.log(Type.is("1231", Number)); // false | ||
console.log(Type.is("1231", Object)); // false | ||
console.log(Type.is([], Object)); // false | ||
console.log(Type.is({}, Object)); // true | ||
console.log(Type.is([], Array)); // true | ||
console.log(Type.is(new Date(), Date)); // true | ||
console.log(Type.is(new Date(), Object)); // false | ||
console.log(Type([], Object)); // false | ||
console.log(Type({}, Object)); // true | ||
console.log(Type([], Array)); // true | ||
console.log(Type(new Date(), Date)); // true | ||
console.log(Type(new Date(), Object)); // false | ||
var s = "hihihi"; | ||
var Stringy = Type(s); | ||
var Stringy = Type.of(s); | ||
var t = new Stringy("hihihi"); | ||
@@ -83,5 +134,84 @@ console.log((s == t)); // true | ||
// User defined objects should be instances of Objects but also can get actual constructor type | ||
function Person (name) { | ||
this.name = name; | ||
} | ||
Person.prototype.barf = function () { | ||
return this.name + " just barfed!"; | ||
}; | ||
var ralph = new Person('Ralph'); | ||
console.log(Type.of(ralph)); // [Function: Person] | ||
console.log(Type.is(ralph, Person)); // true | ||
console.log(Type.is(ralph, Object)); // false | ||
console.log(Type.instance(ralph, Person)); // true | ||
console.log(Type.instance(ralph, Object)); // true | ||
// arguments is weird edge case, there's no Arguments global but typeof arguments is "arguments" | ||
// type returned is Object, but not sure what would be preferable | ||
(function () { | ||
console.log(Type.of(arguments)); // [Function: Object] | ||
})(); | ||
// other built-ins | ||
console.log(Type.of(Infinity)); // [Function: Number] | ||
console.log(Type.of(-Infinity)); // [Function: Number] | ||
console.log(Type.of(NaN)); // [Function: Number] | ||
console.log(Type.of(Math)); // {} | ||
console.log(Type.of(JSON)); // {} | ||
// Returning constructor as type allows it to be used to create new objects i.e. | ||
var s = "s"; | ||
var t = new Type.of(s)("t"); | ||
console.log(t); // "t" | ||
// multi-frame dom | ||
var iFrame = document.createElement('IFRAME'); | ||
document.body.appendChild(iFrame); | ||
var IFrameArray = window.frames[0].Array; | ||
var array = new IFrameArray(); | ||
console.log(array instanceof Array); //false | ||
console.log(array instanceof IFrameArray); //true; | ||
console.log(Type.of(array)); // Array | ||
console.log(Type.is(array, Array)); // false | ||
console.log(Type.is(array, "Array")); // true | ||
``` | ||
# Rationale | ||
Try to iron over some of the surprises in JavaScript type detection | ||
1. typeof is unreliable / surprising in multiple cases (Array -> object, null -> object, etc.) | ||
2. constructor checking is unreliable in multi-frame dom environments | ||
3. type comparison using strings whose string case / formatting differs from constructor names introduces unnecessary complexity | ||
4. ({}).toString returns "[object Object]" for objects created via new rather than constructor name called with new | ||
# Links | ||
http://ecma262-5.com/ELS5_HTML.htm | ||
http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/ | ||
http://skilldrick.co.uk/2011/09/understanding-typeof-instanceof-and-constructor-in-javascript/ | ||
http://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/ | ||
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ | ||
#Build status | ||
[![build status](https://secure.travis-ci.org/stephenhandley/type-of-is.png)](http://travis-ci.org/stephenhandley/type-of-is) |
@@ -7,2 +7,9 @@ var Path = require('path'); | ||
function Person (name) { | ||
this.name = name; | ||
} | ||
Person.prototype.barf = function () { | ||
return this.name + " just barfed!"; | ||
} | ||
Asserts({ | ||
@@ -14,3 +21,3 @@ "Type, Type.of, and Type.string should properly find types": function () { | ||
[[], Array, "Array"], | ||
[null, null, "Null"], | ||
[null, null, "null"], | ||
[1, Number, "Number"], | ||
@@ -22,3 +29,4 @@ [true, Boolean, "Boolean"], | ||
[/blah|foo|bar/, RegExp, "RegExp"], | ||
[undefined, undefined, "Undefined"], | ||
[undefined, undefined, "undefined"], | ||
[new Person('ralph'), Person, "Person"] | ||
]; | ||
@@ -33,15 +41,16 @@ | ||
"Type and Type.is should properly check types": function () { | ||
"Type and Type.is should properly check built-in types": function () { | ||
var types = [ | ||
String, "String", | ||
Object, "Object", | ||
Array, "Array", | ||
null, "Null", | ||
Number, "Number", | ||
Boolean, "Boolean", | ||
Function, "Function", | ||
Date, "Date", | ||
Error, "Error", | ||
RegExp, "RegExp", | ||
undefined, "Undefined" | ||
String, | ||
Object, | ||
Array, | ||
null, | ||
Number, | ||
Boolean, | ||
Function, | ||
Date, | ||
Error, | ||
RegExp, | ||
undefined, | ||
Person | ||
]; | ||
@@ -52,43 +61,47 @@ | ||
["hi", "there", "1234"], // values | ||
[String, "String"], // expect true | ||
String, // expect true | ||
], | ||
[ | ||
[{}, {one: 1, two: 2}], | ||
[Object, "Object"] | ||
Object | ||
], | ||
[ | ||
[[], [1,2,3], ["string", 2, false]], | ||
[Array, "Array"] | ||
Array | ||
], | ||
[ | ||
[null], | ||
[null, "Null"] | ||
null | ||
], | ||
[ | ||
[1, 20324, 2342.425], | ||
[Number, "Number"] | ||
Number | ||
], | ||
[ | ||
[true, false], | ||
[Boolean, "Boolean"] | ||
Boolean | ||
], | ||
[ | ||
[{}.toString, function() { return 1 + 2; }], | ||
[Function, "Function"] | ||
Function | ||
], | ||
[ | ||
[new Date()], | ||
[Date, "Date"] | ||
Date | ||
], | ||
[ | ||
[new Error("oh no"), (function () { try { throw new Error("blah"); } catch (e) { return e; }})()], | ||
[Error, "Error"] | ||
Error | ||
], | ||
[ | ||
[/foo|bar/, /.*abc/], | ||
[RegExp, "RegExp"] | ||
RegExp | ||
], | ||
[ | ||
[undefined], | ||
[undefined, "Undefined"] | ||
undefined | ||
], | ||
[ | ||
[new Person('ralph'), new Person('joe')], | ||
Person | ||
] | ||
@@ -104,9 +117,8 @@ ]; | ||
group[0].forEach(function(obj) { | ||
group[1].forEach(function(true_type) { | ||
Assert(Type(obj, true_type), "testing " + obj + ' is ' + true_type); | ||
Assert(Type.is(obj, true_type), "testing " + obj + ' is ' + true_type); | ||
}); | ||
var true_type = group[1]; | ||
Assert(Type(obj, true_type), "testing " + obj + ' is ' + true_type); | ||
Assert(Type.is(obj, true_type), "testing " + obj + ' is ' + true_type); | ||
types.forEach(function(false_type) { | ||
if (group[1].indexOf(false_type) == -1) { | ||
if (group[1] !== false_type) { | ||
Assert.strictEqual(Type(obj, false_type), false, "testing " + obj + ' is ' + false_type); | ||
@@ -118,3 +130,10 @@ Assert.strictEqual(Type.is(obj, false_type), false, "testing " + obj + ' is ' + false_type); | ||
}); | ||
}, | ||
"Type.instance should work (this is stupid to test)": function () { | ||
var ralph = new Person('ralph'); | ||
Assert(Type.instance(ralph, Person)); | ||
Assert(Type.instance(ralph, Object)); | ||
Assert(!Type.instance(ralph, String)); | ||
} | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16714
246
213
1