JavaScript学习总结笔记之作用域、闭包、立即执行函数

前言
JavaScript总结笔记篇仅是记载本人学习过程中的一些总结,为了梳理一下知识点,督促自己不断加强学习。文中有些是源自官网,有些是搜集资料,有些是个人观点,难免存在某些知识点疏漏或者是有错误的地方,如果错误之处,希望看到的小伙伴能及时提个醒,避免误导其他小伙伴,也希望我的总结能帮助到正在学或者是将要学习JavaScript的小伙伴们!大家一起努力,早日成为IT界的大神!

一、作用域

1.作用域

[[scope]]:每个JavaScript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供JavaScript引擎存取,[[scope]]就是其中一个。
[[scope]]指的是我们所说的作用域,其中存储了执行期上下文的集合。

2.作用域链:

[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫作用域链。

3.执行期上下文:

当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的, 所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁。

4.查找变量:

从作用域的顶端依此向下查找。

function a () {
            function b () {
                console.log(cc); //执行会报错,b的scope里找不到c
                function c () {
                    var cc = 123;
                }
                c();
            }
            b();
        }
        a();

        /* a defined a.[[scope]] -- > 0 : GO
        a doing   a.[[scope]] -- > 0 : aAo
                                   1 : GO
        b defined b.[[scope]] -- > 0 : aAo
                                   1 : GO
        b doing   b.[[scope]] -->  0 : bAO
                                   1 : aAo
                                   2 : GO
        c defined c.[[scope]] -- > 0 : bAo
                                   1 : aAo
                                   2 : GO
        c doing   c.[[scope]] -->  0 : cAO
                                   1 : bAo
                                   2 : aAo
                                   3 : GO */
        function a () {
            function b () {
                var bbb = 234;
                console.log(aaa);
            }
            var aaa = 123;
            return b;
        }
        var glob = 100;
        var demo = a();
        demo(); // 123

二、闭包

(一)定义

当内部函数保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。

(二)作用
1.实现公有变量 函数累加器
function add() {
var count = 0;
function demo() {
count ++;
console.log(count);
}
return demo;
}

var counter = add();
counter();
counter();
2.可以做缓存
function eater() {
var food = "";
var obj = {
eat : function () {
console.log("i am eating " + food );
food = "";
},
push : function (myFood) {
food = myFood;
}
}
return obj;
}

var eater1 = eater();
eater.push("banana");
eater.eat();
3.可以实现封装,属性私有化
4.模块化开发,防止污染全局变量
5.Test
        function test () {
            var num = 100;
            function a () {
                num ++;
                console.log(num);
            }
            function b () {
                num --;
                console.log(num);
            }
            return [a,b];
        }

        var myArray = test();
        myArray[0](); // 101
        myArray[1](); // 100

        function Person (name, age, sex) {
            var a = 0;
            this.name = name;
            this.age = age;
            this.sex = sex;
            function sss () {
                a ++;
                document.write(a);
            }
            this.say = sss; 
        }

        var oPerson = new Person();
        oPerson.say(); // 1  
        /* 
            sss函数体被保存到外部,形成闭包,
            拿到Person函数的执行期上下文,所以每次执行a + 1; 
        */
        oPerson.say(); // 2
        var oPerson1 = new Person();
        oPerson1.say(); // 1

三、立即执行函数

(一)定义
1.此类函数没有声明,在一次执行过后即释放,适合做初始化工作。

Ps:
只有表达式才能被执行符号执行

能被执行符号执行的表达式,函数名称都会被忽略(undefined)

//执行test,一开始结果为a。再执行为undefined
+function test () {
console.log(‘a’);
}();

(二)形式
1.(function (){

}())–》w3c建议

2.(function (){

})()

function test() {
var arr = [];
for(var i = 0; i < 10; i ++) {
arr[i] = funtion () {
document.write(i + "");
}
}
return arr;
}

var myArr = test();
for(var j = 0; j < 10; j++) {
myArr[j]();
}
//打印结果10个10
解决方法:立即执行函数    非常重要!!!


function test() {
var arr = [];
for(var i = 0; i < 10; i ++) {

(function (j){
arr[j] = function (){
document.write(j + " ");
}
}(i))
}
return arr;
}

var myArr = test();
for(var j = 0; j < 10; j++) {
myArr[j]();
}

/* 
            <ul>
                <li>a</li>
                <li>a</li>
                <li>a</li>
                <li>a</li>
            </ul>

            使用原生js,addEventListener,给每个li元素绑定一个click事件,
            并输出他们的顺序。

            主要考察,利用立即执行函数解决闭包问题。
         */
        function test() {
            var liCollections = document.getElementsByTagName("li");
            for (var i = 0; i < liCollections.length; i++) {
                (function (j) {
                    liCollections[j].addEventListener("click", function () {
                        console.log(j);
                    })
                }(i))
            }
        }

        test();
       

文章持续更新中,敬请关注,谢谢阅读!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值