1. 基础调试代码
1.1 控制台打印
可以一次性输出多个值:
console.log(要输出的内容);
console.log(fun,10,100);
输出一个对象或者一个值的详细信息:
console.dir(要详细输出的内容);
console.dir(fun);
1.2 弹窗
1. alert(); 是在浏览器窗口中弹出一个提示框,提示框中输出指定的信息。
var obj={name:"lili"};
alert(obj);
2.confirm(); 是在浏览器窗口中弹出一个选择框,给用户提供了确定和取消两种选择。
var res=confirm("你准备好了吗?");
console.log(res);
3. prompt(); 是在浏览器窗口中弹出一个带输入框的提示框,如果点击的是确定,返回的就是你输入的内容,如果点击是取消是null。
var res2=prompt("你是男孩还是女孩?");
console.log(res2);
1.3 页面输出
document.write("哈哈")
2. 堆(heap)栈(stack)内存
浏览器加载页面,运行代码的时候。每打开一个页面,就会从计算机的内存条中分配出两块内存:堆内存(heap)和栈内存(stack)。
-
堆内存(heap):主要存放引用数据类型的值,对象存储的就是键值对,如果是函数,把整个函数当成字符串进行存储。
-
栈内存(stack):给代码提供可执行的环境;存储基本数据类型的值。
思考题:
var a=12;
var b=a;
console.log(b);//12
var obj1={"name":"lili","age":12};
var obj2=obj1;
obj2.age=18;
console.log(obj1.age);//18
3. 代码自上往下执行 (之前还有一个变量提升阶段,会在后面的课程中进行讲解)
基本数据类型:存在栈内存中, 按值操作。
引用数据类型的值比较复杂,存在堆内存中,按引用地址的操作。
4. 赋值操作的三步曲:
-
先创建值。
-
再创建变量。
-
最后把创建的变量和值关联在一起。
练习题:
var a={
n:12
}
var b=a;
b={
n:13
}
console.log(a.n); //12
------------------------
var obj={
n:10,
b:obj.n*10
}
console.log(obj.b);//报错,因为obj还没有创建出来是无法访问他的属性的
3. 在JS中用来检测数据类型的四种方式
-
typeof
-
instanceof
-
constructor
-
Object.prototype.toString.call()
4. typeof 运算符详解
typeof 首先返回的是一个字符串,它返回的类型。
-
'number'
-
'string'
-
'boolean'
-
'undefined'
-
'object'
-
'function'
特点:
-
typeof null 的结果是 "object"(这个是浏览器的BUG:所有的值在计算中都已二进制编码存储浏览器中把前三位是000的当做对象,而null的二进制前三位就是000,所以被识别为对象。
-
typeof 普通对象/数组对象/正则对象... 结果都是"object",这样就无法基于typeof区分是普通对象还是数组对象等了。
-
两个以上的typeof 结果都是“string”。
typeof 12 ===> "number"
typeof "zhufeng" ====> 'string'
typeof false ===>'boolean'
typeof true ====> 'boolean'
typeof null ====> 'object'
typeof undefined ====>'undefined'
typeof [1,2] =====>"object"
typeof function(){} ===>"function"
typeof [] =====>"object"
typeof typeof [] ====> 'string'
typeof typeof typeof typeof typeof [] ====> 'string'
5.条件语句(实现分支结构)
5.1 单向分支 if
if (表达式) {
code...
}
5.2 双向分支 if...else
if (表达式) {
code...
} else {
code...
}
5.3 多向分支 if... else if
if (表达式) {
code...
} else if (表达式) {
code...
} else if (表达式) {
code...
} else {
code...
}
5.4 多向分支 switch...case
一个变量在不同值情况下的不同操作,我们可以改写为 switch case 判断。(他只能应用于等于什么值做什么事情,不能用户大于或者小于啥值做啥)。
switch (值) {
case 可能的值: code....; break;
//=>每一种情况结束都要设置break(以供当此条件成立并处理完事情后,通知代码不在向下执行)
case 可能的值: code....; break;
//每一种case情况都是基于 === 进行比较的(严格比较,需要保证数据类型的一致)
case 可能的值: code....; break;
case 可能的值: code....; break;
default: code....; //=>等价于else,而且最后一个判断结束无需设置break
}
var num = 6;
switch (num) {
case 5:
num++;
break;
case 6:
num--;
// break;
case 7:
num--
// break;
default:
num = 0;
}
console.log(num);
注意!!!
如果忘记写break,无论你是否满足case的要求,都会往下执行一直到遇到breake或者default结束。
5.5 分支结构嵌套
if (表达式) {
if (表达式) {
code....
}
code ...
} else {
code...
}
6. 循环语句(实现循环结构)
6.1 while 循环
while (循环条件) {
code...
}
6.2 do...while循环
do {
code...
} while (循环条件)
6.3 for 循环
for (循环变量; 循环条件; 循环变量变化) {
code ...
}
//循环输出 0-10
for (var i = 0; i <= 10; i ++) {
console.log(i)
}
6.4 跳转语句
-
break语句结束整个循环。
-
continue语句结束当前循环。
-
return语句返回函数值(后面看)。
for(var i=0;i<10;i++){
if(i<5){
i++;//
continue;
}
if(i>7){
i+=2;
break;
}
i+=1;
}
console.log(i);//10
-------------------------------
for(var i=1;i<=10;i+=2){
if(i<=5){
i++;//
continue;
}else{
i-=2;
break;
}
i--;
console.log(i);
}
console.log(i);//5
-------------------------------
for (var i = 0; i < 10; i++) {
console.log(i);
break;
}
console.log(i);//0
6.5 i++和++i的理解
++在前,正常运算。
++在后,先赋值,后+1。
var i = 5;
var b=i++;
console.log(b);//5
<script>
var a = 15, //16 17
b = 25,//24 23 22 21
c = 10,//9 8 7 6
d = 6;//7 8
// 15 25 9 7 24 8
var resultA = a++ + b-- + --c + ++d + b-- + --c; //88
// 16 23 7 8 22 6
var resultB = a++ + b-- + --c + ++d + b-- + --c; //82
document.write(resultA)
document.write(`<br>`)
document.write(resultB)
</script>
6.6 三元运算
语法:条件表达式 ? 条件成立执行的语句 :条件不成立执行的语句
var num=5
if(num>=5){
num++
}else{
num--
}
改写成三元运算符
num>=5?num++:num--
特殊情况:条件成立,我想做一件事情,不成立我什么都不做,可以用 undefined / null /void 0来做占位符。
var num=5;
num>=5?num++:undefinde;
num>=5?num++:null;
num>=5?num++:void 0;
多条语句:如果条件成立之后,想同时执行多条语句,我们可以用“小括号”把执行语句包起来,并且语句与语句之间用“逗号”进行分割。
var num=5;
var a=3;
num>=5?(num++,a--):null;
练习:
<script>
var num = 12;
let num2 = num > 0 ? (num < 10 ? num++ : num--) : (num == 0 ? (num++, num / 10) : null)
document.write(num2);
</script>
7. 条件判断里面的相互转换规则
7.1 ==和===
-
==先将不同的类型转换成相同的类型,在进行比较,如果值相等,就相等。
-
===值和数据类型相等才相等。
注意特殊的!!!!
对象和对象比较看引用地址 。
对象和字符串,先将对象转为字符串,再比较。
console.log(""== 0);//""--->0 ==> true
console.log(null == undefined);//true
console.log(arr == arr2);//false
console.log(arr == arr3);//true
console.log(arr2 == arr3);//false
console.log([] == "");//true []---""
console.log({} == "");//false {}--"[object object]"
console.log([10] == “10");//true [10]---"10"
console.log([10,20] == “10 20");//false [10,20]---"10,20"
7.2 ==和!=,===和!==
-
对象==数字类型的时候,都先转换为数字,再比较。
-
对象==字符串类型的时候,把对象转换为字符串,再进行比较。
-
对象==布尔数据类型的时候,都先转换为数字,在比较。
-
数字==字符串,都先转换数字类型,再比较。
-
数字==布尔,都先转换为数字类型,再比较。
-
字符串==布尔,都先转换为数字类型,再比较。
总结:对于不同的数据类型转换规律:
1)对象和字符串比较的时候,是对象先转为字符串然后再进行比较。
2)除了第一种,不同数据类型比较都是先转换为number数字,再进行比较。
特殊情况总结:
null == undefined true
nul l=== undefined false
null 和 undefined 和其它值永远不相等。
NaN 和其它值永不相等。
// 1 == 1
console.log(1 == true);//true
// 1 == 0
console.log(1 == false);//false
// 2 == 1
console.log(2 == true);//false
// 0 == 1
console.log([] == true);//false
// !真 == 真 同类型的比较
console.log(![] == true);//false
//同类型的比较,数组地址不一样
console.log([] == []);//false
console.log(1 != true);//false
console.log(null !== undefined);//true
8. 与或非运算符
1. &&(与):全为真,才为真。在使用与运算时,先将&&两侧的内容隐式转换为布尔值,然后根据下面的公式返回对应布尔值的这个值。返回值并不是布尔值,返回对应的值。
- true && true = true :返回第二个true对应的结果。
- true && false = false
- false && true = false
- false && false = false :返回第一个false对应的结果。
2. ||(或):全为假,才为假。返回值并不是布尔值,返回对应的值。
- true || true = true:返回第一个true对应的结果。
- true || false = true
- false || true = true
- false || false = false :返回第二个false对应的结果。
// 逻辑短路
var a = 10,
b = 20,
c = 30;
if(--a > 5 || ++b > 20 || c-- > 20){
console.log("通过")
}else{
console.log("不通过")
}
console.log(a,b,c);
答案:通过,a=9,b=20,c=30
--------------------------------------
var a = 10,
b = 20,
c = 30;
if(--a > 5 && ++b < 20 && c-- > 20){
console.log("通过")
}else{
console.log("不通过")
}
console.log(a,b,c);
答案:不通过,,a=9,b=21,c=30
---------------------------------------
console.log(1 && 0);//0
console.log(1 && 2);//2
console.log("" && 0);//""
---------------------------------------
console.log(1 || 0);//1
console.log(1 || 2);//1
console.log("" || 0);//0
9. 位运算符
9.1 位运算运算规则
位运算 :运算二进制的数据。所有的位运算 不支持2的30次幂以上的结果运算。
1. & (位与) 运算的规则:把十进制的数转化为二进制的数据在进行计算,把计算的结果转为十进制返回。
- 1&1 = 1
- 1&0 = 0
- 0&1 = 0
- 0&0 = 0
例如:console.log(5 & 6);
5转为二进制是 101
&
6转为二进制是 110
结果: 100 转为十进制是4
2. | (位或)运算的规则::把十进制的数转化为二进制的数据在进行计算,把计算的结果转为十进制返回。
- 1|1 = 1
- 0|1 = 1
- 1|0 = 1
- 0|0 = 0
例如:console.log(5 | 6);
5转为二进制是 101
|
6转为二进制是 110
结果: 111 转为十进制是7
3. ^ (异或)运算的规则:相同为false(0),不同为true(1)。
- 1^1 = 0
- 1^0 = 1
- 0^1 = 1
- 0^0 = 0
例如:console.log(5 | 6);
5转为二进制是 101
^
6转为二进制是 110
结果: 011 转为十进制是3
^ (异或)运算的使用场景:
1. 对称加密 :原始数据^加密Key得到加密结果。加密的结果^加密Key得到原始数据。
// 原始数据^加密Key得到加密结果
console.log(4267^1234);//5241
// 加密的结果^加密Key得到原始数据
console.log(5241^1234);//4267
4.~ (位非)运算的规则:+1取负。 当非数值使用位非时,将非数值转换为0,然后做位非;位非遇到小数时,不做小数运算,直接去除小数;连续使用两次位非将会回到原值。
注意!!!
~~两个位非是取整。
例如:
console.log(~3); //-4
console.log(~-1); //0
// 当非数值时,在使用位非时,将非数值转换为0,然后做位非
console.log(~"a");//-1
// 位非遇到小数时,不做小数运算,直接去除小数
console.log(~1.2);//-2
// 连续使用两次位非将会回到原值
console.log(~~1);//1
// 取整
console.log(~~1.23);//1
console.log(~~32.467);//32
console.log(~~"a");//0
console.log(~~true);//1
console.log(~~{ a: 1 });//0
console.log(~~[1]);//1
9.2 编码集的分类
- ASCII
- GB2312:国标码。
- Big5 :繁体汉字编码表。
- Unicode编码表:万国码分为 UTF-8和UTF-16。
charCodeAt(索引下标) : 将指定的索引下标的字符转换成字符集对应的数值。
var str = "abc";
console.log(str.charCodeAt(0));//97
console.log(str.charCodeAt(1));//98
console.log(str.charCodeAt(2));//99
将数字转换为字符的方法:
- var 变量名 = new ArrayBuffer(指定数组长度) ;
- var 变量名= new Uint8Array(数组); :正整型8位数组。服务器进行解密,将正整数转换为对应的字符串。
- var 变量名= new Uint16Array(数组); :正整型16位数组。服务器进行解密,将正整数转换为对应的字符串。汉字使用 Unit16Array。
var str = "abc";
var arr = new Uint8Array(str.split("").map(item => item.charCodeAt(0) ^ 123))
console.log(arr);
10. 移位运算
任何数字需要先转换为二进制再做左移右移。
- << 左移位 :左移位就是后面补0,移动几位就补几个零。例如把5转为二进制就是101,5<<2(101<<2)表示5向左移2位,结果为10100,转为十进制为20。
- >> 右位移 : 右移位就是删除后面的位数。移动几位就删除几位数。例如把8转为二进制就是1000,8>>2(1000>>2)表示5向右移2位,结果为10,转为十进制为2。
- <<< 无符号左移位
- >>> 无符号右移位
11. 相关知识铺垫
11.1 元素包含的常用属性
-
className: 存储的是字符串,代表当前元素的类名。
-
id: 存储的是字符串,代表当前元素的id名。
-
innerHTML:存储当前元素的所有内容,包含标签。
-
innerText:存储当前元素的文本内容。
-
style:存贮当前元素的所有行内样式。
-
onclick:点击事件属性。
-
onmouseover:鼠标滑过事件。
-
onmouseout:鼠标离开事件。
11.2 通过id 获取一个元素
通过id 获取一个元素:document.getElementById("id名字")
<div id="box1">box1</div>
<script>
var Obox1=document.getElementById("box1");
console.log(Obox1)
</script>
11.3 通过标签名去获取一类标签
通过标签名去获取一类标签:[context].getElementsByTagName("标签名");
var olis=document.getElementsByTagName("li"); // 获取文档中左右的li标签
var box1=document.getElementById("box1");
var lis=box1.getElementsByTagName("li");// 获取box1 下面所有的li元素
11.4 通过style属性去添加或者修改元素的样式
<div id="box1">box1</div>
<script>
var Obox1=document.getElementById("box1");
Obox1.style.backgroundColor="pink";
</script>
11.5 给元素添加类名
var Obox1=document.getElementById("box1");
Obox1.className="current";
12. 开关灯案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin:0;
padding:0;
}
body{
background:darkturquoise;
}
#main{
width:300px;
border:1px solid green;
margin:0 auto;
}
#button{
width:100%;
height:50px;
background:lightblue;
text-align: center;
}
#imgbox{
display:block;
}
</style>
</head>
<body>
<div id="main">
<button id="button">隐藏</button>
<img id="imgbox" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1577444372587&di=1684c649c2b1d4b1fdcd5910968c508b&imgtype=0&src=http%3A%2F%2Fimg.pconline.com.cn%2Fimages%2Fupload%2Fupc%2Ftx%2Fpcdlc%2F1709%2F16%2Fc79%2F59427944_1505500668556.gif" alt="">
</div>
</body>
</html>
<script>
/*
默认:图片是显示的,按钮的内容 隐藏
点击按钮的时候,如果按钮原来是隐藏,
+ 按钮内容变成“显示”
+ 图片消失
点击按钮的时候,如果按钮是显示,
+ 按钮内容变成“隐藏”
+ 图片显示
*/
var button=document.getElementById("button");
var oimg=document.getElementById("imgbox");
button.onclick=function(){
var value=button.innerText;
if(value=="隐藏"){
button.innerHTML="显示";
oimg.style.display="none";
}else{
button.innerHTML="隐藏";
oimg.style.display="block";
}
}
</script>
13. 案例之隔行变色
如果每隔三行实现一个变色,就是.main>li:nth-child(3n+1) .main>li:nth-child(3n+2) .main>li:nth-child(3n)12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin:0;
padding:0;
}
ul,ol{
list-style: none;
}
body{
background:lightseagreen;
}
.main{
width:500px;
/* border:1px solid #000; */
margin:50px auto;
color:#666;
}
.main>li{
height:40px;
line-height:40px;
text-indent: 20px;
}
.main>li:nth-child(even){
background:yellow;
}
.main>li:nth-child(odd){
background:lightgreen;
}
.main>li:hover{
background:lightblue;
}
</style>
</head>
<body>
<ul class="main">
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
</ul>
</body>
</html>
14. js实现奇偶行变色
分析:隔行变色的原理:
操作的元素:li ,
让 处于奇数的li 变一个颜色1
让 处于偶数行的li 变一个颜色2
14.1 方法一: 通过style行内属性来改变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul,
ol {
list-style: none;
}
body {
background: lightseagreen;
}
#main {
width: 500px;
/* border:1px solid #000; */
margin: 50px auto;
color: #666;
}
#main>li {
height: 40px;
line-height: 40px;
text-indent: 20px;
}
</style>
</head>
<body>
<ul id="main">
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
<li>走在前沿的专家级课程:微信小程序实战开发课程</li>
</ul>
<script>
var omain = document.getElementById("main");
console.log(omain)
var lis = omain.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
if (i % 2 != 0) {
lis[i].style.backgroundColor = "yellow";
} else {
lis[i].style.backgroundColor = "pink";
}
}
</script>
</body>
</html>
14.2 方法二:通过添加类名
<style>
.color1{
background:lightsalmon;
}
.color2{
background:yellow;
}
</style>
for(var i=0;i<lis.length;i++){
if(i%2!=0){
lis[i].className="color1";
}else{
lis[i].className="color2";
}
}
全部用js实现,隔行变色,并且鼠标滑上去的时候,改变颜色,鼠标离开之后,还原原有的颜色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin:0;
padding:0;
}
li{
height:30px;
line-height: 30px;
}
</style>
</head>
<body>
<ul class="main" id="main" style="background:blue">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
</html>
<script>
/*
原理:获取到所有的li元素,如果这个li是偶数我们就让它是一个颜色,如果不是偶数就是另一个颜色
*/
var omain=document.getElementById("main");
var lis=omain.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
if(i%2==0){
lis[i].style.background="blue";
}else{
lis[i].style.background="yellow";
}
// 鼠标滑上li的时候,改变那个li的背景颜色
lis[i].onmouseover=function(){
// 把原有的颜色绑定上去
this.bgColor=this.style.backgroundColor;
this.style.background="lightpink";
}
// 鼠标离开的时候,恢复原有的颜色
lis[i].onmouseout=function(){
this.style.background=this.bgColor;
}
}
</script>
15. 阿里引发的一道血案面试题
let a={
n:1,
}
let b=a;
a.x=a={
n:2
}
console.log(a.x);
console.log(b)
连等赋值:是按照从右向左
var a=b=20;
// 第一步:先创建一个值
// 第二步:b=20
// 第三步:var a=20;