foop
Version:
interfaces that describe their intentions.
71 lines (65 loc) • 4.03 kB
JavaScript
var isObj = require('./obj')
/**
* safari, ff, chrome/opera
* @type {Array<string>}
*/
var errorKeywords = ['circular', 'cyclic']
/**
* @desc check if a value is circular
*
* @memberOf is
* @since 5.0.0-beta.4
* @symb 🔘
*
* @param {Object | *} obj object to check if is circular
* @return {boolean} isCircular / hasCircular
*
* @TODO find the circular property...
* @NOTE is slow try catch json
* @NOTE if (isFunction(obj)) { throw new Error('cannot determine if function is circular')}
*
* @example
*
* const a = {};
* a.b = a;
* isCircular(a) //=> true
*
* const a = {};
* a.b = {
* c: a
* }
* isCircular(a) //=> true
*
* const a = {};
* a.b = {
* c: 4
* }
* isCircular(a) //=> false
*
* const a = [];
* a.push(a);
* isCircular(a) //=> true
*
* isCircular({}) //=> false
* isCircular('hi') //=> false
* isCircular(undefined) //=> false
*
*/
module.exports = function isCircular(obj) {
if (!isObj(obj)) { return false }
try {
JSON.stringify(obj)
}
catch (err) {
var index = errorKeywords.length
while (index--) {
if (err.message.includes(errorKeywords[index])) {
return true
}
}
// @NOTE should not do this
throw err
}
return false
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lyY3VsYXIuanMiLCJzb3VyY2VzIjpbImNpcmN1bGFyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGlzT2JqID0gcmVxdWlyZSgnLi9vYmonKVxuXG4vKipcbiAqIHNhZmFyaSwgZmYsIGNocm9tZS9vcGVyYVxuICogQHR5cGUge0FycmF5PHN0cmluZz59XG4gKi9cbmNvbnN0IGVycm9yS2V5d29yZHMgPSBbJ2NpcmN1bGFyJywgJ2N5Y2xpYyddXG5cbi8qKlxuICogQGRlc2MgY2hlY2sgaWYgYSB2YWx1ZSBpcyBjaXJjdWxhclxuICpcbiAqIEBtZW1iZXJPZiBpc1xuICogQHNpbmNlIDUuMC4wLWJldGEuNFxuICogQHN5bWIg8J+UmFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0IHwgKn0gb2JqIG9iamVjdCB0byBjaGVjayBpZiBpcyBjaXJjdWxhclxuICogQHJldHVybiB7Ym9vbGVhbn0gaXNDaXJjdWxhciAvIGhhc0NpcmN1bGFyXG4gKlxuICogQFRPRE8gZmluZCB0aGUgY2lyY3VsYXIgcHJvcGVydHkuLi5cbiAqIEBOT1RFIGlzIHNsb3cgdHJ5IGNhdGNoIGpzb25cbiAqIEBOT1RFIGlmIChpc0Z1bmN0aW9uKG9iaikpIHsgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgZGV0ZXJtaW5lIGlmIGZ1bmN0aW9uIGlzIGNpcmN1bGFyJyl9XG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgIGNvbnN0IGEgPSB7fTtcbiAqICAgYS5iID0gYTtcbiAqICAgaXNDaXJjdWxhcihhKSAvLz0+IHRydWVcbiAqXG4gKiAgIGNvbnN0IGEgPSB7fTtcbiAqICAgYS5iID0ge1xuICogICAgIGM6IGFcbiAqICAgfVxuICogICBpc0NpcmN1bGFyKGEpIC8vPT4gdHJ1ZVxuICpcbiAqICAgY29uc3QgYSA9IHt9O1xuICogICBhLmIgPSB7XG4gKiAgICAgYzogNFxuICogICB9XG4gKiAgIGlzQ2lyY3VsYXIoYSkgLy89PiBmYWxzZVxuICpcbiAqICAgY29uc3QgYSA9IFtdO1xuICogICBhLnB1c2goYSk7XG4gKiAgIGlzQ2lyY3VsYXIoYSkgLy89PiB0cnVlXG4gKlxuICogICBpc0NpcmN1bGFyKHt9KSAvLz0+IGZhbHNlXG4gKiAgIGlzQ2lyY3VsYXIoJ2hpJykgLy89PiBmYWxzZVxuICogICBpc0NpcmN1bGFyKHVuZGVmaW5lZCkgLy89PiBmYWxzZVxuICpcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0NpcmN1bGFyKG9iaikge1xuICBpZiAoIWlzT2JqKG9iaikpIHJldHVybiBmYWxzZVxuXG4gIHRyeSB7XG4gICAgSlNPTi5zdHJpbmdpZnkob2JqKVxuICB9XG4gIGNhdGNoIChlcnIpIHtcbiAgICBsZXQgaW5kZXggPSBlcnJvcktleXdvcmRzLmxlbmd0aFxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBpZiAoZXJyLm1lc3NhZ2UuaW5jbHVkZXMoZXJyb3JLZXl3b3Jkc1tpbmRleF0pKSB7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQE5PVEUgc2hvdWxkIG5vdCBkbyB0aGlzXG4gICAgdGhyb3cgZXJyXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cbiJdLCJuYW1lcyI6WyJjb25zdCIsImxldCJdLCJtYXBwaW5ncyI6IkFBQUFBLEdBQUssQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQzs7Ozs7O0FBTTlCQSxHQUFLLENBQUMsYUFBYSxHQUFHLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJDNUMsTUFBTSxDQUFDLE9BQU8sR0FBRyxTQUFTLFVBQVUsQ0FBQyxHQUFHLEVBQUU7RUFDeEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFBLE9BQU8sS0FBSyxFQUFBOztFQUU3QixJQUFJO0lBQ0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUM7R0FDcEI7RUFDRCxPQUFPLEdBQUcsRUFBRTtJQUNWQyxHQUFHLENBQUMsS0FBSyxHQUFHLGFBQWEsQ0FBQyxNQUFNO0lBQ2hDLE9BQU8sS0FBSyxFQUFFLEVBQUU7TUFDZCxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO1FBQzlDLE9BQU8sSUFBSTtPQUNaO0tBQ0Y7OztJQUdELE1BQU0sR0FBRztHQUNWOztFQUVELE9BQU8sS0FBSztDQUNiOyJ9