Struct и readonly: как избежать падения производительности

The height and width Attributes

The input and attributes specify the height and width of an element.


Tip: Always specify both the height and width attributes for images. If height and width are set, the space required for the image is reserved when the page is loaded. Without these attributes, the browser does not know the size of the image, and cannot reserve the appropriate space to it. The effect will be that the page layout will change during loading (while the images load).

Example

Define an image as the submit button, with height and width attributes:

<form>  <label for=»fname»>First name:</label>  <input type=»text» id=»fname» name=»fname»><br><br>  <label for=»lname»>Last name:</label>  <input type=»text» id=»lname» name=»lname»><br><br>  <input type=»image» src=»img_submit.gif» alt=»Submit» width=»48″ height=»48″> </form>

Ref ReadOnly dönüş örneğiRef readonly return example

Bir üzerinde değiştirici, döndürülen başvurunun değiştirilemeyeceğini gösterir.The modifier on a indicates that the returned reference can’t be modified. Aşağıdaki örnek, kaynağına bir başvuru döndürür.The following example returns a reference to the origin. Çağıranların kaynağı değiştiremeyeceğini belirtmek için değiştiricisini kullanır:It uses the modifier to indicate that callers can’t modify the origin:

Döndürülen türün bir olması gerekmez .The type returned doesn’t need to be a . Tarafından döndürülebilecek herhangi bir tür tarafından döndürülebilecek .Any type that can be returned by can be returned by .

Когда следует использовать переменную только для чтенияWhen to Use a ReadOnly Variable

Существуют ситуации, в которых нельзя использовать оператор Const для объявления и присваивания постоянного значения.There are situations in which you cannot use a Const Statement to declare and assign a constant value. Например, инструкция может не принять тип данных, который необходимо назначить, или не удастся вычислить значение во время компиляции с помощью константного выражения.For example, the statement might not accept the data type you want to assign, or you might not be able to compute the value at compile time with a constant expression. Возможно, вы даже не узнаете значение во время компиляции.You might not even know the value at compile time. В таких случаях можно использовать переменную для хранения постоянного значения.In these cases, you can use a variable to hold a constant value.

Важно!

Если тип данных переменной является ссылочным типом, например массивом или экземпляром класса, его члены можно изменить, даже если сама переменная имеет значение .If the data type of the variable is a reference type, such as an array or a class instance, its members can be changed even if the variable itself is . Это показано в следующем примере.The following example illustrates this.

При инициализации массив, на который указывает, содержит «x», «y» и «z».When initialized, the array pointed to by holds «x», «y», and «z». Так как переменная является , ее значение нельзя изменить после инициализации, то есть нельзя присвоить ему новый массив.Because the variable is , you cannot change its value once it is initialized; that is, you cannot assign a new array to it. Однако можно изменить значения одного или нескольких элементов массива.However, you can change the values of one or more of the array members. После вызова процедуры массив, на который указывает, содержит «x», «M» и «z».Following a call to the procedure , the array pointed to by holds «x», «M», and «z».

Обратите внимание, что это похоже на объявление параметра процедуры как ByVal, что не позволяет процедуре изменять сам аргумент вызова, но позволяет ему изменять его члены.Note that this is similar to declaring a procedure parameter to be ByVal, which prevents the procedure from changing the calling argument itself but allows it to change its members

HTML Tags

<!—><!DOCTYPE><a><abbr><acronym><address><applet><area><article><aside><audio><b><base><basefont><bdi><bdo><big><blockquote><body><br><button><canvas><caption><center><cite><code><col><colgroup><data><datalist><dd><del><details><dfn><dialog><dir><div><dl><dt><em><embed><fieldset><figcaption><figure><font><footer><form><frame><frameset><h1> — <h6><head><header><hr><html><i><iframe><img><input><ins><kbd><label><legend><li><link><main><map><mark><meta><meter><nav><noframes><noscript><object><ol><optgroup><option><output><p><param><picture><pre><progress><q><rp><rt><ruby><s><samp><script><section><select><small><source><span><strike><strong><style><sub><summary><sup><svg><table><tbody><td><template><textarea><tfoot><th><thead><time><title><tr><track><tt><u><ul><var><video>

ПримерExample

В следующем примере определяется свойство для даты найма сотрудника.The following example defines a property for the date on which an employee was hired. Класс сохраняет значение свойства внутри в виде переменной, и только код внутри класса может изменить это значение.The class stores the property value internally as a variable, and only code inside the class can change that value. Однако свойство имеет значение , а любой код, который может получить доступ к классу, может считать свойство.However, the property is , and any code that can access the class can read the property.

Модификатор можно использовать в следующих контекстах:The modifier can be used in these contexts:

  • Оператор DimDim Statement
  • Property StatementProperty Statement

Validation


elements of type have no automatic validation applied to them (since a basic text input needs to be capable of accepting any arbitrary string), but there are some client-side validation options available, which we’ll discuss below.

Note: HTML form validation is not a substitute for server-scripts that ensure the entered data is in the proper format. It’s far too easy for someone to make adjustments to the HTML that allow them to bypass the validation, or to remove it entirely. It’s also possible for someone to simply bypass your HTML entirely and submit the data directly to your server. If your server-side code fails to validate the data it receives, disaster could strike when improperly-formatted data (or data which is too large, is of the wrong type, and so forth) is entered into your database.

A note on styling

There are useful pseudo-classes available for styling form elements to help the user see when their values are valid or invalid. These are and . In this section, we’ll use the following CSS, which will place a check (tick) mark next to inputs containing valid values, and a cross (X) next to inputs containing invalid values.

div {
  margin-bottom: 10px;
  position: relative;
}

input + span {
  padding-right: 30px;
}

input:invalid+span:after {
  position: absolute; content: '';
  padding-left: 5px;
}

input:valid+span:after {
  position: absolute;
  content: '✓';
  padding-left: 5px;
}

The technique also requires a element to be placed after the form element, which acts as a holder for the icons. This was necessary because some input types on some browsers don’t display icons placed directly after them very well.

Making input required

You can use the attribute as an easy way of making entering a value required before form submission is allowed:

<form>
  <div>
    <label for="uname">Choose a username: </label>
    <input type="text" id="uname" name="name" required>
    <span class="validity"></span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
div { margin-bottom: 10px; position: relative; } input + span { padding-right: 30px; } input:invalid+span:after { position: absolute; content: ''; padding-left: 5px; } input:valid+span:after { position: absolute; content: '✓'; padding-left: 5px; }

This renders like so:

If you try to submit the form with no search term entered into it, the browser will show an error message.

Input value length

You can specify a minimum length (in characters) for the entered value using the attribute; similarly, use to set the maximum length of the entered value, in characters.

The example below requires that the entered value be 4–8 characters in length.

<form>
  <div>
    <label for="uname">Choose a username: </label>
    <input type="text" id="uname" name="name" required size="10"
           placeholder="Username"
           minlength="4" maxlength="8">
    <span class="validity"></span>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
div { margin-bottom: 10px; position: relative; } input + span { padding-right: 30px; } input:invalid+span:after { position: absolute; content: ''; padding-left: 5px; } input:valid+span:after { position: absolute; content: '✓'; padding-left: 5px; }

This renders like so:

If you try to submit the form with less than 4 characters, you’ll be given an appropriate error message (which differs between browsers). If you try to enter more than 8 characters, the browser won’t let you.

Note: If you specify a but do not specify , the input is considered valid, since the user is not required to specify a value.

Specifying a pattern

You can use the attribute to specify a regular expression that the inputted value must match in order to be considered valid (see for a simple crash course on using regular expressions to validate inputs).

The example below restricts the value to 4-8 characters and requires that it contain only lower-case letters.

<form>
  <div>
    <label for="uname">Choose a username: </label>
    <input type="text" id="uname" name="name" required size="45"
           pattern="{4,8}">
    <span class="validity"></span>
    <p>Usernames must be lowercase and 4-8 characters in length.</p>
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
div {
  margin-bottom: 10px;
  position: relative;
}

p {
  font-size: 80%;
  color: #999;
}

input + span {
  padding-right: 30px;
}

input:invalid+span:after {
  position: absolute;
  content: '';
  padding-left: 5px;
}

input:valid+span:after {
  position: absolute;
  content: '✓';
  padding-left: 5px;
}

This renders like so:

JavaScript

JS Array concat() constructor copyWithin() entries() every() fill() filter() find() findIndex() forEach() from() includes() indexOf() isArray() join() keys() length lastIndexOf() map() pop() prototype push() reduce() reduceRight() reverse() shift() slice() some() sort() splice() toString() unshift() valueOf()

JS Boolean constructor prototype toString() valueOf()

JS Classes constructor() extends static super

JS Date constructor getDate() getDay() getFullYear() getHours() getMilliseconds() getMinutes() getMonth() getSeconds() getTime() getTimezoneOffset() getUTCDate() getUTCDay() getUTCFullYear() getUTCHours() getUTCMilliseconds() getUTCMinutes() getUTCMonth() getUTCSeconds() now() parse() prototype setDate() setFullYear() setHours() setMilliseconds() setMinutes() setMonth() setSeconds() setTime() setUTCDate() setUTCFullYear() setUTCHours() setUTCMilliseconds() setUTCMinutes() setUTCMonth() setUTCSeconds() toDateString() toISOString() toJSON() toLocaleDateString() toLocaleTimeString() toLocaleString() toString() toTimeString() toUTCString() UTC() valueOf()

JS Error name message

JS Global decodeURI() decodeURIComponent() encodeURI() encodeURIComponent() escape() eval() Infinity isFinite() isNaN() NaN Number() parseFloat() parseInt() String() undefined unescape()

JS JSON parse() stringify()

JS Math abs() acos() acosh() asin() asinh() atan() atan2() atanh() cbrt() ceil() cos() cosh() E exp() floor() LN2 LN10 log() LOG2E LOG10E max() min() PI pow() random() round() sin() sqrt() SQRT1_2 SQRT2 tan() tanh() trunc()

JS Number constructor isFinite() isInteger() isNaN() isSafeInteger() MAX_VALUE MIN_VALUE NEGATIVE_INFINITY NaN POSITIVE_INFINITY prototype toExponential() toFixed() toLocaleString() toPrecision() toString() valueOf()

JS OperatorsJS RegExp constructor compile() exec() g global i ignoreCase lastIndex m multiline n+ n* n? n{X} n{X,Y} n{X,} n$ ^n ?=n ?!n source test() toString() (x|y) . \w \W \d \D \s \S \b \B \0 \n \f \r \t \v \xxx \xdd \uxxxx

JS Statements break class continue debugger do…while for for…in for…of function if…else return switch throw try…catch var while

JS String charAt() charCodeAt() concat() constructor endsWith() fromCharCode() includes() indexOf() lastIndexOf() length localeCompare() match() prototype repeat() replace() search() slice() split() startsWith() substr() substring() toLocaleLowerCase() toLocaleUpperCase() toLowerCase() toString() toUpperCase() trim() valueOf()

CSS Reference

CSS ReferenceCSS Browser SupportCSS SelectorsCSS FunctionsCSS Reference AuralCSS Web Safe FontsCSS AnimatableCSS UnitsCSS PX-EM ConverterCSS ColorsCSS Color ValuesCSS Default ValuesCSS Entities

CSS Properties

align-content align-items align-self all animation animation-delay animation-direction animation-duration animation-fill-mode animation-iteration-count animation-name animation-play-state animation-timing-function

backface-visibility background background-attachment background-blend-mode background-clip background-color background-image background-origin background-position background-repeat background-size border border-bottom border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width border-collapse border-color border-image border-image-outset border-image-repeat border-image-slice border-image-source border-image-width border-left border-left-color border-left-style border-left-width border-radius border-right border-right-color border-right-style border-right-width border-spacing border-style border-top border-top-color border-top-left-radius border-top-right-radius border-top-style border-top-width border-width bottom box-decoration-break box-shadow box-sizing break-after break-before break-inside

caption-side caret-color @charset clear clip clip-path color column-count column-fill column-gap column-rule column-rule-color column-rule-style column-rule-width column-span column-width columns content counter-increment counter-reset cursor

direction display empty-cells filter flex flex-basis flex-direction flex-flow flex-grow flex-shrink flex-wrap float font @font-face font-family font-feature-settings font-kerning font-size font-size-adjust font-stretch font-style font-variant font-variant-caps font-weight

grid grid-area grid-auto-columns grid-auto-flow grid-auto-rows grid-column grid-column-end grid-column-gap grid-column-start grid-gap grid-row grid-row-end grid-row-gap grid-row-start grid-template grid-template-areas grid-template-columns grid-template-rows

hanging-punctuation height hyphens @import isolation justify-content @keyframes left letter-spacing

line-height list-style list-style-image list-style-position list-style-type

margin margin-bottom margin-left margin-right margin-top max-height max-width @media min-height min-width mix-blend-mode

object-fit object-position opacity order outline outline-color outline-offset outline-style outline-width overflow overflow-x overflow-y

padding padding-bottom padding-left padding-right padding-top page-break-after page-break-before page-break-inside perspective perspective-origin pointer-events position quotes

resize right

scroll-behavior

tab-size table-layout text-align text-align-last text-decoration text-decoration-color text-decoration-line text-decoration-style text-indent text-justify text-overflow text-shadow text-transform top

transform transform-origin transform-style transition transition-delay transition-duration transition-property transition-timing-function

unicode-bidi user-select

vertical-align visibility

white-space width word-break word-spacing word-wrap writing-mode

z-index

JavaScript

JS Array concat() constructor copyWithin() entries() every() fill() filter() find() findIndex() forEach() from() includes() indexOf() isArray() join() keys() length lastIndexOf() map() pop() prototype push() reduce() reduceRight() reverse() shift() slice() some() sort() splice() toString() unshift() valueOf()

JS Boolean constructor prototype toString() valueOf()

JS Classes constructor() extends static super

JS Date constructor getDate() getDay() getFullYear() getHours() getMilliseconds() getMinutes() getMonth() getSeconds() getTime() getTimezoneOffset() getUTCDate() getUTCDay() getUTCFullYear() getUTCHours() getUTCMilliseconds() getUTCMinutes() getUTCMonth() getUTCSeconds() now() parse() prototype setDate() setFullYear() setHours() setMilliseconds() setMinutes() setMonth() setSeconds() setTime() setUTCDate() setUTCFullYear() setUTCHours() setUTCMilliseconds() setUTCMinutes() setUTCMonth() setUTCSeconds() toDateString() toISOString() toJSON() toLocaleDateString() toLocaleTimeString() toLocaleString() toString() toTimeString() toUTCString() UTC() valueOf()

JS Error name message

JS Global decodeURI() decodeURIComponent() encodeURI() encodeURIComponent() escape() eval() Infinity isFinite() isNaN() NaN Number() parseFloat() parseInt() String() undefined unescape()

JS JSON parse() stringify()

JS Math abs() acos() acosh() asin() asinh() atan() atan2() atanh() cbrt() ceil() cos() cosh() E exp() floor() LN2 LN10 log() LOG2E LOG10E max() min() PI pow() random() round() sin() sqrt() SQRT1_2 SQRT2 tan() tanh() trunc()

JS Number constructor isFinite() isInteger() isNaN() isSafeInteger() MAX_VALUE MIN_VALUE NEGATIVE_INFINITY NaN POSITIVE_INFINITY prototype toExponential() toFixed() toLocaleString() toPrecision() toString() valueOf()

JS OperatorsJS RegExp constructor compile() exec() g global i ignoreCase lastIndex m multiline n+ n* n? n{X} n{X,Y} n{X,} n$ ^n ?=n ?!n source test() toString() (x|y) . \w \W \d \D \s \S \b \B \0 \n \f \r \t \v \xxx \xdd \uxxxx

JS Statements break class continue debugger do…while for for…in for…of function if…else return switch throw try…catch var while

JS String charAt() charCodeAt() concat() constructor endsWith() fromCharCode() includes() indexOf() lastIndexOf() length localeCompare() match() prototype repeat() replace() search() slice() split() startsWith() substr() substring() toLocaleLowerCase() toLocaleUpperCase() toLowerCase() toString() toUpperCase() trim() valueOf()

ПравилаRules

  • Контекст объявления.Declaration Context. можно использовать только на уровне модуля.You can use only at module level. Это означает, что контекст объявления для элемента должен быть классом, структурой или модулем и не может быть исходным файлом, пространством имен или процедурой.This means the declaration context for a element must be a class, structure, or module, and cannot be a source file, namespace, or procedure.

  • Комбинированные модификаторы.Combined Modifiers. Нельзя указывать вместе с в одном объявлении.You cannot specify together with in the same declaration.


  • Присвоение значения.Assigning a Value. Код, использующий свойство, не может задать его значение.Code consuming a property cannot set its value. Но код, имеющий доступ к базовому хранилищу, может назначить или изменить значение в любое время.But code that has access to the underlying storage can assign or change the value at any time.

    Значение переменной можно присвоить только в ее объявлении или в конструкторе класса или структуры, в которой он определен.You can assign a value to a variable only in its declaration or in the constructor of a class or structure in which it is defined.

HTML Теги

<!—><!DOCTYPE><a><abbr><acronym><address><applet><area><article><aside><audio><b><base><basefont><bdi><bdo><big><blockquote><body><br><button><canvas><caption><center><cite><code><col><colgroup><data><datalist><dd><del><details><dfn><dialog><dir><div><dl><dt><em><embed><fieldset><figcaption><figure><font><footer><form><frame><frameset><h1> — <h6><head><header><hr><html><i><iframe><img><input><ins><kbd><label><legend><li><link><main><map><mark><menu><menuitem><meta><meter><nav><noframes><noscript><object><ol><optgroup><option><output><p><param><picture><pre><progress><q><rp><rt><ruby><s><samp><script><section><select><small><source><span><strike><strong><style><sub><summary><sup><svg><table><tbody><td><template><textarea><tfoot><th><thead><time><title><tr><track><tt><u><ul><var><video>

Examples

A common use-case scenario

<!-- A common form that includes input tags -->
<form action="getform.php" method="get">
    First name: <input type="text" name="first_name" /><br />
     Last name: <input type="text" name="last_name" /><br />
        E-mail: <input type="email" name="user_email" /><br />
<input type="submit" value="Submit" />
</form>

Using mozactionhint on Firefox mobile

You can use the attribute to specify the text for the label of the enter key on the virtual keyboard when your form is rendered on Firefox mobile. For example, to have a «Next» label, you can do this:

<input type="text" mozactionhint="next" name="sometext" />

The result is:

HTML Reference

HTML by AlphabetHTML by CategoryHTML Browser SupportHTML AttributesHTML Global AttributesHTML EventsHTML ColorsHTML CanvasHTML Audio/VideoHTML Character SetsHTML DoctypesHTML URL EncodeHTML Language CodesHTML Country CodesHTTP MessagesHTTP MethodsPX to EM ConverterKeyboard Shortcuts

HTML Tags

<!—> <!DOCTYPE> <a> <abbr> <acronym> <address> <applet> <area> <article> <aside> <audio> <b> <base> <basefont> <bdi> <bdo> <big> <blockquote> <body> <br> <button> <canvas> <caption> <center> <cite> <code> <col> <colgroup> <data> <datalist> <dd> <del> <details> <dfn> <dialog> <dir> <div> <dl> <dt> <em> <embed> <fieldset> <figcaption> <figure> <font> <footer> <form> <frame> <frameset> <h1> — <h6> <head> <header> <hr> <html> <i> <iframe> <img> <input> <ins> <kbd> <label> <legend> <li> <link> <main> <map> <mark> <meta> <meter> <nav> <noframes> <noscript> <object> <ol> <optgroup> <option> <output> <p> <param> <picture> <pre> <progress> <q> <rp> <rt> <ruby> <s> <samp> <script> <section> <select> <small> <source> <span> <strike> <strong> <style> <sub> <summary> <sup> <svg> <table> <tbody> <td> <template> <textarea> <tfoot> <th> <thead> <time> <title> <tr> <track> <tt> <u> <ul> <var> <video> <wbr>

JavaScript

JS Array concat() constructor copyWithin() entries() every() fill() filter() find() findIndex() forEach() from() includes() indexOf() isArray() join() keys() length lastIndexOf() map() pop() prototype push() reduce() reduceRight() reverse() shift() slice() some() sort() splice() toString() unshift() valueOf()

JS Boolean constructor prototype toString() valueOf()

JS Classes constructor() extends static super

JS Date constructor getDate() getDay() getFullYear() getHours() getMilliseconds() getMinutes() getMonth() getSeconds() getTime() getTimezoneOffset() getUTCDate() getUTCDay() getUTCFullYear() getUTCHours() getUTCMilliseconds() getUTCMinutes() getUTCMonth() getUTCSeconds() now() parse() prototype setDate() setFullYear() setHours() setMilliseconds() setMinutes() setMonth() setSeconds() setTime() setUTCDate() setUTCFullYear() setUTCHours() setUTCMilliseconds() setUTCMinutes() setUTCMonth() setUTCSeconds() toDateString() toISOString() toJSON() toLocaleDateString() toLocaleTimeString() toLocaleString() toString() toTimeString() toUTCString() UTC() valueOf()

JS Error name message

JS Global decodeURI() decodeURIComponent() encodeURI() encodeURIComponent() escape() eval() Infinity isFinite() isNaN() NaN Number() parseFloat() parseInt() String() undefined unescape()

JS JSON parse() stringify()

JS Math abs() acos() acosh() asin() asinh() atan() atan2() atanh() cbrt() ceil() cos() cosh() E exp() floor() LN2 LN10 log() LOG2E LOG10E max() min() PI pow() random() round() sin() sqrt() SQRT1_2 SQRT2 tan() tanh() trunc()

JS Number constructor isFinite() isInteger() isNaN() isSafeInteger() MAX_VALUE MIN_VALUE NEGATIVE_INFINITY NaN POSITIVE_INFINITY prototype toExponential() toFixed() toLocaleString() toPrecision() toString() valueOf()

JS OperatorsJS RegExp constructor compile() exec() g global i ignoreCase lastIndex m multiline n+ n* n? n{X} n{X,Y} n{X,} n$ ^n ?=n ?!n source test() toString() (x|y) . \w \W \d \D \s \S \b \B \0 \n \f \r \t \v \xxx \xdd \uxxxx

JS Statements break class continue debugger do…while for for…in for…of function if…else return switch throw try…catch var while

JS String charAt() charCodeAt() concat() constructor endsWith() fromCharCode() includes() indexOf() lastIndexOf() length localeCompare() match() prototype repeat() replace() search() slice() split() startsWith() substr() substring() toLocaleLowerCase() toLocaleUpperCase() toLowerCase() toString() toUpperCase() trim() valueOf()

HTML Reference

HTML by AlphabetHTML by CategoryHTML Browser SupportHTML AttributesHTML Global AttributesHTML EventsHTML ColorsHTML CanvasHTML Audio/VideoHTML Character SetsHTML DoctypesHTML URL EncodeHTML Language CodesHTML Country CodesHTTP MessagesHTTP MethodsPX to EM ConverterKeyboard Shortcuts

HTML Tags

<!—> <!DOCTYPE> <a> <abbr> <acronym> <address> <applet> <area> <article> <aside> <audio> <b> <base> <basefont> <bdi> <bdo> <big> <blockquote> <body> <br> <button> <canvas> <caption> <center> <cite> <code> <col> <colgroup> <data> <datalist> <dd> <del> <details> <dfn> <dialog> <dir> <div> <dl> <dt> <em> <embed> <fieldset> <figcaption> <figure> <font> <footer> <form> <frame> <frameset> <h1> — <h6> <head> <header> <hr> <html> <i> <iframe> <img> <input> <ins> <kbd> <label> <legend> <li> <link> <main> <map> <mark> <meta> <meter> <nav> <noframes> <noscript> <object> <ol> <optgroup> <option> <output> <p> <param> <picture> <pre> <progress> <q> <rp> <rt> <ruby> <s> <samp> <script> <section> <select> <small> <source> <span> <strike> <strong> <style> <sub> <summary> <sup> <svg> <table> <tbody> <td> <template> <textarea> <tfoot> <th> <thead> <time> <title> <tr> <track> <tt> <u> <ul> <var> <video> <wbr>

The step Attribute

The input attribute specifies the legal number intervals for an input field.

Example: if step=»3″, legal numbers could be -3, 0, 3, 6, etc.

Tip: This attribute can be used together with the max and min attributes to create a range of legal values.

The attribute works with the following input types: number, range, date, datetime-local, month, time and week.

Example

An input field with a specified legal number intervals:

<form>  <label for=»points»>Points:</label>  <input type=»number» id=»points» name=»points» step=»3″></form>

Note: Input restrictions are not foolproof, and JavaScript provides many ways to add illegal input. To safely restrict input, it must also be checked by the receiver (the server)!


С этим читают