JavaScript
- 一、了解javascript
- 二、javascript语法
- 三、函数
- 四、数组
- 1.什么是数组
- 2.声明数组
- 3.数组的属性
- 4.数组的遍历
- 5.数组的方法
- 栈结构
- 队列结构
- push方法-在数组末尾插入元素
- unshift方法-在数组头部插入元素
- pop方法-从数组中取走最后的元素
- shift方法-从数组取出第一个元素
- concat方法-拷贝数组形成新数组
- slice()方法-截取数组中的元素
- splice()方法-删除元素并插入新元素
- join()方法-为数组元素拼接字符串
- reverse()方法-倒序排列数组
- sort()方法-对无序数组进行排序
- indexOf()方法-查询某个数首次出现在数组的位置
- forEach()方法-遍历数组
- map()方法-用来映射和原数组的关系。
- filter()方法-过滤规则
- includes() -检索函数
- some()方法-找到某个符合条件的元素
- every()方法-根据条件查找,找到不符合的就停止
- reduce()方法-归并,求和
- 6.数据类型的引用
- 7.声明提升
- 8.省略var声明变量
- 9.二维数组
- 10.冒泡排序
- 11.选择排序
- 五、严格模式
- 六、字符串
- 七、面向对象
- 八、JSBOM
- 九、jsDOM
- 十、ECMAScript6
一、了解javascript
1. javascript组成
1.ECMAscript 2.DOM 文档 3. BOM 浏览器
2.javscript使用
1.一般写在body标签内,也可以用link引入。可以写多个script标签,标签执行的顺序自上而下。
2.引入的script标签就不能在标签里面写javascript代码,无法执行到。
二、javascript语法
1. 基础方法
编写javascript,每一行结束的位置加;
,为了以后压缩代码不出现错误。
2.基本数据类型
常量:不能改变的值
基本数据类型:
-
数字类型 number
-
布尔值 boolean
true、false -
字符串 String
带引号都是
特殊类型:
null 空
undefined 未定义
NaN not a number 不是数字
变量:可以修改值
判断数据类型 typeof
可以判断基本数据类型,对复杂的数据类型无法准确判断。
3. 命名规范
由下划线、数字、$ 符号构成,首字母不能是数字,不能是保留字和关键字。区分大小写。见名思意。
typeof +值; 输出数据类型
alert(typeof "dsa");
alert(typeof typeof 100) 在typeof前面在加一个typeof,显示的数据类型都是字符串。因为先判断数据类型给出提示,在判断的提示内容,所以是字符串。
4.运算符
infinity 无穷大
-infinity 无穷小
在JS中除数可以为0
4.1 算术运算符
、+、-、*、/ %取余
4.2 关系运算符
<、> .<=.>=. ==. !=
===恒等
!==恒不等
恒等比较的是数值和数据类型,只有两个都是相等才会返回ture。
4.3 逻辑运算符
&& 、||、!、
与运算的等级比或运算的等级高,在进行复合运算时,可以选择加小括号,也可以选择不加小括号。
4.4 一元运算符
++、- -、
a++,++在后,先取值,在计算。- -同上
++a,++在前,先计算,再取值。- -同上
4.5 赋值运算符
=、+=、-=、
4.6自动类型转换
与字符串相加是合并拼接,输出结果都是字符串
4.7强制类型转换
5. 条件判断
if和switch的选择。有固定的值就选择switch。
5.1 if 单分支和多分支
5.2 switch语句
switch根据固定的条件,选择固定的代码。case后面必须是常亮。case代码块后面必须跟break,最后一个case不用。如果都没有要选择的条件,加上default。
省略break的技巧
当几个选项结果相同时,可以将case排列在一起,在最后的case加上break。
5.3 三目运算
判断?表达式1:表达式2
如果判断为真,输出表达式1.
如果判断为假,输出表达式2.
5.4 while和do while
条件里如果是数字表示为true。如果数字是0表示false。
while循环
while (条件) {
需要执行的代码;
}
先判断条件,如果条件正确,就一直执行,直到条件不满足。
do-while
do {
需要执行的代码
}
while (条件);
先执行一遍代码块,然后再进行条件判断,直到条件不满足。
6. for循环
先执行语句1,确定变量。再执行语句2,判断条件是否满足。如果条件满足,就执行大括号里的代码块。之后再执行语句3,进行自增或自减。
每次循环都是执行括号内容一次
for…in :for(var 属性名或下标 in 对象或数组){} 靠下标来遍历,一般用来遍历对象或数组,遍历对象身上所有属性
foreach(function(item元素,index下标,arr数组){}):靠元素和下标来遍历
for…of:es6 中出现,靠元素来遍历,for(var item元素 of 集合){} 可以用于遍历集合。
7. break和continue和死循环
break:用来终止当前循环。
continue:跳过本次循环,接着进行下一次的循环。
三、函数
1.函数声明和调用
用function封装的是函数,调用的叫方法。
函数声明语法:
函数调用语法:
直接使用函数名字()。
2.函数形式
无参无返回值。
有参无返回值。
有参有返回值。
3.封装函数
不确定的值可以作为形参考虑。
4.return返回值
return 后面写什么就返回什么。可以是任意的东西。
如果在代码块中间写return,会终止函数,不执行后面的代码。
5.arguments 函数内置对象
每封装一个函数,在他的内部都会有一个arguments对象。
arguments是用来存储实参。
在对于函数传入实参不确定的情况下可以用arguments获取参数,对于可以确定的形参,还是直接用形参。
arguments.length------用来输出给函数传入实际参数的个数。
arguments[0]---------根据下标来查看参数内容,下标从零开始。
6.函数作用域和内存
变量的作用域分为全局变量和局部变量。
内存
函数的内存大小取决于函数内变量的个数和形参的个数。
垃圾回收
程序在执行的时候都会占用内存空间。函数在执行的时候也会占用内存空间,当函数调用完,会被清理掉,这就是垃圾回收机制。
1.创建变量a,给a开了一块空间。
2.调用函数show()时,又开了一块新的空间。
7.函数递归
什么是递归
满足三个条件就是递归:
1.函数自己调用自己。
2.一般情况下有参数。
3.一般情况下有return。
递归能干什么
递归可以解决循环能做的事情,有些循环做不了的递归可以做
如何写出递归
1.首先找到临界值,就是不用计算就可以获得的值。
2.找这一次和上一次的关系,就是上一个值做了什么获得这次的值。
3.假设这个递归函数已经可以适用,调用递归函数本身计算一次。
递归注意事项
只能用于静态数据计算,如果用动态数据,风险过高,会开很多的内存,导致系统崩溃。
8.匿名函数
普通函数有函数名,匿名函数没有函数名。运行匿名函数可以给他加个括号包裹起来。
作用:
1.可以实现闭包
2.减少全局变量,节省内存
使用场景:
1.给变量赋值一个函数,等同于声明函数
2.点击事件
3.对象创建函数
匿名函数调用
var add=(function (){})();
匿名函数();
9.this
只要封装函数,任何一个函数系统都会内置一个叫做this的变量
-call() 强制改变this指向参数
格式:函数.call(强制改变指向对象,其他参数,其他参数)
-apply()强制改变this指向参数
格式:函数.apply(强制转换对象,数组)
apply和call非常相似,call传入的是对象,和所需要的参数。apply传入的也是对象,后面参数传入的是数组
-bind()预设this指向
this混乱问题
this指向当前的主人。
1.this事件绑定
解决方法:
2.定时器
4秒后由系统调用
解决方法:
和上面的解决方法一样
3.多个方法嵌套,用箭头函数,箭头函数是外部作用域
10.回调函数
回调函数就是把函数作为参数,传入主函数里
function say(some,value){
alert(value)
some("函数");
}
say(function(name){alert("回调"+name)},'sayy');
四、数组
1.什么是数组
通过一个变量来存储多个数值,数组中存储的数据叫元素,下标从0开始。
2.声明数组
通过new来创建新的数组,括号里可以传入任意的参数
var arr = new Array();
var arr = Array(10); 声明一个长度为10的数组。
3.数组的属性
数组名.length 查看数组长度
数组名[下标] 查看当前下标对应的元素。
4.数组的遍历
通常数组和for循环一起适用,查看数组中所有的元素。
5.数组的方法
栈结构
数组放置元素从前往后依次放入。需要运用数组的push和pop方法。
特点:先进后出,后进先出。
队列结构
特点: 放入数组的元素,从头部取出。需要运用数组的push和shift方法。
push方法-在数组末尾插入元素
格式: 数组.push(插入的元素);
作用: 为数组添加元素,元素添加在原来数组的末尾,push方法的返回值是返回添加元素后的数组中元素的个数。只显示本次使用push方法添加后的个数,在push方法后添加的不考虑。
unshift方法-在数组头部插入元素
格式: 数组.unshift(插入的元素);
返回值: 返回插入元素后,数组中元素的个数。
pop方法-从数组中取走最后的元素
格式: 数组.pop();
返回值: 返回从数组中取出的最后一个元素的值。
作用: 从数组的中取出最后一个元素。
shift方法-从数组取出第一个元素
格式: 数组.shift();
返回值: 返回从数组头部取出的元素的值。
concat方法-拷贝数组形成新数组
格式: 数组.concat(数组,数据。。。。);
作用: 拷贝数组,如果有新数据合并成同一个新数组。
注意: 用concat合并数组的时候,里面传入的数组元素,会被逐个拿出来合并成新数组。拷贝的新数组会在堆中建一个新的内存地址存放数值。
slice()方法-截取数组中的元素
格式: 数组.slice(strat,end); 左闭右开。
作用: 截取数组中的片段,形成新的数组,不会改变原数组。
splice()方法-删除元素并插入新元素
格式: 数组.splice(开始位置,截取的个数,插入的新元素…);
作用: 截取数组,并在截取开始的位置插入新元素。不会改变原数组的元素。会改变原数组元素。
返回值: 返回删除的元素。
注意: 截取个数为0,才不会删除开始位置的元素,如果截取个数有数值,则会删除这些元素,在原数组的位置增加新元素。
join()方法-为数组元素拼接字符串
格式: 数组.join(字符串); 不会改变原数组。
reverse()方法-倒序排列数组
格式: 数组.reverse();
sort()方法-对无序数组进行排序
格式: 数组.sort();
注意: sort排序是按照字符串大小排序,不是按照数值大小排序。
indexOf()方法-查询某个数首次出现在数组的位置
格式: 数组.indexOf(item,start), item:要查询的数。 strat:开始查询的下标,默认是0,不填写也是0。
数组没找到要查询的数,该方法返回-1
forEach()方法-遍历数组
**格式: ** 数组.forEach(function(item,index,arr){})
map()方法-用来映射和原数组的关系。
**格式: ** 数组.map(function(item,index,arr){})
filter()方法-过滤规则
用return填写过滤规则,原数组不改变数值。 可以看成 数组里的数据 一个一个和 回调函数传入的条件对比。 满足条件的是true,返回出去成新的数组。
格式: 数组.filter(function(item,index,arr){})
includes() -检索函数
用来查看数组里是否包含传入的值,是的话 返回true。
some()方法-找到某个符合条件的元素
every()方法-根据条件查找,找到不符合的就停止
reduce()方法-归并,求和
6.数据类型的引用
基本数据类型引用
在基本数据类型引用的内存中,会按照代码块从上至下依次执行。
1.先开一个num1的内存空间,赋值为10。2.在开一块num2的空间,将num1的值赋值给num2,num2为10 。3. 给num2赋值为20。最后的输出结果num1为10,num2为20.
复合数据类型引用-数组
如果是数组引用,数组的值会被放在堆里,数组直接引用内存地址,内存地址指向数据。数组1赋值给数组2的时候,数组2获得的是数组1的内存地址。如果用push方法向数组2中添加数据,直接添加在堆中,数组1和数组2的内存地址相同,根据内存获取数值。
使用concat方法会建立新的内存地址。
7.声明提升
内存分配,一次分配。预编译:在所有代码需要运行之前,计算机先将所有的代码看一遍,将需要分配的空间一次性分配完成。
声明提升就是还没生成变量和函数,先使用。
在当前作用域,声明变量和函数,会直接提升在整个代码最前面运行。
8.省略var声明变量
省略var声明变量会直接将局部变量提升为全局变量。
注意:不建议这样声明变量,属于语法错误。
9.二维数组
数组中存储元素,数组中的元素可以是任意数据类型,也可以是数组。通过数组直接调用。
10.冒泡排序
有两次循环完成冒泡排序。比较方法是,第一轮第一次由第一个和第二个比较,第一轮第二次由第二个和第三个比较
外面的循环,是整体比较几轮。里面的循环是前一个数和后一个数比较的次数。
外面的轮数是整体数字减一(length-1)。里面的循环是随着轮次增加比较的数字减少(length-(轮数+1))。
外面循环的轮数是整体数字减一次,最后一次轮不用比较,最小的得出来了。
里面的数字之间比较的次数,最后一次没有数,不用与其他的数比较,所以还要减少一次,每一轮随着轮数的增加,得出确切的数字越多,所以要减去得到的数字,得到的数字与轮数相等。所以直接减去轮次和第一次不用比较的数。
11.选择排序
思维: 第一个数和后面所有的数比较,如果比他小,互换,接着和后面的比较,比较到最后,第一个数是最小的。
图解:
JS代码:
五、严格模式
严格模式写在哪个作用域下,就在哪个作用域生效。“use strict”
严格模式尽量不要写在全局作用域
1.全局变量必须加var
在严格模式下不会出现局部变量转换成全局变量。必须要在变量前面加var
2.this无法指向全局变量
3.函数内重名参数不可以
在非严格模式下,可以出现同名参数,不会报错,但传入参数会被覆盖。
4.arguments对象不允许动态修改
在严格模式下arguments不会被动态修改。
5.新增关键字不能作为变量使用
六、字符串
1.在js中,字符串即是基本数据类型,又是复合数据类型。
2.字符串是只读的,不能被修改。
1.创建字符串
2.字符串的个数和访问单个字符
格式: 字符串.length
字符串是只读的,不能修改字符串的内容。字符串可以通过循环遍历所有的字符内容。
3.字符串方法
格式: 字符串.方法名
这些方法基本用不上,直接用html+css输出文字更方便。
-charCodeAt() 访问字符串下标元素的ascll码值
-String.fromCharCode() 根据传入的ascll码值返回组成的字符串
-indexOf() 查找一个字符串是否存在另一个字符串中
indexOf(要查询字符串,开始的位置)
如果查询空字符串,填写的是那个,返回就是那个位置,如果开始位置大于整个字符串,会返回字符串长度。
var str="hello password";
alert(str.indexOf('',9));
-lastIndexOf() 查找字符串最后出现的位置
-search() 查找字符串
和indexOf一样的功能,区别在于,传入的参数。search可以传入字符串,也可以传入正则表达式。
-substring() 截取自定义范围的字符串
截取范围内的字符串,左闭右开。返回新的字符串,不改变原字符串。直接写一个数字表示从头到第几个。
-substr() 截取自定义长度的字符串
和subSting一样的功能,区别就是String是根据范围截取,Str是根据长度截取。
-replace() 替换字符串
把老的字符串替换成新的字符串。
-split() 分割字符串
填入你想要切割的字符,会把切割后的字符串返回。填写空格会切割空格。
-toLowerCase() toUpperCase() 转换字符串大小写
-concat() 拼接字符串
七、面向对象
1.认识对象
在JavaScript中,只有对象没有类。对象就是类的实体
2.创建对象
对象遍历
i是变量名
3.delete 删除方法删除对象的属性或方法
4.Math对象提供的方法
5.日期对象提供的方法
6.将时间转换成毫秒数
八、JSBOM
浏览器对象模型(browser object model)
JavaScript实现与浏览器的交互。一个浏览器窗口就是一个BOM,窗口包括页面显示的内容,也包括前进后退等浏览器功能。
1.window-窗口对象
全局域的对象、函数、变量都属于window的对象下的,只不过window可以省略不写。
-window.alert() 警告框
警告框用于确保用户得到某些信息,用户需要点击确定才能继续操作。
-window.confirm() 确认框
确认框用于验证用户接受某些操作,当确认框弹出的时候,用户可以点击确定或取消。返回true或false。
-window.prompt() 提示框
提示框用于用户进入某个页面输入信息提示,如果点击确定会返回输入的值,如果点击取消会返回null。
-window.open() 打开某个网址
第三个参数可以设置宽高,页面距离
第三个参数可以设置打开窗口的特性,有的浏览器兼容,有的浏览器不兼容
-widow.onload 页面加载玩执行方法
因为 JavaScript 中的函数方法需要在 HTML 文档渲染完成后才可以使用,如果没有渲染完成,此时的 DOM 树是不完整的,这样在调用一些 JavaScript 代码时就可能报出"undefined"错误。
2. window.history-浏览器历史对象
history不是浏览器里面的历史记录,针对当前窗口,只要加载url不一样就会产生一条新的历史记录。
-history.length 属性
查看当前窗口有多少条历史记录
-history.back() 后退
-history.forward() 向前
-history.go() 去哪个页面
history.go有三个参数,输入0,刷新当前页面。输入正整数,前进几个页面,输入负整数,后退几个页面。
3. window.location 浏览器地址栏对象
-url路径
url:统一资源定位符
组成:协议://ip(域名):端口/路径目录/文件名.文件后缀?查询字符串#锚点
就以下面这个URL为例,介绍下普通URL的各部分组成
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
从上面的URL可以看出,一个完整的URL包括以下几部分:
1.协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符
2.域名部分:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用
3.端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
计算机端口号 0-65535
浏览器端口:8080
http端口: 80
https端口:443
4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”
5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
-location.protocol 返回当前网址协议
file:// 本地文件
http://
https:// 安全协议
-location.hostname 返回当前网址域名
-location.assign(url) 跳转到指定url
会生成新的url地址,产生history历史记录
-location.replace(url) 当前窗口替换成指定url
会变换网址,不会history产生历史记录
-location.reload() 重新加载本页面
重新加载,如果本地有页面缓存,还是使用缓存。
location.reload(true) 不经过浏览器强制从服务器重载。
4.console 调试对象
-console.log()
-console.time() 测试代码运行时间
console.time(“测试名字1”) 配合console.timeEnd(“测试名字1”) 。中间放置的是测试代码
5. 本地存储
H5之后添加的,不兼容低版本浏览器。
-localStorage 客户端微型数据库
1.永久存储,除非主动删除
2.最大可以存储5M文本
3.只能存储string
4.IE8之前的浏览器不支持localStorage
-localstorage.setItem(name,value)保存数据
-localstorage.getItem(name)读取数据
-localstorage.removeItem(name)删除数据
-cookie
1.可以设置过期时间,多长时间后过期
2.最大可以存储4KB
3.每一个域名下面最多存储50条数据
4.cookie中存储的是字符串
5.cookie保存在客户端
4KB和50条数据同时约束,满足一个都不可继续存储。
-sessionStorage
1.session保存的是对象
2.session数据保存在服务端
6.setInterval()-定时器
window对象方法
格式: setInterval(函数,毫秒数); 定时器在被创建的时候系统分配编号,这个编号在返回值里。可以获得这个返回值
功能: 每隔一次毫秒数,执行一次传入的函数
如何保证只启动一个定时器
每启动定时器之前,先将上一次的定时器关闭
7.clearInterval()-取消定时器
window对象方法
格式: cleatInterval(定时器的返回值);
功能: 根据定时器的返回值,设定到达某个时间取消定时器
九、jsDOM
DOCUMENT OBJECT MODEL 文档对象模型
当网页被加载的时候,浏览器就会获取文本对象模型。就会有各个节点,想要获取各个节点就要运用DOM的方法,页面的每一个组成部分都是一个节点。
1.节点类型
节点类型:
1.元素节点 就是标签
2.属性节点 就是标签的属性
3.文本节点 就是标签里面的文本内容
4.注释节点 页面的注释文本
document是整个文档。node代表各个节点。节点有自己的方法可以获取里面的子节点和对相应的属性。
-document.getElementById(id)获取元素节点
用document.getElementById(“id”)通过ID获取,ID是唯一的。该方法返回一个元素节点,节点属于对象
获取行间的属属性,直接用获取到的节点 节点.属性。(aaa.id)
获取行间css样式
-document.getElementsByname(name属性值)
通过name的属性值获取元素节点
-node.getElementsByTageName(标签名)
通过标签的名字获取到元素节点
-node.getElementsByClassName(class)
通过class获取元素节点
-自定义byClassName方法
2.获取当前有效样式
通过(node.样式)只能获取行内css样式,并不一定是有效的。
修改样式直接获取节点修改即可。
3.attribute 获取属性节点
attribute:属性
-getAttribute 获取属性
-setAttribute 设置属性
通过getElementsById获取的元素节点属于对象,所以自定义属性可以成功,但是不会在行间显示,但是可以获取到。
-removeAttribute 删除属性
普通的方法只能将属性设置成空字符串,而removAttribute可以直接删除属性和属性值。
4.元素节点属性
任何元素节点都拥有的三个属性 innerHTML、innerText、outerHTML
5.节点的属性
nodetype、nodename、nodevalue
6. 获取子节点
7.创建节点
创建元素节点后,直接往标签.属性添加属性,其他方法不常用
-document.createElement() 创建元素节点
-document.createTextNode() 创建文本节点
-document.createComment() 创建注释节点
-document.createAttribute() 创建属性节点
8.插入节点
- appendChild() 追加插入节点
将创建的节点插入到父节点,放在其他节点后面
-insertBefore() 将节点插入到指定位置
9.替换节点
-replaceChild() 替换子节点
10. 克隆节点
-cloneNode() 克隆节点
11.offset系列函数
获取的是元素的坐标
-offsetWidth 获取样式宽度
获取到的宽度=width+padding+border
-offsetHeight 获取样式高度
获取到的高度=width+pdding+border
-offsetLeft 获取样式距左的距离
获取到的是能看到的,距离第一个有定位的父元素的距离
-offsetTop 获取样式距上的距离
获取到当前元素到第一个有定位的父元素的距离
输出当前窗口的宽和高
需要兼容处理
12.文档碎片
文档碎片独立于DOM树之外,存在于内存中,插入节点的时候。思路就是:先将要创建插入的节点放置到一个节点中,然后将这个节点插入到要插入的节点中,创建的时候使用内存,会解决页面的时间
13. event对象 事件
事件就是发生了什么,发生后做了什么。
当事件和函数绑定的时候,系统就会生成一个事件对象。当触发事件的时候,绑定的函数就会把事件对象作为第一个参数传入进去。
onclick-标签点击事件
点击某个标签触发的行为
可以写在标签的后面,表示点击后执行哪个函数。
<button onclick="this.innerHtml=Date()">点击获取时间</button>
也可以用点击事件等于函数。
window.onload-浏览器完成页面加载后做的事
绑定事件
绑定事件分两种模式:
1.内联模式 写在标签里面
2.外联模式/脚本模式 写在js里
事件类型
-鼠标事件
- 键盘事件
keydown事件触发的比获取输入框的时间快。可以用keyup获取输入框内容。
-HTML事件
获取绑定事件对象
事件对象会第一个作为参数自动传入,直接输出。IE8下不兼容,需要用到windo.event输出。
当需要用到事件对象的属性时,就需要先获取时间对象
事件对象属性
.button属性
获取到的是你鼠标按键,左键-0,滚轮-1,右键-2。
获取鼠标位置的三个属性
先获取事件对象,通过事件对象的属性获得鼠标位置。event下的属性,clientX /clientY 。获取鼠标在当前窗口的位置。
事件对象的按键属性
键码识别,快捷键设置
键码识别功能也是需要进行浏览器兼容选择。
.target 触发对象
target:目标
target只能在事件中使用,表示当前哪个对象触发的事件。要做浏览器兼容
target和this的区别
事件冒泡和阻止事件冒泡
事件捕获
添加监听器,false是事件冒泡(事件由里到外执行),ture是事件捕获(事件由外到里执行)。
阻止浏览器右键菜单
阻止超链接行为
拖拽-拖拽三剑客
mousedown、mousemove、mouseup、
事件委托
什么是事件委托
在 JavaScript 中,事件委托(delegate)也称为事件托管或事件代理,就是把目标节点的事件绑定到祖先节点上。这种简单而优雅的事件注册方式是基于事件传播过程中,逐层冒泡总能被祖先节点捕获。
这样做的好处:优化代码,提升运行性能,真正把 HTML 和 JavaScript 分离,也能防止出现在动态添加或删除节点过程中注册的事件丢失的现象。
如何事件委托
1.找到当前节点的父节点或祖先节点
2.将事件添加到父节点或祖先节点
3.找到触发对象,判断触发对象是否是想要触发的对象,如果是,进行其他操作。
-addEventListener() 事件监听器
传统事件给一个按钮绑定两个事件,第二个绑定的事件会覆盖第一个绑定的事件。事件监听器可以解决重复覆盖,可以把多次事件都执行出来。
事件监听器精确绑定事件和删除事件。
低版本IE浏览器不兼容,需要进行浏览器兼容
-removeEventListener()移除事件监听器
-attachEvent() 添加事件监听器,IE低版本
处理事件监听器兼容问题
-detachEvent() 删除事件监听器
十、ECMAScript6
1.let和const关键字
var 用来声明变量,将函数大括号内的变量和参数封为一个作用域,作用域外面不能访问。在循环判断的括号中,var声明的变量,括号外可以访问到。
var 声明的是局部作用域
var 声明的变量可以重名,但是会报错
let也是用来声明变量,只要是括号就是作用域,循环判断的括号外也访问不到参数。如果访问会报错。
let声明的是块级作用域,如果在循环中,每循环一次就是一个作用域,每个循环是单独的作用域。
let声明的变量只能声明一次,不可以重名,声明相同的变量,会取到最后赋值的值。let的作用域在{}
const声明变量,变量值只能在声明的时候确定,后期不能更改。const声明常量
2.箭头函数
箭头函数的作用域绑定的是外层的作用域
3.解构和es6字符串
中括号解构
解构用途:可以用来交换两个变量的值,类似于python,比直接三个换节约变量
中括号解构可以用来接受多个函数返回值,可以让函数返回多个值。
大括号解构
大括号解构声明的是变量不是对象
大括号解构用途:设置参数可以不用像普通参数那样固定位置,且可以设置默认值,传入参数的时候也可以不用固定位置传入参数。
可以快速的取出数组中的某一个数值
es6字符串
传统字符串:由单双引号括起来的就是字符串。传统字符串换行不能输出,换行需要加转义字符,而且换行也体现不出来
es6字符串:由反引号括起来``,里面的字符串可以随便写,调用变量用${变量/表达式/函数}。
4.数组方法和合并对象
-Array.from() 将伪数组转换为真数组
-find() 查找,只找第一个并返回
格式:arr.find(function(item,index,arr));
数组.find(function(item,index,arr)) ,意思是查找数组中的数,
find里跟的是查找条件封装的函数,查找到返回一个符合条件的数, 找不到返回undefined
功能:在数组中查找复合条件的元素,短路查找,只找到第一个复合的元素
返回值:返回找到的第一个元素值,如果没有找到返回undefined -判断函数是否有参数传递的结果。
-findIndex() 寻找数组下标
功能:找到匹配的数的下标,找到了就返回下标,没找到就返回-1
-copyWithin() 复制数组元素
功能:复制某个范围的数组,从指定位置开始,复制几个就替换几个。
格式:array.copyWithin(target, start, end)
-Object.assign() 合并对象
assign:分配,指派
功能:将几个对象合并成一个对象,合并到第一个对象,浅拷贝
格式:Object.assign(对象1,对象2,对象3)
-浅拷贝和深拷贝
对基本类型变量,浅拷贝是对值的拷贝,没有深拷贝的概念。
对引用类型来说,浅拷贝是对对象地址的拷贝,并没有开辟新的栈,复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,另外一个对象的属性也会改变, 而深拷贝则是开辟新的栈。
-数组遍历
5. 集合 Map和Set
集合特点:1.无序 2.不重复
-Set
生成:let myset =new Set(); 通过add()方法添加元素
String(“1”)是 字符串 ,new String(“1”) 生成字符串对象,是对象,地址不同,所以在 add的时候,添加的是两个不同的字符串对象。
set集合遍历
entries : 条目
iterator: 迭代器
通过for…of 遍历集合的键 ,集合的值 ,集合的条目
entries返回值, Set集合键和值是一样的
扩展运算符 […]
[…]将数据结构展开成数组
-Map映射
格式:let myMap =new Map(); 通过set添加键值对,通过get获取值
Map映射遍历
用解构 配合forof 遍历Map
6.面向对象编程
语法:类-一类抽象概念,对象:类的实体
数据类型:基本数据类型,数组,对象
封装(构造函数)、继承()、多态
创建对象
1.自己创建的对象没有new
2.官方对象方法不同对象调用的地址是一样的,自己创建的方法对象调用地址是不一样的
创建构造函数解决上述问题。
1.创建构造函数,里面创建属性
2.用原型prototype添加方法
构造函数
通过new调用的函数称为构造函数,用来创建对象。构造函数首字母大写,构造函数this指向新创建的对象。
构造函数的属性如何选择:在构造函数里面,每一个函数都要用或者跨函数的属性,可以设置成构造函数属性
如何写构造函数:1.将普通创建对象的方法省略,构造函数会自动生成this=new Object。2.将对象变成this。3.省略return,构造函数自动return this 。
prototype 原型对象
每一个函数都有一个prototype原型对象,一般用在构造函数上。如果我们将方法添加到构造函数的原型对象prototype上,那么每一个构造出的新对象都会共享原型prototype的方法。
_ proto _属性
构造函数创建的对象都有一个—proto—的属性,指向这个构造函数的原型。
instanceof 判断对象是否属于某个构造函数
功能:判断这个对象是否是这个构造函数构造出来的,可以用于判断数据类型
格式:对象 instanceof 构造函数 ,无法判断基本数据类型,只能判断实例化的对象。
继承
1.生成父类
2.继承父类
1.使用call()函数,强制改变this,可以将子类的与父类相同的属性传到父类。添加子类独有的属性。
2.继承父类方法
不能直接让子类原型等于父类原型,因为原型是引用类型,拷贝的是地址,是浅拷贝,子类添加方法,父类也会增加子类的方法,这是错误的。
用forin 将父类的原型里的方法逐个添加到子类,不会引发混乱,叫原型链继承。
多态
重写父类的方法,不对父类造成影响。也可以自己新增新的方法。
class继承 extends 父类
constructor 构造方法、制造
上面的内容是基于原型实现,现在用es6class实现继承。继承父类属性用super。
constructor 构造
constructor 除了可以作为构造器构造属性,还可以根据特性对数据类型进行判断
null和undefined 不可以用点. 所以不能使用constructor
万能数据类型检测 Object.prototype.toString.call
格式:Object.prototype.toString.call(数据类型)
利用call ,借用Object上的toString方法。 能检测的比较全,
-hasOwnProperty() 判断本身属性
功能:用来检测某个实例对象的构造函数是否有某个属性。判断是不是自己的属性
格式:Object.hasOwnProperty(字符串格式属性名) ,存在返回true 不存在返回false
-defineProperty() 添加属性 数据劫持
enumerable :可数,可枚举
功能:给对象添加属性和值,或者修改属性
格式:Object.defineProperty(obj对象名,key属性名,{对key的属性进行配置})
7.es6对象函数简写
8.认识运动
运动框架
1.每次启动定时器,将上一次定时器关闭
2.if。。。else 将运动和停止分开
多物体运动
1.定时器不能共用
2.任何数据不能共用
链式运动
链式运动:在第一个动画结束的时候,开始第二个动画