閉包
閉包產生的條件:函式嵌套函式,內部函式訪問外部函式的變數/函式
閉包產生有兩種表現:
- 函式作為引數被傳遞
- 函式作為回傳值被回傳
函式中的自由變數,取決于函式定義的地方,跟執行的地方沒關系
// 函式作為引數被傳遞
function fn() {
const a = 10
return function() {
console.log(a); // 10
}
}
const f = fn()
const a = 20
f()
// 函式作為引數被傳遞
function fn() {
const a = 20
f()
}
const a = 10
function f() {
console.log(a); // 10
}
fn(f)
閉包的作用
- 函式內部變數在函式執行完后,仍然存活在記憶體中(延長區域變數的生命周期)
- 讓函式外部可以操作(讀寫)到函式內部的資料(變數/函式)
閉包缺點
函式執行后,函式內的區域變數沒有釋放,占用記憶體會變長,容易造成記憶體泄漏,
this指向
談到閉包不得不說this指向問題是在執行時確認的,定義時無法確認
普通函式、
定時器、
物件方法、
call apply bind、
class、
箭頭函式
普通函式
function fn() {
console.log(this); // Window
}
fn()
物件方法
let obj = {
name:'zbt',
run: function() {
console.log(this); // obj, this指向方法呼叫者
}
}
obj.run()
call apply bind
function fn() {
let arg = arguments // arguments是一個偽元素,不具有陣列方法
let arr = [4,5,6]
// 借用陣列
// Array.prototype.push.call(arg,4)
// Array.prototype.push.call(arg,arr)
// Array.prototype.push.apply(arg,arr)
// Array.prototype.push.bind(arg,4)()
console.log(arg);
}
fn(1,2,3)
Array.prototype.push.call(arg,arr) 輸出結果:

Array.prototype.push.apply(arg,arr) 輸出結果:

Array.prototype.push.bind(arg,4)() 輸出結果:

call() /apply() /bind() 都可以改變this指向,指向第一個引數
call:引數是單個使用的 引數是一個引數串列,
apply:引數是一個集合時使用,引數是一個陣列
bind:使用bind會改變this,不會改變資料,需要在呼叫的地方加一個括號
calss語法糖
class Person {
constructor(name,age) {
this.name = name
this.age = age
}
run() {
console.log(this); // this指向p實體物件
}
}
let p = new Person('小明',19)
p.run()
箭頭函式
箭頭函式的this是在定義時確定的
this時刻指向父級的上下物件,并且不可以被 call()/apply()/bind()修改
var name = '小明'
let obj = {
name:'小紅',
run:()=>{
console.log(this.name);
}
}
let fn = {name:'小小'}
obj.run() // 小明
obj.run.call(fn) // 小明
obj.run.apply(fn) // 小明
定時器
let obj = {
name:'小小',
sun:function() {
// 定時器是Window定義的
setTimeout(function(){
console.log(this); // Window
},1000)
}
}
obj.sun()
裝換成箭頭函式
// 箭頭函式this,定義時確定的
let obj = {
name:'小小',
sun:function() {
setTimeout(()=>{
console.log(this); // obj
},1000)
}
}
obj.sun()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/413470.html
標籤:其他
