Created
June 2, 2017 07:26
-
-
Save fanyer/5c2ddbe6b11ebd40827ecd793417de34 to your computer and use it in GitHub Desktop.
isObject
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
/* @flow */ | |
// these helpers produces better vm code in JS engines due to their | |
// explicitness and function inlining | |
export function isUndef (v: any): boolean %checks { | |
return v === undefined || v === null | |
} | |
export function isDef (v: any): boolean %checks { | |
return v !== undefined && v !== null | |
} | |
export function isTrue (v: any): boolean %checks { | |
return v === true | |
} | |
export function isFalse (v: any): boolean %checks { | |
return v === false | |
} | |
/** | |
* Check if value is primitive | |
*/ | |
export function isPrimitive (value: any): boolean %checks { | |
return typeof value === 'string' || typeof value === 'number' | |
} | |
/** | |
* Quick object check - this is primarily used to tell | |
* Objects from primitive values when we know the value | |
* is a JSON-compliant type. | |
*/ | |
export function isObject (obj: mixed): boolean %checks { | |
return obj !== null && typeof obj === 'object' | |
} | |
const _toString = Object.prototype.toString | |
/** | |
* Strict object type check. Only returns true | |
* for plain JavaScript objects. | |
*/ | |
export function isPlainObject (obj: any): boolean { | |
return _toString.call(obj) === '[object Object]' | |
} | |
export function isRegExp (v: any): boolean { | |
return _toString.call(v) === '[object RegExp]' | |
} | |
/** | |
* Convert a value to a string that is actually rendered. | |
*/ | |
export function toString (val: any): string { | |
return val == null | |
? '' | |
: typeof val === 'object' | |
? JSON.stringify(val, null, 2) | |
: String(val) | |
} | |
/** | |
* Convert a input value to a number for persistence. | |
* If the conversion fails, return original string. | |
*/ | |
export function toNumber (val: string): number | string { | |
const n = parseFloat(val) | |
return isNaN(n) ? val : n | |
} | |
/** | |
* Make a map and return a function for checking if a key | |
* is in that map. | |
*/ | |
export function makeMap ( | |
str: string, | |
expectsLowerCase?: boolean | |
): (key: string) => true | void { | |
const map = Object.create(null) | |
const list: Array<string> = str.split(',') | |
for (let i = 0; i < list.length; i++) { | |
map[list[i]] = true | |
} | |
return expectsLowerCase | |
? val => map[val.toLowerCase()] | |
: val => map[val] | |
} | |
/** | |
* Check if a tag is a built-in tag. | |
*/ | |
export const isBuiltInTag = makeMap('slot,component', true) | |
/** | |
* Remove an item from an array | |
*/ | |
export function remove (arr: Array<any>, item: any): Array<any> | void { | |
if (arr.length) { | |
const index = arr.indexOf(item) | |
if (index > -1) { | |
return arr.splice(index, 1) | |
} | |
} | |
} | |
/** | |
* Check whether the object has the property. | |
*/ | |
const hasOwnProperty = Object.prototype.hasOwnProperty | |
export function hasOwn (obj: Object | Array<*>, key: string): boolean { | |
return hasOwnProperty.call(obj, key) | |
} | |
/** | |
* Create a cached version of a pure function. | |
*/ | |
export function cached<F: Function> (fn: F): F { | |
const cache = Object.create(null) | |
return (function cachedFn (str: string) { | |
const hit = cache[str] | |
return hit || (cache[str] = fn(str)) | |
}: any) | |
} | |
/** | |
* Camelize a hyphen-delimited string. | |
*/ | |
const camelizeRE = /-(\w)/g | |
export const camelize = cached((str: string): string => { | |
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '') | |
}) | |
/** | |
* Capitalize a string. | |
*/ | |
export const capitalize = cached((str: string): string => { | |
return str.charAt(0).toUpperCase() + str.slice(1) | |
}) | |
/** | |
* Hyphenate a camelCase string. | |
*/ | |
const hyphenateRE = /([^-])([A-Z])/g | |
export const hyphenate = cached((str: string): string => { | |
return str | |
.replace(hyphenateRE, '$1-$2') | |
.replace(hyphenateRE, '$1-$2') | |
.toLowerCase() | |
}) | |
/** | |
* Simple bind, faster than native | |
*/ | |
export function bind (fn: Function, ctx: Object): Function { | |
function boundFn (a) { | |
const l: number = arguments.length | |
return l | |
? l > 1 | |
? fn.apply(ctx, arguments) | |
: fn.call(ctx, a) | |
: fn.call(ctx) | |
} | |
// record original fn length | |
boundFn._length = fn.length | |
return boundFn | |
} | |
/** | |
* Convert an Array-like object to a real Array. | |
*/ | |
export function toArray (list: any, start?: number): Array<any> { | |
start = start || 0 | |
let i = list.length - start | |
const ret: Array<any> = new Array(i) | |
while (i--) { | |
ret[i] = list[i + start] | |
} | |
return ret | |
} | |
/** | |
* Mix properties into target object. | |
*/ | |
export function extend (to: Object, _from: ?Object): Object { | |
for (const key in _from) { | |
to[key] = _from[key] | |
} | |
return to | |
} | |
/** | |
* Merge an Array of Objects into a single Object. | |
*/ | |
export function toObject (arr: Array<any>): Object { | |
const res = {} | |
for (let i = 0; i < arr.length; i++) { | |
if (arr[i]) { | |
extend(res, arr[i]) | |
} | |
} | |
return res | |
} | |
/** | |
* Perform no operation. | |
*/ | |
export function noop () {} | |
/** | |
* Always return false. | |
*/ | |
export const no = () => false | |
/** | |
* Return same value | |
*/ | |
export const identity = (_: any) => _ | |
/** | |
* Generate a static keys string from compiler modules. | |
*/ | |
export function genStaticKeys (modules: Array<ModuleOptions>): string { | |
return modules.reduce((keys, m) => { | |
return keys.concat(m.staticKeys || []) | |
}, []).join(',') | |
} | |
/** | |
* Check if two values are loosely equal - that is, | |
* if they are plain objects, do they have the same shape? | |
*/ | |
export function looseEqual (a: mixed, b: mixed): boolean { | |
const isObjectA = isObject(a) | |
const isObjectB = isObject(b) | |
if (isObjectA && isObjectB) { | |
try { | |
return JSON.stringify(a) === JSON.stringify(b) | |
} catch (e) { | |
// possible circular reference | |
return a === b | |
} | |
} else if (!isObjectA && !isObjectB) { | |
return String(a) === String(b) | |
} else { | |
return false | |
} | |
} | |
export function looseIndexOf (arr: Array<mixed>, val: mixed): number { | |
for (let i = 0; i < arr.length; i++) { | |
if (looseEqual(arr[i], val)) return i | |
} | |
return -1 | |
} | |
/** | |
* Ensure a function is called only once. | |
*/ | |
export function once (fn: Function): Function { | |
let called = false | |
return function () { | |
if (!called) { | |
called = true | |
fn.apply(this, arguments) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment