你不知道的JavaScript

短路运算的妙用:

||会把为真的值a赋给f,先看||左边的是否为真,再看||右边的是否为真

若是不输入性别,则||左边为假,右边为真,若输入性别,则先选择||左边的

1
2
3
4
<script>
let sex =prompt("请输入性别")||"保密"
console.log(sex);
</script>
1
2
3
let a = 6
b = 0
let f = a || b //6

&& 和 ||

&& 如果表达式1 结果为真 则返回表达式2 如果表达式1为假 那么返回表达式1

1
2
3
4
5
6
7
8
9
   console.log(123 && 456); // 456

console.log(0 && 456); // 0

console.log(0 && 1 + 2 && 456 * 56789); // 0

console.log('' && 1 + 2 && 456 * 56789); // ''

// 如果有空的或者否定的为假 其余是真的 0 '' null undefined NaN

|| 如果表达式1 结果为真 则返回的是表达式1 如果表达式1 结果为假 则返回表达式2

1
2
3
4
5
6
7
console.log(123 || 456); // 123

console.log(123 || 456 || 456 + 123); // 123

console.log(0 || 456 || 456 + 123); // 456

// 逻辑中断很重要 它会影响我们程序运行结果

for-in 与for-of使用方法操作

for...infor...of是两种不同的循环结构,用于遍历集合或数组中的元素

for...in循环:

  • 遍历对象的属性,而不是数组或集合的元素

  • 循环变量为对象的属性名称或键

  • 循环过程中会遍历所有可枚举的属性,包括继承自原型链的属性

  • 循环顺序是无序的,可能不按照属性的顺序进行遍历

    1
    2
    3
    4
    5
    let obj = { a: 1, b: 2, c: 3 };
    for (let prop in obj) {
    console.log(prop); // 输出:a, b, c
    }
    // 我们使用 for in 里面的变量 我们喜欢写 k 或者 key

for...of循环:

  • 用于遍历可迭代对象(如数组、字符串、Set、Map等)的元素。
  • 循环变量表示的是集合中的每个元素本身
  • 循环过程中只会遍历集合自身的元素,不会包括原型链上的属性或方法。
  • 循环顺序是有序的,按照集合元素的顺序进行遍历。
1
2
3
4
let arr = [1, 2, 3]; 
for (let element of arr) {
console.log(element); // 输出:1, 2, 3
}
  • for...in适用于遍历对象的属性。
  • for...of适用于遍历可迭代对象的元素。
  • for...in遍历属性,for...of遍历元素。

关于浮点数运算细节:

js浮点数运算精度问题:0.1+0.2≠0.3_js中浮点数0.1+0.2-CSDN博客

三元表达式

语法结构

1
2
    // 条件表达式 ? 表达式1 : 表达式2
//如果条件表达式结果为真 则 返回 表达式1 的值 如果条件表达式结果为假 则返回 表达式2 的值
1
2
3
var num = 10;

var result = num > 5 ? '是的' : '不是的'; // 我们知道表达式是有返回值的

switch分支语法结构

1
2
3
4
5
6
7
8
9
10
11
// switch (表达式) {
// case value1:
// 执行语句1;
// break;
// case value2:
// 执行语句2;
// break;
// ...
// default:
// 执行最后的语句;
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// switch注意事项
var num = 1;
switch (num) {
case 1:
console.log(1);

case 2:
console.log(2);

case 3:
console.log(3);
break;


}
// 1. 我们开发里面 表达式我们经常写成变量
// 2. 我们num 的值 和 case 里面的值相匹配的时候是全等===,必须是值和数据类型一致才可以 num === 1
// 3. break 如果当前的case里面没有break 则不会退出switch 是继续执行下一个case

break 退出整个循环

1
2
3
4
5
6
7
8
// break 退出整个循环
for (var i = 1; i <= 5; i++) {
if (i == 3) {
break;
}
console.log('我正在吃第' + i + '个包子');

}

函数返回值注意事项

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
// 函数返回值注意事项
// 1. return 终止函数
function getSum(num1, num2) {
return num1 + num2; // return 后面的代码不会被执行
alert('我是不会被执行的哦!')
}
console.log(getSum(1, 2));

// 2. return 只能返回一个值
function fn(num1, num2) {
return num1, num2; // 返回的结果是最后一个值
}
console.log(fn(1, 2));


// 3. 我们求任意两个数的 加减乘数结果
function getResult(num1, num2) {
return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
}
var re = getResult(1, 2); // 返回一个数组
console.log(re);


// 4. 我们的函数如果有return 则返回的是 return 后面的值,如果函数么有 return 则返回undefined
function fun1() {
return 666;
}
console.log(fun1()); // 666
function fun2() {

}
console.log(fun2()); // undefined

arguments 的使用

1
2
3
4
5
//只有函数才有 arguments对象  而且是每个函数都内置好了这个arguments
// 伪数组 并不是真正意义上的数组
// 1. 具有数组的 length 属性
// 2. 按照索引的方式进行存储的
// 3. 它没有真正数组的一些方法 pop() push() 等等

作用域链 :

1
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链  就近原则
1
2
3
4
5
6
7
8
9
10
11
12
var num = 10;

function fn() { // 外部函数
var num = 20;

function fun() { // 内部函数
console.log(num);

}
fun();
}
fn();//20

对象字面量创建对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// var obj = {};  // 创建了一个空的对象 
var obj = {
uname: '张三疯',
age: 18,
sex: '男',
sayHi: function() {
console.log('hi~');

}
}
// (1) 里面的属性或者方法我们采取键值对的形式 键 属性名 : 值 属性值
// (2) 多个属性或者方法中间用逗号隔开的
// (3) 方法冒号后面跟的是一个匿名函数

// 2. 使用对象
// (1). 调用对象的属性 我们采取 对象名.属性名
console.log(obj.uname);
// (2). 调用属性还有一种方法 对象名['属性名']
console.log(obj['age']);
// (3) 调用对象的方法 sayHi 对象名.方法名()
obj.sayHi();

console.log() 和console.dir()区别

1
2
3
console.log()可以取代alert()或document.write(),在网页脚本中使用console.log()时,会在浏览器控制台打印出信息。

console.dir()可以显示一个对象所有的属性和方法。

事件三要素

1
2
3
4
5
6
7
8
//  事件是有三部分组成  事件源  事件类型  事件处理程序   我们也称为事件三要素
//(1) 事件源 事件被触发的对象 谁 按钮
var btn = document.getElementById('btn');
//(2) 事件类型 如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
//(3) 事件处理程序 通过一个函数赋值的方式 完成
btn.onclick = function() {
alert('点秋香');
}

innerText 和 innerHTML的区别

1
2
3
4
5
6
7
8
9
// 1. innerText 不识别html标签 非标准  去除空格和换行
var div = document.querySelector('div');
// div.innerText = '<strong>今天是:</strong> 2019';
// 2. innerHTML 识别html标签 W3C标准 保留空格和换行的
div.innerHTML = '<strong>今天是:</strong> 2019';
// 这两个属性是可读写的 可以获取元素里面的内容
var p = document.querySelector('p');
console.log(p.innerText);
console.log(p.innerHTML);

焦点事件onfocus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 1.获取元素
var text = document.querySelector('input');
// 2.注册事件 获得焦点事件 onfocus
text.onfocus = function() {
// console.log('得到了焦点');
if (this.value === '手机') {
this.value = '';
}
// 获得焦点需要把文本框里面的文字颜色变黑
this.style.color = '#333';
}
// 3. 注册事件 失去焦点事件 onblur
text.onblur = function() {
// console.log('失去了焦点');
if (this.value === '') {
this.value = '手机';
}
// 失去焦点需要把文本框里面的文字颜色变浅色
this.style.color = '#999';
}

可参考的表格结构

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
<table>
<thead>
<tr>
<th>代码</th>
<th>名称</th>
<th>最新公布净值</th>
</tr>
</thead>
<tbody>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
</tr>
<tr>
<td>003526</td>
<td>农银金穗3个月定期开放债券</td>
<td>1.075</td>
</tr>
</tbody>
</table>

H5自定义属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var div = document.querySelector('div');
// console.log(div.getTime);
console.log(div.getAttribute('getTime'));
div.setAttribute('data-time', 20);
console.log(div.getAttribute('data-index'));
console.log(div.getAttribute('data-list-name'));
// h5新增的获取自定义属性的方法 它只能获取data-开头的
// dataset 是一个集合里面存放了所有以data开头的自定义属性
console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);
// 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
console.log(div.dataset.listName);
console.log(div.dataset['listName']);

子节点

1
2
3
4
5
6
7
8
9
// 1. firstChild 第一个子节点 不管是文本节点还是元素节点
console.log(ol.firstChild);
console.log(ol.lastChild);
// 2. firstElementChild 返回第一个子元素节点 ie9才支持
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
// 3. 实际开发的写法 既没有兼容性问题又返回第一个子元素
console.log(ol.children[0]);
console.log(ol.children[ol.children.length - 1]);

兄弟节点

1
2
3
4
5
6
7
var div = document.querySelector('div');
// 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等
console.log(div.nextSibling);
console.log(div.previousSibling);
// 2. nextElementSibling 得到下一个兄弟元素节点
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);

三种创建元素方式区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 三种创建元素方式区别 
// 1. document.write() 创建元素 如果页面文档流加载完毕,再调用这句话会导致页面重绘
// var btn = document.querySelector('button');
// btn.onclick = function() {
// document.write('<div>123</div>');
// }

// 2. innerHTML 创建元素
var inner = document.querySelector('.inner');
// for (var i = 0; i <= 100; i++) {
// inner.innerHTML += '<a href="#">百度</a>'
// }
var arr = [];
for (var i = 0; i <= 100; i++) {
arr.push('<a href="#">百度</a>');
}
inner.innerHTML = arr.join('');
// 3. document.createElement() 创建元素
var create = document.querySelector('.create');
for (var i = 0; i <= 100; i++) {
var a = document.createElement('a');
create.appendChild(a);
}

注册事件三种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var btns = document.querySelectorAll('button');
// 1. 传统方式注册事件
btns[0].onclick = function() {
alert('hi');
}
btns[0].onclick = function() {
alert('hao a u');
}
// 2. 事件侦听注册事件 addEventListener
// (1) 里面的事件类型是字符串 必定加引号 而且不带on
// (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function() {
alert(22);
})
btns[1].addEventListener('click', function() {
alert(33);
})
// 3. attachEvent ie9以前的版本支持
btns[2].attachEvent('onclick', function() {
alert(11);
})

事件委托

1
2
3
4
5
6
7
8
9
// 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// alert('知否知否,点我应有弹框在手!');
// e.target 这个可以得到我们点击的对象
e.target.style.backgroundColor = 'pink';


})

常见事件对象的属性和方法

  1. e.target 返回的是触发事件的对象(元素) , this 返回的是绑定事件的对象(元素)

    e.target 指向我们点击的那个对象谁触发了这个事件我们点击的是li ,那么e.target 指向的就是li

​ 给ul 绑定了事件 那么this 就指向ul

1
2
3
4
ul.addEventListener('click', function(e) {
// 我们给ul 绑定了事件 那么this 就指向ul
console.log(this);
}

currentTarget 事件属性

event.currentTarget 事件属性返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口

在捕获和起泡阶段,该属性是非常有用的,因为在这两个节点,它不同于event.target 属性。

阻止默认行为

让链接不跳转 或者让提交按钮不提交

1
2
3
4
var a = document.querySelector('a');
a.addEventListener('click', function(e) {
e.preventDefault(); // dom 标准写法
})

鼠标对象事件 MouseEvent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
document.addEventListener('click', function(e) {
// 1. client 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------------');

// 2. page 鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
console.log('---------------------');

// 3. screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);

})

键盘对象事件

  1. keyup 按键弹起的时候触发
  2. keydown 按键按下的时候触发 能识别功能键 比如 ctrl shift 左右箭头啊
  3. keypress 按键按下的时候触发 不能识别功能键 比如 ctrl shift 左右箭头啊

三个事件的执行顺序 keydown – keypress – keyup

焦点事件

1
2
3
4
5
6
7
8
9
10
    // 当我们失去焦点,就隐藏这个con盒子
jd_input.addEventListener('blur', function() {
con.style.display = 'none';
})
// 当我们获得焦点,就显示这个con盒子
jd_input.addEventListener('focus', function() {
if (this.value !== '') {
con.style.display = 'block';
}
})

window.onload

1
2
// load 等页面内容全部加载完毕,包含页面dom元素 图片 flash  css 等等
// DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比 load更快一些
1
2
3
4
5
6
7
8
9
// window.onload = function() {
// var btn = document.querySelector('button');
// btn.addEventListener('click', function() {
// alert('点击我');
// })
// }
// window.onload = function() {
// alert(22);
// }

清除定时器

1
2
3
4
5
6
7
8
9
10
11
12
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
var timer = null; // 全局变量 null是一个空对象
begin.addEventListener('click', function() {
timer = setInterval(function() {
console.log('ni hao ma');

}, 1000);
})
stop.addEventListener('click', function() {
clearInterval(timer);
})

this指向问题

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
// 1. 全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window)
console.log(this);

function fn() {
console.log(this);

}
window.fn();
window.setTimeout(function() {
console.log(this);

}, 1000);
// 2. 方法调用中谁调用this指向谁
var o = {
sayHi: function() {
console.log(this); // this指向的是 o 这个对象

}
}
o.sayHi();
var btn = document.querySelector('button');
// btn.onclick = function() {
// console.log(this); // this指向的是btn这个按钮对象

// }
btn.addEventListener('click', function() {
console.log(this); // this指向的是btn这个按钮对象

})
// 3. 构造函数中this指向构造函数的实例
function Fun() {
console.log(this); // this 指向的是fun 实例对象

}
var fun = new Fun();