资讯专栏INFORMATION COLUMN

【JS基础】作用域和闭包

SolomonXie / 2309人阅读

摘要:变量提升的理解语言的执行规则先定义,后执行变量定义函数声明就属于定义代码的范畴注意函数声明和函数表达式的区别说明几种不同的使用场景要在执行时才能确认值,定义时无法确认全局环境下的对象方法中的构造函数中的事件函数中的触发当前事件的对象中的创建

变量提升的理解
js语言的执行规则:先定义,后执行
变量定义、函数声明就属于定义代码的范畴(注意“函数声明”和“函数表达式”的区别)
说明this几种不同的使用场景

this 要在执行时才能确认值,定义时无法确认

var a = {
    name: "A",
    fn: function () {
        console.log(this.name);
    }
};
a.fn(); // this === a
a.fn.call({name: "B"}); // this === {name: "B"}
var fn1 = a.fn;
fn1(); // this === window

全局环境下的this

function fn() {
    console.log(this); // this === window
}
fn();

对象方法中的this

var obj = {
    name: "A",
    printName: function () {
        console.log(this.name); // this === obj
    }
};
obj.printName();

构造函数中的this

function Foo(name) {
    this.name = name; // this === f
}
var f = new Foo("can");

事件函数中的this

document.getElementById("div1").onclick = function () {
    console.log(this); // this === 
div1
触发当前事件的Element对象 };

call apply bind 中的this

function fn1(name, age) {
    console.log(name, age);
    console.log(this); // this === {x:100}
}

fn1.call({x: 100}, "can", 22);
fn1.apply({x: 100}, ["can", 22]);

var fn2 = function (name, age) {
    console.log(name, age);
    console.log(this); // this === {y:200}
}.bind({y: 200});
fn2("can", 22);
创建10个a标签,点击的时候弹出来对应的序号
for (var i = 0; i < 10; i++) {
    (function (i) {
        // 函数作用域
        var a = document.createElement("a");
        a.innerHTML = i + "
"; a.addEventListener("click", function (e) { e.preventDefault(); alert(i); // i 是自由变量,去父作用域寻找 }); document.body.appendChild(a); })(i); }
作用域

ES5中,无块级作用域

if (true) {
    var name = "can";
}
console.log(name); // "can"

函数和全局作用域

var b = 1;
function fn3() {
    var b = 2;
    console.log("fn", b); // 2
}
console.log("global", b); // 1
fn3();

自由变量

var a = 100;
function fn4() {
    var b = 200;
    // 当前作用域没有定义的变量,即“自由变量”
    console.log(a); // 100  a 是自由变量,去父作用域寻找
    console.log(b); // 200
}
fn4();
一个函数的父级作用域,是它定义时的父级作用域,而不是执行时

作用域链,即自由变量的查找

var a = 100;
function fn5() {
    var b = 200;
    function fn6() {
        var c = 300;
        console.log(a); // 100  a 是自由变量,去父作用域寻找
        console.log(b); // 200  b 是自由变量,去父作用域寻找
        console.log(c); // 300
    }
    fn6();
}
fn5();
闭包的使用场景

1.函数作为返回值

function fn1() {
    var a = 100;
    // 返回一个函数(函数作为返回值)
    return function () {
        console.log(a); // a是自由变量,去父作用域寻找
    }
}

// f1 得到一个函数
var f1 = fn1();
var a = 200;
f1(); // 100

2.函数作为参数传递

function fn1() {
    var a = 100;
    // 返回一个函数(函数作为返回值)
    return function () {
        console.log(a); // a是自由变量,去父作用域寻找
    }
}

// f1 得到一个函数
var f1 = fn1();

function fn2(fn) {
    var a = 200;
    fn();
}

fn2(f1); // 100
实际开发中闭包的应用

闭包实际应用中主要用于封装变量,收敛权限

function isFirstLoad() {
    var list = [];
    return function (id) {
        if (list.indexOf(id) > -1) {
            return false;
        } else {
            list.push(id);
            return true;
        }
    }
}
// 在 isFirstLoad 函数外面,不可能修改到 list 的值
var firstLoad = isFirstLoad();
firstLoad(10); // true
firstLoad(10); // false
firstLoad(20); // true

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100173.html

相关文章

  • javascript作用域和闭包之我见

    摘要:查询是在作用域链中,一级级的往上查找该变量的引用。作用域和作用域链作用域的概念,应该两张图几句话就能解释吧。这个建筑代表程序中的嵌套作用域链。一层嵌一层的作用域形成了作用域链,变量在作用域链中的函数内得到了自己的定义。 javascript作用域和闭包之我见 看了《你不知道的JavaScript(上卷)》的第一部分——作用域和闭包,感受颇深,遂写一篇读书笔记加深印象。路过的大牛欢迎指点...

    SoapEye 评论0 收藏0
  • Js基础知识(三) - 作用域与闭包

    摘要:是词法作用域工作模式。使用可以将变量绑定在所在的任意作用域中通常是内部,也就是说为其声明的变量隐式的劫持了所在的块级作用域。 作用域与闭包 如何用js创建10个button标签,点击每个按钮时打印按钮对应的序号? 看到上述问题,如果你能看出来这个问题实质上是考对作用域的理解,那么恭喜你,这篇文章你可以不用看了,说明你对作用域已经理解的很透彻了,但是如果你看不出来这是一道考作用域的题目,...

    lemanli 评论0 收藏0
  • Js基础知识(三) - 作用域与闭包

    摘要:是词法作用域工作模式。使用可以将变量绑定在所在的任意作用域中通常是内部,也就是说为其声明的变量隐式的劫持了所在的块级作用域。 作用域与闭包 如何用js创建10个button标签,点击每个按钮时打印按钮对应的序号? 看到上述问题,如果你能看出来这个问题实质上是考对作用域的理解,那么恭喜你,这篇文章你可以不用看了,说明你对作用域已经理解的很透彻了,但是如果你看不出来这是一道考作用域的题目,...

    XFLY 评论0 收藏0
  • Js基础知识(三) - 作用域与闭包

    摘要:是词法作用域工作模式。使用可以将变量绑定在所在的任意作用域中通常是内部,也就是说为其声明的变量隐式的劫持了所在的块级作用域。 作用域与闭包 如何用js创建10个button标签,点击每个按钮时打印按钮对应的序号? 看到上述问题,如果你能看出来这个问题实质上是考对作用域的理解,那么恭喜你,这篇文章你可以不用看了,说明你对作用域已经理解的很透彻了,但是如果你看不出来这是一道考作用域的题目,...

    tanglijun 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<