1.开篇
2.前端发展史
w3c:html与css的语法规范。
ECMAScript: js的语法规范。
ES5:老一代语法规范
ES6:新一代语法规范
### 常用的浏览器
- webkit内核(v8引擎)
+ 谷歌chrom
+ safari
+ Opera >=v14
+ 国产浏览器
+ 手机浏览器
+ ···
- Gecko
+ 火狐Firefox
- presto
+ opera<v14
- Trident
+ IE
+ IE EDGE开始采用双内核(其中包含chrome迷你)
谷歌浏览器的控制台(F12/Fn+F12)
- Elements:查看结构样式,可以修改这些内容
- console:查看输出结果和报错信息,调试JS的利器
- sources:查看项目源码
- network:查看当前网站所有资源的请求信息(包括和服务器传输的HTTP报文信息)、
加载时间等(根据加载时间进行项目优化)
- Application:查看当前网站的数据存储和资源文件(可以盗图)
### JS做客户端语言
> 按照相关的JS语法,去操作页面中的元素,有时还要操作浏览器里面的一些功能
- ECMAScript3/5/6...:JS的语法规范(变量、数据类型、操作语句等等)
- DOM(document object model):文档对象类型,提供一些JS的属性和方法,用来操作页面中的DOM元素
- BOM(browser object model):浏览器对象模型,提供一些JS的属性和方法,用来操作浏览器的
### JS中的变量variable
>变量:可变的量,在编程语言中,变量其实就是一个名字,用来存储和代表不同值的东西
```
//ES3
var a = 12;
a = 13;
console.log(a);//=>输出的a代表的值13
//ES6
let b = 100;
b = 200;
const c = 1000;
c = 2000;//=>报错:CONST创建的变量,存储的值不能被修改(可以理解为叫做常量)
//创建函数也相当于在创建变量
function fn(){}
//创建类也相当于创建变量
class A{}
//ES6的模块导入也可以创建变量
import B from './B.js';
//symbol创建唯一值
let n=Symbol(100);
let m=Symbol(100);
```
### JS中的命名规范
- 严格区分大小写
```
let test=100;
console.log(Test);=>无法输出,因为第一个字母大写了
```
- 使用数字、字母、下划线、$,数字不能作为开头
```
let $box;//=>一般用JQ获取的以$开头
let _box;//=>一般公共变量都是以_开头
let 1box;//=>不可以,但可以写box1
```
- 使用驼峰命名法:首字母小写,其余每一个有意义单词的首字母都要大写
(命名尽可能语义化明显,使用英文单词)
```
let studentInformation;
let studentInfo;
//常用的缩写:add/insert/create/new(新增)、update(修改)、
delete/del/remove/rm(删除)、sel/select/query/get(查询)、info(信息)···
//不正确的写法
let xueshengInfo;
let xueshengxinxi;
let xsxx;
```
- 不能使用关键字和保留字
```
当下有关键含义的是关键字,未来可能会成为关键字的叫做保留字
var let const function···
var var10 = 10;//=>肯定不行
```
//=>代码强迫症(代码洁癖):良好的编程习惯、极客精神
### JS中常见的数据类型
- 基本数据类型
+ 数字number
常规数字和NaN
+ 字符串string
所有单引号、双引号、反问号(撇)包起来的都是字符串
+ 布尔(boolean)
true/false
+ 空对象指针
+ 未定义defined
- 引用数据类型
+ 对象数据类型object
+ {}普通数组
+ []数组对象
+ /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/正则对象
+ Math数学函数对象
+ 日期对象
+ ···
+ 函数数据类型function
## number数字类型
> 包含:常规数字、NaN
### NaN
> not a number:不是一个数,但他率属于数字类型
NaN和任何值(包括自己)都不相等:NaN!=NaN,所以不能用相等的方式判断是否为有效数字
### isNaN
> 检测一个值是否为非有效数字,如果不是有效数字返回true,反之是有效数字返回false
在使用isNaN进行检测时,首先会验证检测的值是否为数字类型,如果不是,先基于Number()
这个方法,把值转换为数字类型,然后再检测
### 把其他类型值转换为数字类型
- Number([val])
- parseInt/parseFloat([val],[进制]):也是转换为数字的方法,对于字符串来说,
他是从左到右依次查找有效数字字符,直到遇到非有效数字字符,停止查找(不管后面是否还有
数字,都不再找了),把找到的当做数字返回
- ==进行比较的时候,可能要出现把其他类型值转换为数字
## string字符串数据类型
> 所有用单引号、双引号、反引号(撇 ES6模板字符串)包起来的都是字符串
### 把其他类型值转换为字符串
- [val].tostring()
- 字符串拼接
## boolean布尔数据类型
> 只有两个值 true/false
### 把其他类型值转换为布尔类型
> 只有 0 、NaN、''、null、undefined 五个值转换为false,其余都转换为true(没有任
何特殊情况)
- boolean([val])
- !/!!
- 条件判断
## null / undefined
> null和undefined都代表的是没有
- null: 意料之中(一般都是开始不知道值,我们手动先设置为null,后期再给予赋值操作)
```
let num = null;//=>let num =0;一般最好用null作为初始的空值,因为零不是空值,他在
栈内存中有自己的存储空间(占了位置)
···
num = 12;
```
- undefined:意料之外(不是自己能决定的)
```
let num;/=>创建一个变量没有赋值,默认值是undefined
···
num = 12;
```
## object对象数据类型-普通对象
> {[key]:[value],···} 任何一个对象都是由零到多组键值对(属性名:属性值)组成的
(并且属性名不能重复)
> 数组是特殊的对象数据类型
number
// console.log([val]):在控制台输出内容
// console.log('hello!');
// ==:进行比较的
// console.log(1==2);
// console.log('AA'== NaN)
// console.log(10 == NaN)
// console.log(NaN == NaN)
// isNaN([val])
// console.log(isNaN(10));//=>false
// console.log(isNaN('AA'));//=>TRUE
/*
* Number('AA') =>NaN
* isNaN(NaN) =>TRUE
*/
// console.log(isNaN('10'));//=>false
/*
* Number('10') =>10
* isNaN(10) =>TRUE
*/
// =============Number===============
// 把字符串转换为数字,只要字符串中包含任意一个非有效数字字符
(第一个点除外)结果都是NaN,空字符串会变为数字零
// console.log(Number('12.5'));//=>12.5
// console.log(Number('12.5px'));//=>NaN
// console.log(Number('12.5.5'));//=>NaN
// console.log(Number(''));//=>0
// 布尔转换为数字
// console.log(Number(true));//=>1
// console.log(Number(false));//=>0
// console.log(isNaN(false));//=>false
// NULL->0 undefined->NaN
// console.log(Number(null));//=>0
// console.log(Number(undefined));//=>NaN
// 把引用数据类型转换为数字,是先把他基于tostring方法转换为字符串,
然后再转换为数字
// console.log(Number({name:'10'}));//=>NaN
// console.log(Number({}));//=>NaN
// // {}/{xxx.xxx}.tostring()=>"[object object]"=>NaN
// console.log(Number([]));//=>0
// // [].TOSTRING()->''
// console.log(Number([12]));//=>12
// // [12].TOSTRING()->'12'
// console.log(Number([12,23]));//=>NaN
// // [12,23].TOSTRING()->'12,23'
// let str = '12.5px';
// console.log(Number(str));//=>NaN
// console.log(parseInt(str));//=>12
// console.log(parseFloat(str));//=>12.5
// console.log(parseFloat('width:12.5px'));//=>NaN
字符串
/* let a = 12;
console.log(a.toString());//=>12
console.log((NaN).toString());//=>NaN */
//null和undefined是禁止直接toString的
//(null).toString()//=>报错
//但是和undefined一样转换为字符串的结果就是'null'/'undefined'
//普通对象.toString()的结果是"[object object]"=>?
=>object.prototype.toString方法不是转换为字符串的,而是用来监
测数据类型的
//=============字符串拼接==============
//四则运算法则中,除加法外,其余都是数学运算,只有加法可能存在字符串
拼接(一旦遇到字符串,则不是数学运算,而是字符串拼接)
/* console.log('10'+10);//=>'1010'
console.log('10'-10);//=>0
console.log('10px'-10);//=>NaN */
let a = 10 + null + true + [] + undefined + '珠峰' + null + []
+ 10 + false;
/*
10 + null -> 10 + 0 -> 10
10 + true -> 10 + 1 -> 11
11 + [] -> 11 + '' -> '11' 空数组变为数字,先要经历变为空字符串,
遇到字符串,直接变为字符串拼接
'11' + undefined -> '11undefined'
...
'11undefined珠峰null10false'
*/
console.log(a);
布尔
/* console.log(Boolean(0));
console.log(Boolean(''));
console.log(Boolean(' '));
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean([]));
console.log(Boolean([12]));
console.log(Boolean(-1)); */
//!:取反(先转为布尔,然后取反)
//!!:取反再取反,只相当于转换为布尔<=>Boolean
/* console.log(!1);//=>false
console.log(!!1);//=>true */
//如果条件只是一个值,不是==/===/!=/>=等这些比较,是要先把这个值先
转换为布尔类型,然后验证真假
if(1) {
console.log('嘿嘿');
}
if('3px' + 3) {
//=>'3px3'
console.log('嘻嘻')
}
if('3px' - 3) {
//=>NaN-3=>NaN
console.log('哈哈')
}
数组
let person = {
name: '张三',
age: 30,
height: '185cm',
weight: '80kg',
1:100
};
//删除属性
//=>真删除:把属性彻底删掉
/* delete person[1];
//=>假删除:属性还在,值为空
person.weight = null;
console.log(person);
*/
//设置属性名属性值
//=>属性名不能重复,如果属性名已经存在,不属于新增属于修改属性值
/* person.GF = 'yuanyuan';
person.name = '李四'
console.log(person['GF']);
console.log(person['name']); */
//获取属性名对应的属性值
//=>对象.属性名
//=>对象[属性名] 属性名是数字或者字符串格式的
//如果当前属性名不存在,默认的属性值是undefined
//如果属性名是数字,则不能使用点的方式获取属性值
/* console.log(person.name);
console.log(person['age']);
console.log(person.sex);//=>undefined
console.log(person[1]);
// console.log(person.1);//=>syntaxerror:语法错误 */
/*
*数组是特殊的对象
* 1.中括号中设置的是属性值,它的属性名是默认生成的数字,从零开始递
增,而且这个数字代表每一项的位置,称其为“索引”=>从零开始,连续递增,
代表每一项位置的数字属性名
* 2.天生默认属性名 length ,存储数组的长度
*/
let ary = [12,'hh',true,11];
console.log(ary.length);
console.log(ary['length']);
console.log(ary[1]);
//第一项索引0 最后一项索引 ary.length-1
console.log(ary[0]);
console.log(ary[ary.length-1]);
//向数组末尾追加内容
ary[ary.length] = 100;
console.log(ary);
练习1
/* let a = 12;
let b = a;
b = 13;
console.log(a);
let n = {
name: 'zhufeng'
};
let m = n;
m.name = 'peixun';
console.log(n.name); */
let n =[10,20];
let m = n;
let x = m;
m[0]=100;
x=[30,40];
x[0]=200;
m=[50,60];
m=x;
m[1]=300;
n[2]=400;
console.log(n,m,x);//=>n =[100,20,400]m = x = [200,300]
练习2
let a = {
n: 1
};
let b = a;
a.x = a = {
n: 2
};
console.log(a.x);
console.log(b);
/* let a = {n:1};
let b = a;
a.x = b;
console.log(a.x);
console.log(b); */
阿里的面试题
let a = {
n: 1
};
let b = a;
a.x = a = {
n: 2
};
console.log(a.x);=>undefined
console.log(b);=>{
n: 1,
x:{
n: 2
}
}
堆栈底层机制
练习题
数据类型的检测
### JS中的数据类型检测
- typeof[val]:用来检测数据类型的运算符
- instanceof :用来检测当前实例是否率属于某个类
- constructor :基于构造函数检测数据类型(也是基于类的方式)
- object.prototype.toString.call() :检测数据类型最好的办法
### JS中的操作语句:判断、循环
#### 判断
> 条件成立做什么?不成立做什么?
- if/else if/else
- 三元运算符
- Switch case
1. if/else
```
if(条件){
条件成立执行
}else if(条件2){
条件2成立执行
}
···
else{
以上条件都不成立
}
```
2. == vs ===
==:相等(如果左右两边数据值类型不同,默认先转换为相同类型,再比较)
'5'==5=>true
===:绝对相等(如果类型不一样,肯定不相等,不会默认转换数据类型)
'5'===5=>false
项目中为了保证业务的严谨,推荐使用===
/*
*基于typeof检测出来的结果
* 1.首先是一个字符串
* 2.字符串中包含对应的类型
* 局限性
* 1.typeof null=> "object" 但是null并不是对象
* 2.基于typeof无法细分出当前值是普通对象还是数组对象等,因为只要是对象
数据类型,返回结果都是"object"
*/
/* console.log(typeof 1);
let a = NaN;
console.log(typeof a);//=>'number' */
console.log(typeof typeof typeof []);
//=>typeof [] =>"object"
//=>typeof "object" =>"string"
//因为typeof检测的结果都是字符串,所以只要两个及以上同时检测,最后结果必然是"string"
css写鼠标经过显示详情
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>鼠标滑过显示详情</title>
<!-- import css -->
<style>
* {
margin: 0;
padding: 0;
}
.box {
/* css3新盒子模型属性:控制width/height是盒子最终的宽高 */
box-sizing: border-box;
margin: 20px auto;
width: 200px;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid lightblue;
position: relative;
}
.box .detail {
display: none;
position: absolute;
right: -1px;
top: 38px;
box-sizing: border-box;
width: 500px;
height: 100px;
line-height: 100px;
text-align: center;
border: 1px solid blue;
z-index: -1;
}
.box:hover .detail{
display: block;
}
.box:hover{
border-bottom: 1px solid #fff;
}
/* 如果是点击实现显示,不需要js也可以,可以基于:target实现手风琴效果 */
</style>
</head>
<body>
<!-- 基于css实现,我们需要让详情区域是按钮的子元素-->
<div class="box">
<span>购物车</span>
<div class="detail">
购物车的相关信息
</div>
</div>
</body>
</html>
js写鼠标点击切换详情显示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>点击切换详情显示</title>
<!-- import css -->
<style>
* {
margin: 0;
padding: 0;
}
.box {
box-sizing: border-box;
margin: 20px auto;
width: 200px;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid lightblue;
position: relative;
/* 设置鼠标是一个小手 */
cursor: pointer;
}
.box .detail {
display: none;
position: absolute;
right: -1px;
top: 38px;
box-sizing: border-box;
width: 500px;
height: 100px;
line-height: 100px;
text-align: center;
border: 1px solid blue;
z-index: -1;
}
</style>
</head>
<body>
<div class="box" id="box">
<span>购物车</span>
<div class="detail" id="detail" style="display:none">
购物车的相关信息
</div>
<!--
传统基于操作DOM的方式实现业务需求
1.想操作谁就先获得谁
2.给某元素绑定某事件
3.在事件触发的时候修改元素的样式等
-->
<!-- import js -->
<!-- <script>
//document.getElementById([id]):在整个文档中,通过元素的id获取当前这个元素对象
let box = document.getElementById('box');
let detail = document.getElementById('detail');
//元素对象.on***=function(){}:事件绑定,***事件类型(click/mouseover/mousedown/keydown···)
box.onclick = function () {
//元素对象.style.***=***:修改元素的某一个样式值(操作的是元素行内样式,如果没有把样式写在行内上,在JS中基于.style.***的方式是无法获取样式的)
//1.首先获取detail原有的样式(显示还是隐藏):元素.style.***就是获取某一个样式(前提:需要在元素行内设置这个样式才能获取到)
// console.log(detail.style.color)
/* detail.style.display = 'block';
box.style.borderBottomColor = '#FFF'; */
let n = detail.style.display;
if(n==='none'){
//当前是隐藏的,让其显示
detail.style.display = 'block';
box.style.borderBottomColor='#FFF'
}else{
//当前是显示的,使其隐藏
detail.style.display = 'none';
box.style.borderBottomColor='lightblue'
}
}
</script> -->
<script>
let box = document.getElementById('box');
let detail = document.getElementById('detail');
box.onclick = function () {
let n = detail.style.display;
if (n === 'none') {
detail.style.display = 'block';
box.style.borderBottomColor = '#FFF';
} else {
detail.style.display = 'none';
box.style.borderBottomColor = 'lightblue';
}
}
</script>
</div>
</body>
</html>