JavaScript作用域闭包与this
Posted lime2019
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript作用域闭包与this相关的知识,希望对你有一定的参考价值。
javascript作用域、闭包与this
1. JavaScript作用域
作用域代表了变量合法的使用范围。
JavaScript中作用域:
- 全局作用域;
- 函数作用域:函数中声明的变量,会成为函数的局部变量,其作用域是局部的;
- 块级作用域(ES6新增):
自由变量:一个变量如果在当前作用域内没有被定义,但是被使用了。则向上级作用域一层层寻找(链式作用域),直到找到为止,如果到全局作用域还是未找到,报错:xx is not defined
。
2. JavaScript闭包
闭包就是能够读取其他函数内部变量的函数。从本质上而言,闭包就是将函数内部和外部连接在一起的一座桥梁。
闭包的作用:
- 读取函数内部的变量;
- 将函数内部变量的值保持在内存中;
使用闭包注意点:
- 闭包会使函数中变量存储在内存中,内存消耗大,且在IE中可能造成内存泄漏。(可在退出函数之前将不适用的局部变量删除)
- 闭包会在父函数外部,修改父函数内部变量的值。
- 自由变量的查找,在于函数定义的地方,向上级作用域查找,而非在函数执行的地方。
匿名函数、回调函数本身也是一个闭包。
此知识点主要从两个方面考察(抓住自由变量的作用域即可):
- 函数作为返回值;
- 函数作为参数;
3. JavaScript中this
this是 JavaScript 语言的一个关键字。
它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。
this使用场景:
- 作为普通函数;
- 作为对象方法被调用;
- 作为构造函数被使用;
- 使用
call
、apply
、bind
; - 箭头函数;
this
取值是函数执行时确定的,而非函数定义时确定的。
3.1 作为普通函数执行
let x = 1
function test(){
console.log(this.x)
}
test() // 1
此时属于全局调用,this
代表全局对象。
3.2 作为对象方法执行
function test(){
console.log(this.x)
}
let obj = { x:1 }
obj.f = test
obj.f() // 1
此时this
指向上一级对象
3.3 作为构造函数执行
function test(){
this.x = 1
}
let obj = new test()
console.log(obj.x) // 1
此时this
指向新对象。
3.4 apply等方法中执行
apply
、call
、bind
方法是Function
对象自带的三个方法,作用是改变函数的this
指向。
apply
、call
、bind
方法:
- 相同点:第一个参数:
this
要指向的对象,即想要指定的上下文(this
关键字的值),其他参数可以传递字符串、数值、布尔值; apply
与call
作用一样,仅接受参数方式不一样,call(this,arg1,arg2,...)
、apply(this,[arg1,arg2,...])
;bind
返回对应的函数,以便稍后调用,其接受后续参数方式与call
相同;
3.5 箭头函数中执行
箭头函数没有自己的this
值,其所使用的this
来自函数作用域链,即父函数的this
值,因此其不能用作构造函数。箭头函数中this指向是固定的。
let obj = {
x : 1,
test: function(){
setTimeout(() => {
console.log(this)
})
}
}
obj.test()
代码部分参考博文:
ES6 箭头函数中的 this?你可能想多了(翻译)
4. 拓展
4.1 手写bind函数
Function.prototype._bind = function (){
// 将参数解析为数组
const args = Array.prototype.slice.call(arguments)
// 获取 this (即数组第一项)
const t = args.shift()
const self = this
// 返回函数
return function(){
// 执行原函数,并返回结果
return self.apply(t,args)
}
}
Function.prototype._call = function(obj,...args){
try{
window
}catch(error){
window = null
}
obj = obj || window || global
obj._fun_ = this
let res = obj._fun_(...args)
delete obj._fun_
return res
}
以上是关于JavaScript作用域闭包与this的主要内容,如果未能解决你的问题,请参考以下文章
作用域与闭包:this,var,(function () {})