目录
普通函数中this 普通函数指的是直接拿函数名称调用的函数。
三、bind方法:复制出一个新的函数,并改变新函数中的this。
通常用于将伪数组转成数组,方便调用数组方法处理元素。不是所有方法都可以这样做的,因为有些方法中是没有this关键字的。六、参数处理
一、this关键字
一、this关键字含义
-
全局中this
-
普通函数中this 普通函数指的是直接拿函数名称调用的函数。
-
自调用函数中的this
(function() { console.log(this) })()
-
定时器中this
setTimeout(function() { console.log(this) }, 1000)
-
函数事件中this
<button id="btn">按钮</button> btn.onclick = function() { console.log(this) }
-
对象方法中this
var obj = { name: '张三', age: 12, eat: function() { console.log(this) } } obj.eat()
二、this的含义
-
解释:普通函数,大多都是属于window方法,所以普通函数调用就是调用window方法;事件的绑定就是再给标签对象添加方法,最终调用其实也是在调用标签对象的方法;定时器属于window的方法,所以定时器其实就是在调用window的方法。
-
总结
-
全局/ 普通函数/ 定时器/ 自调用函数 中的this都代表window
-
事件函数中的this - 当前事件源/标签(触发事件的标签)
-
对象方法中的this - 当前对象
-
箭头函数再定义好的时候就已经明确this关键字含义了,代表上级作用域的this。
严格模式中普通函数的this代表undefined
-
函数定义好,我们并不能确定其中的this代表什么,关键取决于谁调用这个函数,他就代表谁
-
fn() === window.fn()
-
document.onclick = fn === document.onclick()
-
obj.fn()
-
window.setTimeout() == window
-
自调用函数 === window.函数()
-
全局中的this - window
三、this含义改变(三种方法)
一、call方法:调用函数同时改变this
-
调用函数:函数.call(改变后的this含义,函数的实参) 和正常函数调用一样
-
<script> function fn() { console.log('三国') } fn() // 三国 fn.call() // 三国 </script>
二、apply方法:调用函数同时改变this
- 调用函数:函数.apply(改变后的this含义,[函数实参])和call方法一样。唯一不同的地方,在于传递实参。
call在调用函数时,给函数传递实参,是从call的第二个参数开始传递;apply给函数传递实参,是将所有实参组成一个数组作为apply的第二个参数传递的:
function fn(a, b) { var c = a + b console.log(c) console.log(this) } fn(1, 2) // 3 window fn.apply(document, [7, 3]) // document 10
三、bind方法:复制出一个新的函数,并改变新函数中的this。
- 使用语法:函数.bind(新的this含义),返回新函数。
四、注意箭头函数中this含义无法改变。
五、改变this使用场景
第一种:检测数据为对象时的精准类型
语法:对象.toString.call(数据)
第二种:使伪数组可以调用某些数组方法
语法:数组方法.call(伪数组)
var checkboxes = document.querySelectorAll('div')
var brr = [].slice.call(checkboxes)
console.log(brr);
通常用于将伪数组转成数组,方便调用数组方法处理元素。不是所有方法都可以这样做的,因为有些方法中是没有this关键字的。
六、参数处理
1.含义:如果被调用的函数需要实参时,call方法从第二个参数开始给函数传递实参
2.语法:函数.call(新的this含义, 实参1, 实参2, ...)
function fn(a, b) {
var c = a + b
console.log(c)
console.log(this)
}
fn(1, 2) // 3 window
fn.call(document, 2, 3) // document 5
fn.call(null, 5, 6) // window 11
七、伪数组
伪数组是一个对象。
这个对象中必须有length属性,如果length不为0,那么这个对象中必须有下标和对应的数据
常见的伪数组有: arguments DOM对象列表----HTMLCollection
伪数组转为数组的方法:将伪数组进行遍历放入数组中:上面有。
二、事件委托
- 含义:事件委托是指子标签委托父标签处理事件。
- 原理:利用事件冒泡,触发子标签事件的时候,会在冒泡阶段触发父标签的事件。
- 好处:1.提高的事件的绑定事件 2.动态添加的子标签也能有事件
- 关键技术:获取精准的目标元素(事件对象.target),对其进行判断。
三、ES6
es6是ECMAScript的第6个版本,在2015年发布。 es6有很多新语法,让开发者在操作数据和函数的时候,功能既多,操作又简便。
一、定义变量
es6中新增了两个类似于var的关键字来定义变量,分别是let和const。
var定义的变量,其实属于window
的属性,完整的写法应该是window.变量名
二、let关键字
1.没有预解析
2.不能重复定义
3.会自带块级作用域(全局定义的变量不在window中)
二、const关键字(常量)
1.let具有的特性const都有
2.定义就必须赋值
3.值不可以改
二、箭头函数
es6中的箭头函数是用来简写函数的:对以前函数定义的一种简写 - 只能简写匿名函数。
语法:function ( ) {代码段}
语法:(形参) => {代码段}
带参数的写法:
let fn = function(a,b){
console.log(a+b);
}
使用箭头函数改写:
let fn = (a,b)=>{console.log(a+b);}
注意:如果只有一个形参的时候,小括号可以省略:
注意:当大括号中只有一行代码的话,就可以省略大括号;
var add = a => console.log(a + 8);
注意:当箭头函数省略大括号后,如果这行代码中有return关键字,return关键字必须省略。
var add = function(a) {
return a + 3
}
var add = a => a + 3
var sum = add(7)
console.log(sum);//10
使用场景:通常在数组方法中使用
map - 新元素 filter - 条件 every - 条件 some - 条件 find - 条件 findIndex - 条件
数组.方法(function(v) { return 内容 } )
数组.方法(v => 内容)
三、形参默认值
当需要让一个形参变成可选项,可传递实参也可以不传递的时候,es6中新语法,快速实现需求
注意:带有默认值的形参,必须放在所有形参的末尾
// 随机颜色 - getRandom(0, 256)
// 随机字符 - getRandom(97, 123)
// 随机left - getRandom(0, innerWidth - 30)
// 随机下标 - getRandom(0, length)
function getRandom(a, b = 0) { // 形参可以有默认值
return Math.floor(Math.random() * Math.abs(a - b)) + Math.min(a, b)
}
// 函数调用有一个参数为0的情况比较多,我希望调用的时候能简便一点
// console.log(getRandom(256))
// console.log(getRandom(innerWidth - 30))
// console.log(getRandom(5, 10))
四、模板字符串
es6提供的一种新的定义字符串的语法,使用反引号
-
可以换行书写,保持字符串中的换行和空格
-
模板字符串中可以识别变量,使用美元符大括号:
${变量}
-
语法: `字符`
-
var img = 'a/b/c/1.jpg' var i = '<img src="'+img+'" />' var i = `<img src="${img}" />` console.log(i);
五、解构赋值
解构赋值:是快速的批量的把对象或数组中的多个值赋值给多个变量
// 对象解构
var obj = {
name: '李白',
age: 26,
isMan: true
}
//解构时: 变量名必须跟属性名一样
var {name, age, isMan} = obj
console.log(name, age, isMan);
// 在解构的时候取别名
// var {name: a, age: b, isMan: c} = obj
// console.log(a, b, c);
// 取别名后原来的名称就不能使用了
// console.log(age);
解构赋值嵌套
var obj = {
name: '刘备',
wife: {
name: '孙尚香',
age: 36
}
}
var {wife} = obj
console.log(wife);
var {name, age} = wife
console.log(name, age);
var {wife: {name, age}} = obj
console.log(name, age);
数组解构
// 数组解构
var arr = [1, 2, 3]
// var a = arr[0]
// var b = arr[1]
// var c = arr[2]
var [a, b, c] = arr
console.log(a, b, c);
var arr = [
1,
2,
[4,5],
3
]
// 麻烦
// console.log(arr[0]);
// var [a,b,c] = arr
// console.log(c);
// var [d,e] = c
// console.log(d,e);
// 数组解构
var [a,b,[d,e]] = arr
// var [_,_,[d,e]] = arr
// console.log(d,e);
六、展开运算符
将对象展开成多个键值对
语法: ...对象 - 将对象展开成多个键值对
var obj = {
name: '刘备',
age: 56,
isMan: true
}
var pbj = {
...obj, // 将obj展开成多个键值对放在pbj中了
wife: {
name: '孙尚香',
age: 26,
isMan: false
}
}
console.log(pbj);
数组展开 - 将数组展开成多个值
语法: ...数组
//求数组最大值
var arr = [1,9,5,15,3,4,64]
var m = Math.max(...arr)
console.log(m);//64
//求前三个数和
var arr = [1,9,5,15,3,4,64]
function fn(a, b, c) {
console.log(a + b + c);
}
fn(...arr)//15
利用展开运算合并数组
<script>
// 之前的写法
let arr = [1,2,3];
let arr1 = [4,5,6].concat(arr);
console.log(arr1);
// 利用展开运算合并
let arr2 = [4,5,6].concat(...arr);
console.log(arr2)
// 再简化
let arr3 = [4,5,6,...arr]
console.log(arr3)
</script>
利用展开运算合并数组
const obj = {
name:"Jack",
age:20,
sex:"男",
}
const obj1 = {
...obj,
wife:{
name:"Rose",
age:18
}
}
console.log(obj1);
七、合并运算符
数组合并
语法: ...数组名 将多个值收集在一个数组中
function fn(...arr) {
console.log(arr);
}
fn(3,3,7)//[3,3,7]
fn(3,3,7,78,57,68,57,785,89)//[3,3,7,78,57,68,57,785,89]
箭头函数中没有arguments,可以使用合并运算符来模拟arguments
var fn = (...arr) => {console.log(arr)};
fn(1,2,3); // [1,2,3]
八、对象的简写
当对象的属性名和对应的值所使用的变量名同名,就可以简写
var obj = {
'name': name,
'age': age,
'sex': sex
}
console.log(obj);
// 简写
var obj = {
name,
age,
sex
}
console.log(obj);
当对象的方法的值是一个匿名函数的时候,方法可以简写
var name = '张三'
var age = 12
var sex = '男'
var obj = {
name,
age,
sex,
ha: function() {
console.log('我哈哈哈');
}
}
console.log(obj);
// 简写
var obj = {
name,
age,
sex,
ha() {
console.log('我哈哈哈');
}
}
console.log(obj);
九、Map
map是es6提供的一种对象类型,用于存储键值对。
跟object不同的地方在于:object的键必须是字符串,如果给的不是字符串,会转成字符串作为对象的键 Map的键,可以是任意数据类型
一、定义map数据:
语法:var m = new Map()
map的结构使用[]
,其中的数据也必须是[]
,在里面的[]
中第一个为键,第二个为值,如果只有键没有值,默认的值为undefined。
var obj = {
sex: '男'
}
var m = new Map([['name', '张三'], [obj, '对象']])
console.log(m);
二、设置键值对:
语法:map.set(键, 值)
如果map中已经有了当前指定的键,后面的值会覆盖前面的值。
var obj = {
sex: '男'
}
var m = new Map([['name', '张三'], [obj, '对象']])
m.set('age', 12)
console.log(m);
三、根据键修改值:
var obj = {
sex: '男'
}
var m = new Map([['name', '张三'], [obj, '对象']])
m.set(obj, '喜欢')
console.log(m);
四、根据键修改值:
语法:map.get(键)
返回获取到的值。如果获取一个map中不存在的键,返回undefined。
var obj = {
sex: '男'
}
var m = new Map([['name', '张三'], [obj, '对象']])
console.log( m.get(obj) );
console.log( m.get('sex') );
五、删除键值对:
语法:map.delete(键)
。
返回布尔值,代表是否删除成功。删除map中不存在的键,返回false。
var obj = {
sex: '男'
}
var m = new Map([['name', '张三'], [obj, '对象']])
var bool1 = m.delete('age')
console.log(bool1); // false
var bool2 = m.delete('name')
console.log(bool2); // true
console.log( m ); //{Object => "对象"}
六、判断map中是否包含某个键值对:
语法:map.has(键)
。
返回布尔值
var obj = {
sex: '男'
}
var m = new Map([['name', '张三'], [obj, '对象']])
var bool1 = m.has('name')
console.log(bool1); // true
七、获取map中键值对的数量:
语法:map.size
返回数字
var m = new Map([['name', '张三'], ['sex', '男'],['age', '36']])
console.log( m.size ); // 3
八、清空map中的数据:
语法:map.clear()
没有返回值
var m = new Map([['name', '张三'], ['sex', '男']])
m.clear()
console.log(m);
九、获取所有键的集合:
语法:map.keys()
返回一个集合,
var m = new Map([['name', '张三'], ['sex', '男']])
console.log( m.keys() );
十、获取所有值的集合:
语法:map.values()
,
返回一个集合,
var m = new Map([['name', '张三'], ['sex', '男']])
console.log(m.values());
十一、遍历map:
语法:map.forEach((item, key) => {})
var m = new Map([['name', '张三'], ['sex', '男'],['skill', '吹牛']])
m.forEach((item, key) => {
console.log(key, item);
})
十、Set
set是es6新增的一种对象类型,用于存储多个键。
新型的数组,数组中不能有重复的元素
一、定义语法:
new Set([多个数据])
。
定义语法使用[]
,如果[]
中重复的数据,会被set去重。
var s = new Set([1,2,3,65,7])
console.log(s);
二、数组去重:
var s = new Set([1,1,1,2,2,1,1,1,1])
console.log(s);//[1,2]
三、给set集合中添加值:
set.add(值)
。
返回添加后的新set。如果添加的数据在set中存在,则添加不进去。
var s = new Set([1,2,3,6,5,4])
console.log(s);
var s1 = s.add(8)
console.log(s1);
四、从set中删除元素:
set.delete(元素)
。
返回布尔值,表示是否删除成功。
var s = new Set([1,2])
var s1 = s.delete(2)
console.log(s1);
console.log(s);
五、查看set中数据的长度:
set.size
返回数字。
var s = new Set([1,2,5,6,7])
console.log(s.size); // 5
六、判断set中是否有某个数据:
set.has(数据)
。
返回布尔值,
var s = new Set([1,2])
var bool = s.has(2)
console.log(bool); // true
var bool1 = s.has(3)
console.log(bool1); // false
七、清空set中的数据:
set.clear()
。
没有返回值
var s = new Set([1,2])
s.clear()
console.log(s);
八、遍历set:
set.forEach(item => {})
var s = new Set([1,2])
s.forEach(item => {
console.log(item); // 1 2
})
十一、for...of for of用来遍历值
-
可以遍历数组,遍历出来的是数组中的每个元素
-
可以遍历字符串,遍历出来的是字符串中的每个字符
-
可以遍历set集合
-
可以遍历Map集合
-
不可以遍历对象
十二、for...in for in用来遍历键
-
可以遍历object类型,只要类型是object就能遍历,但能遍历的只有可遍历的属性
-
可以遍历数组,但遍历出来的下标是字符串,遍历数组的时候会将数组的下标作为键
-
可以遍历字符串,遍历出来的下标也是字符串
-
如果对象的原型中有可遍历的属性,会将原型中的可遍历属性也遍历出来。如果原型中的可遍历属性和对象本身的可遍历属性重名,就只遍历对象本身的属性了。