发表于: 2020-02-20 22:37:16

1 1186


今天完成的事情:今天学习了jd的函数调用,js的闭包
明天计划的事情:继续选项js的内容
遇到的问题:熟练度不足,没想出什么实际的使用方式,需要实际应用
收获:今天试了js函数的各种调用方式

JavaScript 函数有 4 种调用方式。

每种方式的不同在于 this 的初始化。

作为一个函数调用,比如

<p>
    全局函数 (myFunction) 返回参数参数相乘的结果:
</p>
<p id="demo"></p>
<script>
    function myFunction(ab) {
        return a * b;
    }
    document.getElementById("demo").innerHTML = myFunction(102); 
</script>

运行结果

JavaScript 函数有 4 种调用方式。

每以上函数不属于任何对象。但是在 JavaScript 中它始终是默认的全局对象。

在 HTML 中默认的全局对象是 HTML 页面本身,所以函数是属于 HTML 页面。

在浏览器中的页面对象是浏览器窗口(window 对象)。以上函数会自动变为 window 对象的函数。

myFunction() 和 window.myFunction() 是一样的:方式的不同在于 this 的初始化。例如

<p>全局函数 myFunction() 会自动成为 window 对象的方法。</p>
<p>myFunction() 类似于 window.myFunction()。</p>
<p id="demo"></p>
<script>
    function myFunction(ab) {
        return a * b;
    }
    document.getElementById("demo").innerHTML = window.myFunction(102); 
</script>

运行结果

作为全局对象

当函数没有被自身的对象调用时 this 的值就会变成全局对象。

在 web 浏览器中全局对象是浏览器窗口(window 对象)。

该实例返回 this 的值是 window 对象

<p>在 HTML 中 <b>this</b> 的值, 在全局函数是一个 window 对象。</p>
<p id="demo"></p>
<script>
    function myFunction() {
        return this;
    }
    document.getElementById("demo").innerHTML = myFunction(); 
</script>

运行结果

函数作为方法调用

在 JavaScript 中你可以将函数定义为对象的方法。

<p>myObject.fullName() 返回 John Doe:</p>
<p id="demo"></p>
<script>
    var myObject = {
        firstName: "John",
        lastName: "Doe",
        fullName: function () {
            return this.firstName + " " + this.lastName;
        }
    }
    document.getElementById("demo").innerHTML = myObject.fullName(); 
</script>

运行结果

fullName 方法是一个函数。函数属于对象。 myObject 是函数的所有者。

this对象,拥有 JavaScript 代码。实例中 this 的值为 myObject 对象。

测试以下!修改 fullName 方法并返回 this 值:比如

<p>在一个对象方法中 ,<b>this</b> 的值是对象本身。</p>
<p id="demo"></p>
<script>
    var myObject = {
        firstName: "John",
        lastName: "Doe",
        fullName: function () {
            return this;
        }
    }
    document.getElementById("demo").innerHTML = myObject.fullName();
</script>

运行结果

使用构造函数调用函数

如果函数调用前使用了 new 关键字, 则是调用了构造函数。

这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象:

比如

<p>该实例中, myFunction 是函数构造函数:</p>
<p id="demo"></p>
<script>
    function myFunction(arg1arg2) {
        this.firstName = arg1;
        this.lastName = arg2;
    }
    var x = new myFunction("John""Doe")
    document.getElementById("demo").innerHTML = x.firstName
</script>

运行结果

作为函数方法调用函数

在 JavaScript 中, 函数是对象。JavaScript 函数有它的属性和方法。

call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。

<p id="demo"></p>

<script>
    var myObject;
    function myFunction(ab) {
        return a * b;
    }
    myObject = myFunction.call(myObject102);    // 返回 20
    document.getElementById("demo").innerHTML = myObject
</script>

运行结果

关于js的闭包

JavaScript 变量可以是局部变量或全局变量。

私有变量可以用到闭包。

全局变量

函数可以访问由函数内部定义的变量,如:

<p>函数可以访问函数内部定义的变量:</p>
<button type="button" onclick="myFunction()">点我</button>
<p id="demo"></p>
<script>
    function myFunction() {
        var a = 4;
        document.getElementById("demo").innerHTML = a * a;
    } 
</script>

运行结果

点击之后

函数也可以访问函数外部定义的变量,如:

<p>函数可以访问定义在函数外的变量:</p>
<button type="button" onclick="myFunction()">点我</button>
<p id="demo"></p>
<script>
    var a = 4;
    function myFunction() {
        document.getElementById("demo").innerHTML = a * a;
    } 
</script>

运行结果,同样的

变量生命周期

全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。

而在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用

计数器困境

设想下如果你想统计一些数值,且该计数器在所有函数中都是可用的。

你可以使用全局变量,函数设置计数器递增:比如

<p>全局变量计数。</p>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
    var counter = 0;
    function add() {
        return counter += 1;
    }
    function myFunction() {
        document.getElementById("demo").innerHTML = add();
    }
</script>

运行结果

点击

可一点击累计

计数器数值在执行 add() 函数时发生变化。

但问题来了,页面上的任何脚本都能改变计数器,即便没有调用 add() 函数。

如果我在函数内声明计数器,如果没有调用函数将无法修改计数器的值:

<p>局部变量计数。</p>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
    function add() {
        var counter = 0;
        return counter += 1;
    }
    function myFunction() {
        document.getElementById("demo").innerHTML = add();
    }
</script>

运行结果

一直都是一

JavaScript 内嵌函数

所有函数都能访问全局变量。  

实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。

JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。

该实例中,内嵌函数 plus() 可以访问父函数的 counter 变量:

<p>局部变量计数。</p>
<p id="demo">0</p>
<script>
    document.getElementById("demo").innerHTML = add();
    function add() {
        var counter = 0;
        function plus() { counter += 1; }
        plus();
        return counter;
    }
</script>

运行结果

如果我们能在外部访问 plus() 函数,这样就能解决计数器的困境。

我们同样需要确保 counter = 0 只执行一次。

我们需要闭包。

<p>局部变量计数。</p>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
    var add = (function () {
        var counter = 0;
        return function () { return counter += 1; }
    })();
    function myFunction() {
        document.getElementById("demo").innerHTML = add();
    }
</script>

运行结果

可以正常增加了

这是闭包的用处,剩下的明天再看



返回列表 返回列表
评论

    分享到