作用域
全局作用域
window对象,document对象
函数作用域
在函数中定义的变量
块级作用域
if (1) {
let x = 100
}
console.log(x) // 报错
创建10个标签,点击时弹出对应序号
// 错误写法:i是全局作用域,点击事件发生时i已经是10了
let i,a;
for(i=0;i<10;i++){
a = document.createElement('a')
a.innerHTML = i + '<br>'
// 点击时才会执行,此时的i已经为10
a.addEventListener('click', function(e){
e.preventDefault();
alert(i)
})
document.body.appendChild(a)
}
// 正确写法
let a;
for(let i=0;i<10;i++){
a = document.createElement('a')
a.innerHTML = i + '<br>'
// 点击时才会执行,此时的i已经为10
a.addEventListener('click', function(e){
e.preventDefault();
alert(i)
})
document.body.appendChild(a)
}
闭包
自由变量的查找,是在函数定义的地方,向上级作用域查找不是在执行的地方!!!
函数作为返回值
function create() {
let a = 100;
return function() {
console.log(a)
}
}
let fn = create()
let a = 200
fn() // 100
函数作为参数
function print(fn) {
let a = 200
fn()
}
let a = 100
function fn() {
console.log(a)
}
print(fn) // 100
闭包隐藏数据,只提供API
const createCache = () => {
const data = {};
return {
set : (key,val) => {
data[key] = val
},
get : (key) => {
return data[key]
}
}
}
const c = createCache()
c.set('a',100)
console.log(c.get('a')) // 100
console.log(c.data) // undefined
this
- 当做普通函数被调用
- 使用call apply bind
- 作为对象方法调用
- 在class的方法中调用
- 箭头函数
this取什么样的值是在函数执行时决定而不是函数定义时。
function fn() {
console.log(this)
}
fn() // window
fn.call({x:100}) // {x:100}
const fn2 = fn.bind({x:200})
fn2() // {x:200}
在宏任务时this指向window
const Zhangshan = {
name: "Zhangshan",
sayhi() {
console.log(this)
},
waitSayhi() {
setTimeout(function() {
console.log(this)
} )
}
}
Zhangshan.sayhi() // object Zhangshan
Zhangshan.waitSayhi() // window
箭头函数永远指向上一级
const Zhangshan = {
name: "Zhangshan",
sayhi() {
console.log(this)
},
waitSayhi() {
setTimeout(() => {
console.log(this)
} )
}
}
Zhangshan.sayhi() // object Zhangshan
Zhangshan.waitSayhi() // object Zhangshan
手写bind
**bind()
**方法创建一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
Function.prototype.bind() - JavaScript | MDN
// 模拟bind
Function.prototype.bind1 = function() {
// 将参数拆解成数组
const args = Array.prototype.slice.call(arguments);
// 获取 this (数组第一项)
const t = args.shift();
// fn1.bind(...)中的fn1
const self = this;
// 返回一个函数
return function(){
return self.apply(t,args)
}
}
function fn1(a, b, c) {
console.log("this", this);
console.log(a, b, c);
return "this is fn1";
}
const fn2 = fn1.bind1({ x: 100 }, 10, 20, 30);
const res = fn2();
console.log(res);
this { x: 100 }
10 20 30
this is fn1