github 上擁有2k+ star 的校驗插件validate.js

前言

前端技術井噴發展後,不知如今還有多少小夥伴跟我同樣,最開編寫javascirpt的目的僅是作表單驗證。從收藏正則表達式編寫if-else,渡過boorstrap與各類jquery的validate插件的時代,到如今各廠UI庫完整封裝的表單組件直接使用,每一次,數據校對的功能猶如業務的附屬品,換一個業務,寫一套校驗。在實際工做中,基礎開發的重複勞動佔比明顯。類與繼承的編程方式必定程度上規避了冗餘,但根本辦法是對功能進行更高一級的抽象化。前端

與其餘插件的區別:

  • 單一純粹

與moment.js只作date的相關功能同樣,validate.js只專一於對數據的校驗。且不須要任何的外部依賴。java

validate函數的參數:node

  1. attributes --被校驗的對象
  2. constraints --校驗規則,至關於其餘validate的rules
  3. options —(可選)配置擴展
  • 可拆分/集成校驗規則

約束具備如下格式:jquery

{ <attribute>:
    { <validator name>: <validator options> }
 }
複製代碼

約束規則支持傳參配置與自定義函數,很大程度上提升了複用。而在方式上,支持單值/嵌套等方式校驗也極大提升代碼可讀性。web

  • 自由的輸出格式

默認的校驗結果爲:正則表達式

  • 經過:undefined
  • 不經過:{'attribute':[ errorMessage ]}
經過自定義擴展,可支持boolean,object,array等各種型返回值,甚至拋出異常。
  • 提供豐富的校驗規則

支持對js基礎類型數據,bom內置對象,甚至dom/jquery對象。 這表明着validate.js不只能夠低成本的集成入各類舊項目中,甚至能夠一個約束同時支持業務邏輯,表單驗證,後端(若是是nodejs)傳參校驗。編程

validate的使用

  • 基礎函數使用

var constraints = {
  username: {
    presence: true,
    exclusion: {
      within: ["nicklas"],
      message: "'%{value}' is not allowed"
    }
  },
  password: {
    presence: true,
    length: {
      minimum: 6,
      message: "must be at least 6 characters"
    }
  }
};

validate({password: "bad"}, constraints);
// => {
//   "username": ["Username can't be blank"],
//   "password": ["Password must be at least 6 characters"]
// }

validate({username: "nick", password: "better"}, constraints);
// => undefined

validate({username: "nicklas", password: "better"}, constraints);
// => {"username": ["Username 'nicklas' is not allowed"]}

validate({password: "better"}, constraints, {fullMessages: false});
// => {"username": ["can't be blank"]}

validate({}, constraints, {format: "flat"});
// => ["Username can't be blank", "Password can't be blank"]

validate({username: "nicklas", password: "bad"}, constraints, {format: "detailed"});
// => [
//   {
//     "attribute": "username",
//     "value": "nicklas",
//     "validator": "exclusion",
//     "globalOptions": {
//       "format": "detailed"
//     },
//     "attributes": {
//       "username": "nicklas",
//       "password": "bad"
//     },
//     "options": {
//       "within": [
//         "nicklas"
//       ],
//       "message": "'%{value}' is not allowed"
//     },
//     "error": "Username 'nicklas' is not allowed"
//   },
//   {
//     "attribute": "password",
//     "value": "bad",
//     "validator": "length",
//     "globalOptions": {
//       "format": "detailed"
//     },
//     "attributes": {
//       "username": "nicklas",
//       "password": "bad"
//     },
//     "options": {
//       "minimum": 6,
//       "message": "must be at least 6 characters"
//     },
//     "error": "Password must be at least 6 characters"
//   }
// ]

validate({}, {username: {presence: {message: "^You must pick a username"}}});
// => {"username": ["You must pick a username"]}
複製代碼

attributes參數只能是正常js對象或element,不支持其餘如backbone的viewmodel。後端

若是attributes爲HTML/DOM/jQuery element,須要在函數執行前調用collectFormValues。api

fullMessages配置表示是否在異常信息中加入參數名與參數值。數組

若是須要在異常信息爲開頭則在message中加入^前綴,須要輸出^則編寫\^ 。

messeage中的%{value}將會先執行validate.stringifyValue再傳入(validate.prettify函數中的默認調用)。

validate.prettify函數可提供string格式化。具體見輔助函數部分。

  • 異步驗證Async validation

function success(attributes) {
  console.log("Success!", attributes);
}

function error(errors) {
  if (errors instanceof Error) {
    // This means an exception was thrown from a validator
    console.err("An error ocurred", errors);
  } else {
    console.log("Validation errors", errors);
  }
}

var constraints = {
  name: {
    presence: true
  },
  // This is so the country doesn't get removed when cleaning the attributes country: {} }; var attributes = { name: "Nicklas", country: "Sweden", someMaliciousAttribute: "scary value" }; // Will call the success function and log { // name: "Nicklas", // country: "Sweden" // } validate.async(attributes, constraints).then(success, error); // Will call the error function validate.async({}, constraints).then(success, error); function ValidationErrors(errors, options, attributes, constraints) { Error.captureStackTrace(this, this.constructor); this.errors = errors; this.options = options; this.attributes = attributes; this.constraints = constraints; } ValidationErrors.prototype = new Error(); // This isn't supported by the ES6 promises
validate.async({}, constraints, {wrapErrors: ValidationErrors})
  .then(success)
  .catch(ValidationErrors, function(error) {
    // Handle the validation errors
    console.log("ValidationErrors", error);
  })
  .catch(function(error) {
    // Handle other errors;
    console.log("SystemError", error);
  });

// Supporting another promise implementation (RSVP in this case)
validate.Promise = RSVP.Promise;
複製代碼

validate支持異步調用,在原先validate基礎上返回Promise。當環境/全局變量不支持Promise時,將拋出異常。

異步函數增長兩個option參數。1.cleanAttributes:當不爲false時,將在promise的resolve以前調用validate.cleanAttributes函數。2.wrapErrors :自定義方法捕捉異常。

任何符合A+規範的promise均可以經過重寫validate.Promise來實現promise。請勿使用jquery的promise,由於它並不是A+規範。

  • 單值驗證Single validation

validate.single(null, {presence: true, email: true});
// => ["can't be blank"]

validate.single("foo", {presence: true, email: true});
// => ["is not a valid email"]

validate.single("foo@bar.com", {presence: true, email: true});
// => undefined
複製代碼

針對基礎數據類型的校驗

  • 嵌套驗證Nested validation

var constraints = {
  "addresses.shipping": {
    presence: true
  },
  "addresses.shipping.street": {
    format: {
      // Must be numbers followed by a name
      pattern: "^[0-9]+ .+$",
      message: "^The street for the shipping address must be a valid street name"
    }
  }
};

validate({}, constraints);
// => {"addresses.shipping": ["Addresses shipping can't be blank"]}

validate({addresses: {shipping: {street: "Foobar"}}}, constraints);
// => {"addresses.shipping.street": ["The street for the shipping address must be a valid street name"]}

validate({"foo.bar": 3}, {"foo\\.bar": {numericality: {even: true}}});
// => {"foo\.bar": ["Foo bar must be even"]}
複製代碼
  • 默認選項Default options

var constraints = {
  name: {
    presence: true
  }
};

validate.options = {format: "flat"};
validate.async.options = {format: "flat", cleanAttributes: false};
validate.validators.presence.options = {message: "can't be empty"};

// The default options will be used for both the
// validator and the validate function
validate({}, constraints);
// => ["Name can't be empty"]

// The default options are not used if the constraints options are falsy
validate({format: "grouped"}, {});
// => undefined
複製代碼
  • 錯誤格式Error formatting

var constraints = {
  username: {
    presence: true,
    exclusion: {
      within: ["nicklas"],
      message: "'%{value}' is not allowed"
    }
  },
  password: {
    presence: true,
    length: {
      minimum: 6,
      message: "must be at least 6 characters"
    }
  }
};

validate({}, constraints, {format: "flat"});
// => ["Username can't be blank", "Password can't be blank"]

validate({username: "nicklas", password: "bad"}, constraints, {format: "detailed"});
// => [
//   {
//     "attribute": "username",
//     "value": "nicklas",
//     "validator": "exclusion",
//     "globalOptions": {
//       "format": "detailed"
//     },
//     "attributes": {
//       "username": "nicklas",
//       "password": "bad"
//     },
//     "options": {
//       "within": [
//         "nicklas"
//       ],
//       "message": "'%{value}' is not allowed"
//     },
//     "error": "Username 'nicklas' is not allowed"
//   },
//   {
//     "attribute": "password",
//     "value": "bad",
//     "validator": "length",
//     "globalOptions": {
//       "format": "detailed"
//     },
//     "attributes": {
//       "username": "nicklas",
//       "password": "bad"
//     },
//     "options": {
//       "minimum": 6,
//       "message": "must be at least 6 characters"
//     },
//     "error": "Password must be at least 6 characters"
//   }
// ]

validate.formatters.custom = function(errors) {
  return errors.map(function(error) {
    return error.validator;
  });
};

validate({username: "nicklas", password: "bad"}, constraints, {format: "custom"});
// => ["exclusion", "length"];
複製代碼

validate.js支持不一樣的錯誤返回格式

  • grouped:依屬性分組排列信息
  • flat:返回數組
  • detailed:返回對象

還能夠經過validate.formatters來自定義返回格式

自定義一個驗證器

validate.validators.custom = function(value, options, key, attributes) {
  console.log(value);
  console.log(options);
  console.log(key);
  console.log(attributes);
  return "is totally wrong";
};

// Will log:
//   - "some value"
//   - "some options"
//   - "foo"
//   - {"foo": "some value"}
validate({foo: "some value"}, {foo: {custom: "some options"}});
// => {foo: ["Foo is totally wrong"]}
複製代碼

編寫本身的驗證器很是簡單。只需將其添加到validate.validators對象中,它就會自動被拾取。

  • value - 值在屬性對象中的確切值。
  • options - 驗證器的選項。保證不是null或undefined。
  • key - 屬性名稱。
  • attributes - 整個屬性對象。
  • globalOptions - 調用時傳遞的選項 validate(將始終爲對象,非null)

返回null或undefined將視爲經過。返回字符串或字符串數數組爲錯誤信息。

不須要再錯誤信息中添加屬性名,函數會自動完成此功能。

自定義異步驗證器

validate.validators.myAsyncValidator = function(value) {
  return new validate.Promise(function(resolve, reject) {
    setTimeout(function() {
      if (value === "foo") resolve();
      else resolve("is not foo");
    }, 100);
  });
};

var constraints = {name: {myAsyncValidator: true}}
  , success = alert.bind(this, "The validations passed")
  , error = function(errors) {
      alert(JSON.stringify(errors, null, 2));
    };

// Will call the success callback
validate.async({name: "foo"}, constraints).then(success, error);

// Will call the error callback with {name: ["Name is not foo"]} as the first argument
validate.async({name: "bar"}, constraints).then(success, error);
複製代碼

與普通驗證器不一樣的是異步驗證器返回一個new validate.Promise,並經過resolve與reject來控制校驗是否經過。

內置驗證器

  • date與datetime

官方建議直接使用moment.js

// Before using it we must add the parse and format functions
// Here is a sample implementation using moment.js
validate.extend(validate.validators.datetime, {
  // The value is guaranteed not to be null or undefined but otherwise it
  // could be anything.
  parse: function(value, options) {
    return +moment.utc(value);
  },
  // Input is a unix timestamp
  format: function(value, options) {
    var format = options.dateOnly ? "YYYY-MM-DD" : "YYYY-MM-DD hh:mm:ss";
    return moment.utc(value).format(format);
  }
});

validate({}, {departure: {datetime: true}});
// => undefined

validate({departure: "foobar"}, {departure: {datetime: true}});
// => {"departure": ["Departure must be a valid date"]}

validate({departure: "2013-12-11 10:09:08"}, {departure: {datetime: true}});
// => undefined

validate({departure: "2013-12-11 10:09:08"}, {departure: {datetime: {dateOnly: true}}});
// => {"departure": ["Departure must be valid date"]}

var constraints = {
  birthday: {
    datetime: {
      dateOnly: true,
      latest: moment.utc().subtract(18, 'years'),
      message: "^You need to be at least 18 years old"
    }
  }
};

validate({birthday: "3013-11-14"}, constraints);
// => {"birthday": ["You need to be at least 18 years old"]}
複製代碼
  • email

var constraints = {
  from: {
    email: true
  }
};

validate({from: null}, constraints);
// => undefined

validate({from: ""}, constraints);
// => {"email": ["From is not a valid email"]}

validate({from: "nicklas@ansman"}, constraints);
// => {"email": ["From is not a valid email"]}

// Any TLD is allowed
validate({from: "nicklas@foo.faketld"}, constraints);
// => undefined

// Upper cased emails are allowed
validate({from: "NICKLAS@ANSMAN.SE"}, constraints);
// => undefined

constraints = {
  from: {
    email: {
      message: "doesn't look like a valid email"
    }
  }
};

validate({from: "foobar"}, constraints);
// => {"email": ["From doesn't look like a valid email"]}

// It allows unicode
validate({from: "first.läst@example.com"}, constraints);
// => undefined
複製代碼

因爲校驗email的規則可能很複雜,能夠經過設置validate.validators.email.PATTERN 自定義所的正則表達式匹配。

  • equality

var constraints = {
  confirmPassword: {
    equality: "password"
  }
};

validate({password: "foo", confirmPassword: "foo"}, constraints);
// => undefined

validate({password: "foo", confirmPassword: "bar"}, constraints);
// => {confirmPassword: ["Confirm password is not equal to password"]}

constraints = {
  complexAttribute: {
    equality: {
      attribute: "otherComplexAttribute",
      message: "is not complex enough",
      comparator: function(v1, v2) {
        return JSON.stringify(v1) === JSON.stringify(v2);
      }
    }
  }
};

validate({complexAttribute: [1,2,3], otherComplexAttribute: [1,2,3]}, constraints);
// => undefined

validate({complexAttribute: [1,2,3], otherComplexAttribute: [3,2,1]}, constraints);
// => {complexAttribute: ["Complex attribute is not complex enough"]}
複製代碼

默認經過 ===來判斷,也能夠自定義函數與其餘字段進行匹配,經過返回true、false校驗結果。

  • exclusion

var restrictedDomains = ["jp", "ch"];

validate({}, {subdomain: {exclusion: restrictedDomains}});
// => undefined

validate({subdomain: "jp"}, {subdomain: {exclusion: restrictedDomains}});
// => {"size": ["jp is restricted"]}

var constraints = {
  subdomain: {
    exclusion: {
      within: {jp: "Japan", "ch": "China"},
      message: "^We don't support %{value} right now, sorry"
    }
  }
};

validate({subdomain: "jp"}, constraints);
// => {"subdomain": ["We don't support Japan right now, sorry"]}

validate({subdomain: "com"}, constraints);
// => undefined
複製代碼
  • format

var pattern = /\d{5}(-\d{4})?/;

validate({}, {zipCode: {format: pattern}});
// => undefined

validate({zipCode: "foobar"}, {zipCode: {format: pattern}});
// => {"zipCode": ["Zip code is invalid"]};

validate({zipCode: "12345"}, {zipCode: {format: pattern}});
// => undefined

var constraints = {
  username: {
    format: {
      pattern: "[a-z0-9]+",
      flags: "i",
      message: "can only contain a-z and 0-9"
    }
  }
};

validate({username: "Nicklas!"}, constraints);
// => {"username": ["Username can only contain a-z and 0-9"]}

validate({username: "Nicklas"}, constraints);
// => undefined
複製代碼
  • inclusion

var sizes = ["small", "medium", "large"];

validate({}, {size: {inclusion: sizes}});
// => undefined

validate({size: "xlarge"}, {size: {inclusion: sizes}});
// => {"size": ["xlarge is not included in the list"]}

var constraints = {
  size: {
    inclusion: {
      within: {"Small": "s", "Medium": "m", "Large": "l"},
      message: "^We're currently out of %{value}"
    }
  }
};

validate({size: "Extra large"}, constraints);
// => {"size": ["We're currently out of Extra large"]}

validate({size: "Medium"}, constraints);
// => undefined
複製代碼
  • length

var constraints = {
  key1: {length: {is: 3}},
  key2: {length: {minimum: 20}},
  key3: {length: {maximum: 3}},
  key4: {
    length: {
      minimum: 3,
      tooShort: "needs to have %{count} words or more",
      tokenizer: function(value) {
        return value.split(/\s+/g);
      }
    }
  }
};

validate({}, constraints);
// => undefined
// This is because nil and undefined are valid values.
// Use the presence validator if you don't want to allow undefined values. var values = { key1: "wrong length", key2: "too short", key3: "too long", key4: "too short" }; validate(values, constraints); // => { // "key1": ["Key1 is the wrong length (should be 3 characters)"], // "key2": ["Key2 is too short (minimum is 20 characters)"], // "key3": ["Key3 is too long (maximum is 3 characters)"], // "key4": ["Key4 needs to have 3 words or more"] // } 複製代碼
  • numericality

// null and undefined are valid values regardless of the options
validate({}, {duration: {numericality: true}});
//= > undefined

validate({duration: "foobar"}, {duration: {numericality: true}});
// => {"duration": ["Duration is not a number"]}

validate({duration: "3"}, {duration: {numericality: true}});
// => undefined

validate({duration: "03"}, {duration: {numericality: true}});
// => undefined

validate({duration: "03"}, {duration: {numericality: {strict: true}}});
// => {"duration": ["Duration must be a valid number"]}

validate({duration: "3"}, {duration: {numericality: {noStrings: true}}});
// => {"duration": ["Duration is not a number"]}

validate({duration: "7"}, {duration: {numericality: {divisibleBy: 3}}});
// => {"duration": ["Duration must be divisible by 3"]}

var constraints = {
  duration: {
    numericality: {
      onlyInteger: true,
      greaterThan: 0,
      lessThanOrEqualTo: 30,
      even: true,
      notEven: "must be evenly divisible by two"
    }
  }
};

validate({duration: 3.14}, constraints);
// => {"duration": ["Duration must be an integer"]}

validate({duration: 4711}, constraints);
// => {
//   "duration": [
//     "Duration must be less than or equal to 30",
//     "Duration must be evenly divisible by two"
//   ]
// }
複製代碼

對於數字的校驗,若是value爲sting,默認經過+value轉換。也可經過noStrings:true來禁止轉換。

如下爲限制類型:

  • onlyInteger:只容許整數
  • strict:嚴格的字符換數字校驗,不容許0位開頭的string數字
  • greaterThan:大於
  • greaterThanOrEqualTo:大於等於
  • equalTo:等於
  • lessThanOrEqualTo:小於等於
  • lessThan:小於
  • divisibleBy:不等於
  • odd:奇數
  • even:偶數

相對應的錯誤消息配置:

  • notValid

  • notInteger

  • notGreaterThan

  • notGreaterThanOrEqualTo

  • notEqualTo

  • notLessThan

  • notLessThanOrEqualTo

  • notDivisibleBy

  • notOdd

  • notEven

  • presence

validate({}, {username: {presence: true}});
// => {"username": ["Username can't be blank"]}

validate({username: "ansman"}, {username: {presence: true}});
// => undefined

validate({input: ""}, {input: {presence: true}});
// => undefined

validate({input: ""}, {input: {presence: {allowEmpty: false}}});
// => {"input:" ["Input can't be blank"]}

validate({}, {username: {presence: {message: "is required"}}});
// => {"username": ["Username is required"]}

validate.validators.presence.message = "is required";
validate({}, {username: {presence: true}});
// => {"username": ["Username is required"]}
複製代碼

默認爲null與undefined,若allowEmpty:false,如下不經過:

  • {} (empty objects)

  • [] (empty arrays)

  • "" (empty string)

  • " " (whitespace only string)

  • type

validate({myAttribute: "value"}, {myAttribute: {type: "string"}});
// => undefined

validate({myAttribute: true}, {myAttribute: {type: "string"}});
// => {"myAttribute": ["My attribute must be of type string"]}

validate({myAttribute: "other"}, {myAttribute: {type: {type: function(value) { return value === "stuff"; }}}});
// => {"myAttribute": ["My attribute must be of the correct type"]}

validate.validators.type.types.customType = function (value) { return value === "stuff"; };
validate({myAttribute: true}, {myAttribute: {type: "customType"}});
// => {"myAttribute": ["My attribute must be of type customType"]}

validate.validators.type.messages.customType = "is simply wrong";
validate({myAttribute: true}, {myAttribute: {type: "customType"}});
// => {"myAttribute": ["My attribute is simply wrong"]}
複製代碼
  • url

validate({website: "http://google.com"}, {website: {url: true}});
// => undefined

validate({website: "google.com"}, {website: {url: true}});
// => {"website": ["Website is not a valid url"]}

validate({website: "ftp://google.com"}, {website: {url: true}});
// => {"website": ["Website is not a valid url"]}

validate({website: "ftp://google.com"}, {
  website: {
    url: {
      schemes: ["ftp"]
    }
  }
});
// => undefined

validate({website: "http://localhost"}, {website: {url: true}});
// => {"website": ["Website is not a valid url"]}

validate({website: "http://localhost"}, {
  website: {
    url: {
      allowLocal: true
    }
  }
});
// => undefined

validate({website: "data:,Hello%2C%20World!"}, {website: {url: true}});
// => {"website": ["Website is not a valid url"]}

validate({website: "data:,Hello%2C%20World!"}, {
    website: {
        url: {
            allowDataUrl: true
        }
      }
    }
);
// => undefined
複製代碼
  • schemes:默認只容許"http", "https",可匹配正則。
  • allowLocal :默認爲false,是否容許本地ip,如 10.0.1.1 或 localhost。
  • allowDataUrl :默認爲false,是否容許轉義符。

工具函數

  • capitalize

validate.capitalize("foobar");
// => "Foobar"
複製代碼
  • cleanAttributes

var whitelist = {
  name: true,
  "address.street": true,
  "address.postal": true,
  "something\\.with\\.periods": true
};

var attributes = {
  name: "Nicklas",
  address: {
    street: "Drottninggatan 98",
    postal: "111 60"
  },
  "something.with.periods": "some value",
  id: 4711,
  createdAt: "1970-01-01 00:00"
};

validate.cleanAttributes(attributes, whitelist);
// => {
//   name: "Nicklas",
//   address: {
//     street: "Drottninggatan 98",
//     postal: "111 60"
//   },
//   "something.with.periods": "some value"
// }

var constraints = {
  name: {
    presence: true
  },
  "address.street": {},
  "address.postal": {},
  "something\\.with\\.periods": {}
};

validate.cleanAttributes(attributes, constraints);
// => {
//   name: "Nicklas",
//   address: {
//     street: "Drottninggatan 98",
//     postal: "111 60"
//   },
//   "something.with.periods": "some value"
// }
複製代碼

返回白名單中的屬性的object

  • collectFormValues

<form id="login">
  <input type="text" name="username" value="ansman">
  <input type="password" name="password" value="correcthorsebatterystaple">
  <input type="checkbox" name="remember-me" checked>
  <input type="hidden" name="some-hidden-value" data-ignored>
</form>
<script>
var form = document.querySelector("form#login");
validate.collectFormValues(form);
// => {username: "ansman", password: "correcthorsebatterystaple", remember-me: false}
</script>
複製代碼

驗證fromData,配置:

  • nullify:空字符串爲null
  • trim:去先後空格

不須要驗證的element增長data-ignored便可。

  • contains

validate.contains({}, "foo");
// => false

validate.contains({foo: "bar"}, "foo");
// => true

validate.contains([1, 2, 3], 4);
// => false

validate.contains([1, 2, 3], 3);
// => true
複製代碼
  • extend

var o1 = {foo: "bar"}
  , o2 = {baz: "quux"};

validate.extend(o1, o2) === o1;
// => true

o1;
// => {foo: "bar", baz: "quux"};

o2;
// => {bar: "quux"};

// Makes a copy of o1, doesn't modify o1 validate.extend({}, o1); // => {foo: "bar", baz: "quux"}; // o1 is not touched validate.extend({}, o1) === o1; // => false 複製代碼
  • format

validate.format("Hi, my name is %{name}", {name: "Nicklas"});
// => "Hi, my name is Nicklas"

validate.format("%%{this} will not be replaced", {this: "that"});
// => "%{this} will not be replaced"
複製代碼

%{...}表明在屬性中的值,買message中用%%{...}來打印%{...}

  • getDeepObjectValue

validate.getDeepObjectValue({foo: "bar"}, "foo");
// => "bar"

validate.getDeepObjectValue({foo: {bar: {baz: "quux"}}}, "foo.bar.baz");
// => "quux"

validate.getDeepObjectValue({"foo.bar": "baz"}, "foo\\.bar");
// => "baz"
複製代碼
  • isArray

validate.isArray({});
// => false

validate.isArray([]);
// => true
複製代碼
  • isBoolean

validate.isBoolean("true");
// => false

validate.isBoolean(true);
// => true
複製代碼
  • isDate

validate.isDate(new Date());
// => true

validate.isDate(null);
// => false

validate.isDate({});
// => false
複製代碼
  • isDefined

validate.isDefined("foobar");
// => true

validate.isDefined(null);
// => false

validate.isDefined(undefined);
// => false
複製代碼
  • isDomElement

validate.isDomElement({});
// => false

validate.isDomElement(document.createElement("div"));
// => true
複製代碼
  • isEmpty

validate.isEmpty({});
// => true

validate.isEmpty(null);
// => true

validate.isEmpty("");
// => true

validate.isEmpty(" ");
// => true

validate.isEmpty("foo");
// => false

validate.isEmpty({foo: "bar"});
// => false
複製代碼
  • isFunction

validate.isFunction("foobar");
// => false

validate.isFunction(function() {});
// => true
複製代碼
  • isHash

validate.isHash([]);
// => false

validate.isHash({foo: "bar"});
// => true
複製代碼
  • isInteger

validate.isInteger("foobar");
// => false

validate.isInteger(3.14);
// => false

validate.isInteger(3);
// => true
複製代碼
  • isNumber

validate.isNumber("foobar");
// => false

validate.isNumber(3.14);
// => true
複製代碼
  • isObject

validate.isPromise({});
// => false

validate.isPromise(new Promise(function() {}));
// => true

validate.isPromise({then: function() {}});
// => true
複製代碼
  • isString

validate.isString("");
// => true

validate.isString({});
// => false
複製代碼
  • prettify

validate.prettify("This.is_a-weirdString\\.");
// => "this is a weird string."
複製代碼
  • 根據 .分割

  • 反斜槓轉義

  • _ 與 - 代替空格

  • 切割駝峯單詞

  • 全小寫

  • 數字轉字符串最多保留兩位小數

  • 對象 toString 轉string

  • 數組join(',')鏈接

  • result

// Not a function, returns the first argument
validate.result("foobar", 1, 2);
// => "foobar"

// Returns the result of Math.max(1, 2)
validate.result(Math.max, 1, 2);
// => 2

// Doesn't work since String#toUpperCase is not a pure function validate.result("foo".toUpperCase); // => Uncaught TypeError: String.prototype.toUpperCase called on null or undefined 複製代碼

validate.result(value, [arguments...])

相關文章
相關標籤/搜索