美文网首页JS
JS 作用域,闭包,箭头函数,普通函数中this指向问题

JS 作用域,闭包,箭头函数,普通函数中this指向问题

作者: 郝同学1208 | 来源:发表于2020-10-29 14:59 被阅读0次

文章序

本文就标题的问题,小结一下本人的观点与想法,如有错误欢迎指正交流.

作用域

在ES6之前只有两个作用域,全局作用域和函数内的局部作用域,for循环内部,对象,{}等内部是没有作用域,使用var定义的变量都是全局变量。在ES6之后,使用let定义的变量只能在大括号{}内部有效,比如循环内部,if内部,包括单独的{}内,是块级元素,{}内部作用域也就称为块级作用域,但是对象的{}内部仍然是没有作用域的.

闭包

闭包,通俗的讲就是可以在外部访问局部变量,通过函数可以根据链式作用域原则取到外层局部作用域的原理,将外层局部作用域的变量通过return返回出去,这样就可以在局部作用域外部使用局部作用域内部的变量了.
优点
可以在外部使用局部作用域的变量.

缺点
使局部作用域变量不能被内存释放,变量就会占用内存,内存消耗大,可能会导致内存泄露.

闭包的使用方法
简单来讲就是在局部作用域内通过函数将需要的局部作用域变量通过return返回出去,代码如下:

var hobby = 'football'
{
    let hobby = 'games';
    window.getHobby = function () {
        return hobby;
    }
}

let hpfHobby = window.getHobby();
console.log(hobby); //football
console.log(hpfHobby);  // games

可以看到,我们通过闭包的方式,在全局环境下拿到了{}内部局部作用域的games,这便是闭包。其实闭包没必要必须通过函数套函数的方式去使用,只是说函数内部创造了一个局部作用域,我们也可以通过其他方式创造局部作用域,比如我这里就是通过单纯的{}创造了局部作用域并通过设置window对象的getHobby方法,在外部拿到了局部作用域的变量.
如果通过函数嵌套的方式去调用的话,代码如下:

var hobby = 'football'
var getHobby = function () {
    let hobby = 'games'
    return function () {
        return hobby;
    };
}

console.log(hobby); //football
console.log(getHobby()());  // games

可以看到,这种写法就跟我们在网上能够找到的关于闭包的主流写法比较一致了,但我是不推荐谈及闭包就是函数套函数,return出去这种说法,这只是一种写法,而不应该一传十十传百好像只有这种写法才对一样.

箭头函数

对象内部函数
ES6新增箭头函数,funName () => {}
箭头函数内部的this指针是指向箭头函数被创建时外部作用域的this指向的对象,而不是调用时指定this指向,普通函数则是根据调用时外部作用域内的this的指向来确定函数内部this的指向。这样看起来比较晦涩难懂,请看如下代码:

var name = 'xx';

let obj1 = {
    name: 'hpf',
    normalGetName: function () {
        console.log('name: ', name);    // name:  xx
        console.log('this.name: ', this.name);  // this.name:  hpf
        console.log(this);  // {name: "hpf", normalGetName: ƒ, arrowGetName: ƒ}
    },
    arrowGetName: () => {
        console.log('name: ', name);    // name:  xx
        console.log('this.name: ', this.name);  // this.name:  xx
        console.log(this);  // Window {window: Window, self: Window, document: document, name: "xx", location: Location, …}
    }
};

obj1.normalGetName();
obj1.arrowGetName();

这里普通函数因为调用时是通过obj1.normalGetName()去调用,所以this是指向obj1,但是箭头函数的this是根据函数定义时的上下文作用域去确定,而定义时因为对象内部是没有作用域的,所以根据链式作用域原则,向上去找到全局window作为作用域.

函数内部函数
当函数外部有作用域时,比如放在函数内,代码和结果如下:

var name = 'xx';
let fun1 = function () {
    let name = 'lmm';
    console.log(this); // Window {window: Window, self: Window, document: document, name: "xx", location: Location, …}
    let normalGetName = function () {
        console.log('name: ', name);    // name:  lmm
        console.log('this.name: ', this.name);  // this.name:  xx
        console.log(this);  // Window {window: Window, self: Window, document: document, name: "xx", location: Location, …}
    }
    let arrowGetName = () => {
        console.log('name: ', name);    // name:  lmm
        console.log('this.name: ', this.name);  // this.name:  xx
        console.log(this);  // Window {window: Window, self: Window, document: document, name: "xx", location: Location, …}
    }
    normalGetName();
    arrowGetName();
};

fun1();

这里很显然,因为函数内部是有作用域的,所以name均取到了函数内部变量,所以显示lmm,this.name因为普通函数是在函数内部调用,箭头函数也是在函数内部定义,所以两者的this指向和函数fun1内部的this指向相同,而又因为fun1是在全局下调用,所以两种函数的this均为全局变量winodw了.

总结

那么我觉得,到现在为止,你应该已经很清晰JS中作用域,闭包,普通函数和箭头函数以及this指向的问题了.

JS中查找变量是按照链式作用域来查找,即先找自己的作用域是否有该变量,如无继续向父作用域找,直到全局作用域window,如果都没有则报错抛出异常.

闭包就是利用在函数内部可以访问到函数外部作用域的变量,通过return的形式返回出去,这样就可以在外部得到局部作用域内部的变量了.

箭头函数的this指向定义时外部作用域内的this指向,普通函数的this指向调用时根据上下文取确认.

相关文章

  • JS 作用域,闭包,箭头函数,普通函数中this指向问题

    文章序 本文就标题的问题,小结一下本人的观点与想法,如有错误欢迎指正交流. 作用域 在ES6之前只有两个作用域,全...

  • JavaScript笔记2

    this、高阶函数、闭包、箭头函数、generator 1. this 函数this指向问题:(1)this和它声...

  • 作用域、作用域链、闭包、面向对象、执行上下文

    作用域 作用域链 函数的提前声明 闭包 JavaScript 闭包与类(原型链)之间的开发方式 构造函数和普通函数...

  • 箭头函数

    v2箭头函数中this指向外部函数,不用转换this!!!解决了局部变量作用域问题!

  • 2.Dart面向对象

    函数 命名可选参数{} 位置可选参数[] 作用域定义:与js的作用域一致,层层向上找。 Dart函数闭包 js函数...

  • JavaScript 函数

    函数函数定义与调用变量作用域全局变量方法高阶函数闭包箭头函数$generator$ 函数 函数定义与调用 定义函数...

  • this

    在箭头函数中,就算是setTimeout()方法中,this指向的也是函数所在作用域的对象 非箭头函数中,this...

  • js 闭包

    一、js 作用域 讲闭包首先就要理解 js 的作用域。再 ES5 中,js 有两种作用域,全局作用域和函数作用域(...

  • js 闭包

    什么是闭包?所谓闭包,就是可以访问函数内部变量的函数。 在JS中,函数内部是一个独立封闭的作用域,函数可以访问全局...

  • JavaScript闭包

    有权访问另一个函数作用域内变量的函数都是闭包 闭包存储局部变量 this指向window 对象冒充改变this指向...

网友评论

    本文标题:JS 作用域,闭包,箭头函数,普通函数中this指向问题

    本文链接:https://www.haomeiwen.com/subject/gsekvktx.html