Live Note

Remain optimistic

validity 对象

通过 validity 对象,通过下面的 valid 可以查看验证是否通过,如果八种验证都通过返回 true,有一种失败则返回 false

  • oText.addEventListener(‘invalid’, fn, false);
  • ev.preventDefault()
  • valueMissing: 输入值为空时
  • typeMismatch: 控件值与预期类型不匹配
  • patterMismatch: 输入值不满足 pattern 正则
  • tooLong: 超过 maxLength 最大限制
  • rangeUnderflow: 验证的 range 最小值
  • rangeOverflow: 验证的 range 最大值
  • setMismatch: 验证 range 的当前值是否符合 min、max、step 的规则
  • customError: 不符合自定义验证–setCustomValidity()设置自定义验证
Read more »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<form action="">
<!--placeholder: 输入框提示信息-->
<!--autocomplete: 自动保存用户输入过的值,默认为on-->
<!--pattern: 正则验证-->
<input
type="text"
placeholder="请输入6-8个数字"
pattern="\d{6,8}"
name="user"
autocomplete="off"
id=""
/>
<!--formaction: 定义提交地址-->
<input type="submit" value="提交" formaction="http://www.baidu.com" />
</form>

<form action="">
<!--autofocus: 自动焦点-->
<!--required: 必填项-->
<input type="text" name="username" id="" autofocus required />
<input type="password" name="" id="" required />
</form>

<!--datalist选项列表,与input元素配合使用,定义input的可能值-->
<input type="text" list="varList" />
<datalist id="varList">
<option value="javascript">javascript</option>
<option value="html">html</option>
<option value="css">css</option>
</datalist>
Read more »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!--新的输入控件-->

<!--email: 电子邮箱文本框,当输入的不是邮箱的时候,验证通不过。移动端的键盘会有变化-->
<form action="">
<input type="email" name="" id="" />
<input type="submit" value="提交" />
</form>

<!--tel: 电话号码-->
<input type="tel" name="" id="" />
<!--url: 网页的url-->
<!--search: 搜索引擎,chrom下会多个关闭按钮-->
<!--number: 只能输入数字-->
<!--color: 颜色选择器-->
<!--datetime: 显示日期-->
<!--datetime-local: 显示完整日期,不含时区-->
<!--time: 显示时间,不含时区-->
<!--date: 显示日期-->
<!--week: 显示周-->
<!--month: 显示月-->

<!--特定范围内的数值选择器 max、min、step、value-->
<input type="range" step="2" min="0" max="10" value="2" name="" id="" />

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!--语义化标签-->
<header>页面的头部</header>
<hgroup>
<h1>Test</h1>
<h2>test</h2>
</hgroup>
<footer>页面的底部</footer>
<nav>
<a href="#">导航</a>
<a href="#">link1</a>
<a href="#">link2</a>
</nav>
<section>用来划分区域</section>
<article>用来在页面中表示一套结构完整且独立的内容部分(主题)</article>
<aside>和主题相关的附属信息</aside>

<figure>用于对元素进行组合,一般用于图片或视屏</figure>
<figure>
<img src="" alt="" />
<figcaption>Test</figcaption>
</figure>

<time>9:00</time>

<p>
明天
<time datatime="2018-02-14">情人节</time>
</p>

<!--用于描述文档或文档某个部分的细节-->
<details open>
<!--open时默认打开-->
<summary>test</summary>
<!--details元素的标题-->
<p>testjfkdsjkfsjd</p>
</details>

<!--定义一段对话-->
<dialog>
<dt>老师</dt>
<dd>2 + 3 ?</dd>
<dt>学生</dt>
<dd>5</dd>
</dialog>

<address>定义文章或页面作者的详细联系信息</address>

<mark>需要标记的词或句子</mark>

<!--keygen给表单添加一个公钥-->
<form action="http://www.baidu.com" method="get">
用户:
<input type="text" name="usr_name" /> 公钥:
<keygen name="security" />
<input type="submit" />
</form>

<!--定义进度条-->
<progress max="100" value="76">
<span>76</span>%
<!--为了兼容-->
</progress>

属性名表达式

JavaScript 定义属性有两种方法:

1
2
obj.foo = true
obj["a" + "bc"] = 123

ES6 允许字面量定义对象时使用第二种方法:

1
2
3
4
5
6
7
8
let propKey = "foo"
let obj = {
[propKey]: true,
["a" + "bc"]: 123,
["he" + "llo"]() {
return "hi"
},
}
Read more »

扩展运算符

1
2
3
4
5
6
7
8
9
10
11
console.log(...[1, 2, 3]) //1 2 3
console.log(1, ...[2, 3], 4) //1 2 3 4
;[...document.querySelectorAll("div")] //[<div>, <div>, ...];

function add(x, y) {
return x + y
}
add(...[1, 2]) //3

//与表达式一同使用
const arr = [...(x > 0 ? ["a"] : []), "b"]

扩展运算符的应用

  • 替代数组的 apply 方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function f(x, y, z) {}
    var args = [0, 1, 2]

    //ES5 写法
    f.apply(null, args)

    //ES6 写法
    f(...args)

    //用 Math.max 求数组中最大的数
    //ES5 写法
    Math.max.apply(null, [2, 33, 3])

    //ES6 写法
    Math.max(...[2, 33, 3])

    //用 push 将一个数组添加到另一个数组尾部
    var arr1 = [0, 1, 2]
    var arr2 = [3, 4, 5]

    //ES5 写法
    Array.prototype.push.apply(arr1, arr2)

    //ES6 写法
    arr1.push(...arr2)
  • 合并数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var arr1 = ["a"]
    var arr2 = ["b", "c"]
    var arr3 = ["d"]

    //ES5 写法
    arr1.concat(arr2, arr3)

    //ES6 写法
    ;[...arr1, ...arr2, ...arr3]
  • 与解构赋值结合

    Read more »

尾调用

Tail Call 是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数。

1
2
3
function f(x) {
return g(x)
}

尾调用不一定出现在函数尾部,只要是最后一步操作即可。

1
2
3
4
function f(x) {
if (x > 0) return t(x)
return m(x)
}

尾调用优化

函数调用会在内存中形成一个 call frame,保存调用位置和内部变量等信息。所有的 call frame 形成一个 call stack。
尾调用由于是函数的最后一步操作,所以不需要保留外层函数的 call frame,这就叫 Tail Call Optimization,即只保留内层函数的调用帧。

尾递归

递归非常耗内存,因为需要同时保存多个 call frame,很容易发生 stack overflow。但对于尾递归来说,由于只存在一个 call frame,所以不会发生溢出。

1
2
3
4
5
6
7
function Fibonacci(n) {
if (n <= 1) return 1
return Fibonacci(n - 1) + Fibonacci(n - 2)
}
console.log(Fibonacci(10)) //89
console.log(Fibonacci(100)) //overflow
console.log(Fibonacci(500)) //overflow
Read more »

函数的默认值

在 ES6 之前,不能直接为函数指定默认值,只能采用变通的方法:

1
2
3
4
5
6
7
8
function log(x, y) {
if (y === "undefined") {
y = "world"
}
console.log(x, y)
}
log("hello") //hello test
log("hello", "") //hello

ES6 允许为函数的参数设置默认值:

1
2
3
4
5
6
7
8
9
10
11
12
function log(x, y = "world") {
console.log(x, y)
}
log("hello") //hello world
log("hello", "") //hello

eg: function Point(x = 0, y = 0) {
this.x = x
this.y = y
}
let p = new Point()
console.log(p.x + " " + p.y) //0 0
Read more »

~运算符

位运算符是三步处理的过程:

  1. 把运算数转换成 32 位数字
  2. 把二进制数转换成它的二进制反码
  3. 把二进制数转换成浮点数
1
2
3
var iNum1 = 25 //25 等于 00000000000000000000000000011001
var iNum2 = ~iNum1 //转换为 11111111111111111111111111100110
alert(iNum2) //输出 "-26"

~~技巧

这是刷题时看见别人的代码里使用的东西,通常用来代替 Math.trunc()的方法。

1
2
3
4
5
6
//单个 ~
console.log(~1337) // -1338
//数字输入
console.log(~~47.11) //47
console.log(~~1.9999) //1
console.log(~~3) //3

当原始输入不确定时,~~可以将任何非数字类型转换成 0:

1
2
3
4
5
6
7
8
console.log(~~[]) //0
console.log(~~NaN) //0
console.log(~~null) //0

// | 0 也是相同的效果
console.log([] | 0) //0
console.log(NaN | 0) //0
console.log(null | 0) //0
Read more »

Math.trunc()

Math.trunc 用于除去一个数的小数部分。

1
2
3
4
5
6
7
8
9
10
11
Math.trunc(111.22) //111
Math.trunc("123.456") //123
//对空和无法截取整数的值,返回 NaN
Math.trunc(NaN) //NaN

//代码模拟
Math.trunc =
Math.trunc ||
function (x) {
return x < 0 ? Math.ceil(x) : Math.floor(x)
}
Read more »