函数的四种调用模式
其中3种无法修改
普通函数调用:函数名()》》this指向window
function fn() {
console.log(this);
}
fn()
对象方法调用:对象名,方法名()》》this指向对象
let obj = {
name: '豆豆',
age: 40,
eat: fn
}
obj.eat()
构造函数调用:new函数名()》》this指向new创建的实例对象
function fn() {
console.log(this);
}
new fn()
优先判断new函数有new关键字,则指向new创建的对象.否则不是window就是对象
然后看调用:函数名()还是对象名()
可以修改this的指向:上下文模式
call():函数名.call(this修改后的指向,实参1,实参2.。。。)适用于只有一个参数的函数。可用于伪数组排序,检测数据类型。
function fn(a, b) {
console.log(this)
console.log(a + b)
}
fn.call({
name: '王五'
}, 78, 22)
apply()函数名.apply(this修改后的指向,伪数组或者数组)适用于有多个参数的函数,可用于伪数组转真数组,求数组的最大值。
let obj = {
0: 20,
1: 40,
2: 50,
3: 70,
length: 4
}
let newaArr = []
newaArr.push.apply(newaArr, obj)
// 假数组转真数组
let arr = Array.from(obj)
console.log(arr);
bind():函数名.bind(this修改后的指向,实参1,实参2....),比较特殊不会立刻执行函数,而是返回一个修改指定后的新函数,用于回调函数。而且实参一经修改不可改变。用于回调函数(定时器,事件处理函数)
递归函数
大致意识就是:一个函数自己调用自己。注意点(一定要有结束条件,否则会导致死循环)
应用的地方(浅拷贝与深拷贝,渲染dom树)
之前的方法:
let obj = {
name: '小顾',
age: 30,
friend: {
name: '朋友',
sex: '男'
}
}
// 先把js转为json
let json = JSON.stringify(obj)
// 然后再把json转换成js,这个过程就完成了深度拷贝
let js = JSON.parse(json)
js.name = '干饭'
console.log(obj, js)
// 简写
// let newObj = JSON.parse(JSON.stringify(obj))
现在的:
<script>
// 如果obj[key]是引用类型(数组.对象),则不能拷贝地址
let obj = {
name: '小顾',
age: 30,
friend: {
name: '朋友',
sex: '男'
}
}
function kaobei(newObj, obj) {
for (let key in obj) {
// 判断是不是数组类型
if (obj[key] instanceof Array) {
// 声明一个空数组,然后继续拷贝数组里面的数据
newObj[key] = []
kaobei(newObj[key], obj[key])
} else if (obj[key] instanceof Object) {
newObj[key] = {}
kaobei(newObj[key], obj[key])
} else {
newObj[key] = obj[key]
}
}
}
let newObj = {}
kaobei(newObj, obj)
newObj.age = '111'
console.log(newObj, obj);
</script>
闭包函数
闭包函数大意为:一个可以访问其他函数内部变量的函数
<script>
// 闭包:一个可以访问其他函数内部变量的函数
function fn() {
let name = 2
function fn1() {
console.log(name)
}
fn1()
}
fn()
</script>