JS 闭包与作用域

2021/3/18 18:58:32admin0 阅读0 评论

<h3>函数自执行</h3>

<pre class=“language-html line-numbers”><code class=“language-html”>
<!DOCTYPE html>
<html lang=“en”>
<head>
<meta charset=“UTF-8”>
<title>Document</title>
<style>
.box{
width: 100px;
height: 100px;
background: red;
}

    .box2{
        width: 100px;
        height: 100px;
        background: yellow;
    }
&lt;/style&gt;

</head>
<body>
<div class=“box” title=“123”></div>
<div class=“box2”></div>
<script>

	var box = document.querySelector('.box');
	box.onclick = function(){
	    alert(box.title)
	}
	
	var box = document.querySelector('.box2');
	//鼠标移入
	box.onclick= function(){
	    alert(2);
	}
	
&lt;/script&gt;

</body>
</html>
</code></pre>
工作中,也许两个事件出自不同的人,这时,就有可能出现重名,这避免的方法就是都使用作用域。
<pre class=“language-javascript line-numbers”><code class=“language-javascript”>
// 作用域
// 在函数内部,它作用域的概念就是局部的函数它只能调用局部作用域的变量
// 这时就可以把函数封装起来自执行 - 避免命名冲突

(function(){})();

// 这样这个var box就是局部变量了,就算外面有相同的命名,也不会影响到当前代码本身的逻辑
(function(){
var box = document.querySelector(‘.box’);
box.onclick = function(){
alert(box.title)
}

})();

(function(){
var box = document.querySelector(‘.box2’);
//鼠标移入
box.onclick= function(){
alert(2);
}

})();

// 原生js逻辑基本上就是采用这种方式去分离代码业务的
</code></pre>

<h3>闭包题思考</h3>

<pre class=“language-javascript line-numbers”><code class=“language-javascript”>
function fn(){
var n = 0;
function fn2(){
n++;

            return n;
        }
        return fn2; //不加括号的函数返回的只是函数体
    }

    var fn3 = fn(); // 这里调用时相当于声明了一个 n 等于 0
    var num = fn3(); // 第二次执行时相当于 n++ 了,就等于 1 ,n++不是变量,所以调用时改变的是 var n的值
    var num2 = fn3();
    var num3 = fn3();

    console.log(num3) //3

</code></pre>

<pre class=“language-javascript line-numbers”><code class=“language-javascript”>
function fn(){
var n = 0;
function fn2(){
n++;

            return n;
        }
        return fn2; //不加括号的函数返回的只是函数体
    }

    var fn3 = fn();
    var num = fn3();
    var num2 = fn3();
    var num3 = fn3();
    console.log(num3) //3


    var fn4 = fn(); // 这里调用时相当于又声明了一个新的 n 等于 0 ,影响的是fn4 这个函数
    var num4 = fn4();
    console.log(num4) //1

</code></pre>

<h3>return</h3>

<pre class=“language-javascript line-numbers”><code class=“language-javascript”>
function fn(){

        function a(){
            alert(1)

            // return 'lalala'; // 如果加了return且写了值,才不会返回undefined
        };
        
        // 局部函数在外部可以调用的原因是它加了return
        return a;
    }

    var n = fn(); // 把函数体存起来

    // 既然n是函数 就可以 n() 去执行
    console.log(n()) // 执行结果,弹出 1 ,然后打印 undefined ,打印undefined的原因是a这个函数里没有return,没return默认就返回undefined

</code></pre>

<pre class=“language-javascript line-numbers”><code class=“language-javascript”>
function a(n1){
var b = 6;
function c(n2){
return n2*2;
}
return [c,arguments[0]-c(b)+b];
}

    var n  = a(5)[1];

    console.log(n)

// ----------------------------

    function a(n1){  // 2.这时a(n1)就是a(5)
        var b = 6;
        function c(n2){
            return n2*2;
        }
        return [c,arguments[0]-c(b)+b]; //3. 这里返回的是一个数组,这时就看拿的是第几个数,a(5)[1] 可知要的是第一个,第0个的c不用去管他
        // arguments[0]-c(b)+b
        // arguments[0] 它是 函数a(n1)的不定参列表,第0个就是 n1 ,n1 为 5 
        // c(b) 子函数调用父函数变量 这时c(n2)的 n2 就是 6 ,里面 return n2*2就是return 6*2, 这时的c(b)就是 12
        // b 就是父函数里 var b 的值 6 
        // 5-12+6;
    }

    var n  = a(5)[1];  // 1.遇到函数,首先看在什么地方调用

    console.log(n) // -1

</code></pre>

<pre class=“language-javascript line-numbers”><code class=“language-javascript”>
function a(n1){
var b = 6; //3. 这时,因为函数里也声明了b,这时返回出来的值同时影响了父级的局部变量 也把它变成了 b =12
function c(n2){
b = n22; // 1. 62等于12后,赋值给了b
return b; // 2. 这里返回的 b 就是 12
}

        // arguments[0] = 5;
        // c(6) = 12
        // b = 12
        return [c,arguments[0]-c(b)+b]; //5-12+12;
    }

    var n  = a(5)[1];

    console.log(n)  // 5

</code></pre>