【javascript知识进阶】this和闭包

来源:互联网 发布:小学英语听力软件 编辑:程序博客网 时间:2024/05/24 11:14

一.javascript中的this

在几种不同的情况下 ,this 指向的各不相同。

全局范围内


console.log(this);

当在全部范围内使用 this,它将会指向全局window对象。

函数调用

        function fun() {            console.log(this);        }        fun();

这里 this 也会指向全局对象。

方法调用

        var test = {            fun:function () {                console.log(this);            }        }        test.fun();

这个例子中,this 指向 test 对象。

调用构造函数

        function con() {            console.log(this);        }        new con();

如果函数倾向于和 new 关键词一块使用,则我们称这个函数是 构造函数。 在函数内部,this 指向新创建的对象。

常见误解

尽管大部分的情况都说的过去,不过第二个规则 被认为是JavaScript语言另一个错误设计的地方,因为它从来就没有实际的用途。

var Foo = {}Foo.method = function() {    function test() {        // this 将会被设置为全局对象    }    test();}

一个常见的误解是 test 中的 this 将会指向 Foo 对象,实际上不是这样子的。

为了在 test 中获取对 Foo 对象的引用,我们需要在 method 函数内部创建一个局部变量指向 Foo 对象。

Foo.method = function() {    var that = this;    function test() {        // 使用 that 来指向 Foo 对象    }    test();}

that 只是我们随意起的名字,不过这个名字被广泛的用来指向外部的 this 对象。

可以运行下面代码来更好的理解:

代码片段1:

var name = "The Window";  var object = {    name : "My Object",    getNameFunc : function(){      return function(){        return this.name;      };    }  };  alert(object.getNameFunc()());

代码片段2:

var name = "The Window";  var object = {    name : "My Object",    getNameFunc : function(){      var that = this;      return function(){        return that.name;      };    }  };  alert(object.getNameFunc()());

二.闭包

作用域

在函数内部用var声明的变量我们可以将它看成是私有变量。

私有变量在函数的外部,或者在它的父级函数中是无法访问到的。

闭包的意义

函数 是 JavaScript 中唯一拥有自身作用域的结构,因此闭包的创建依赖于函数。

function Counter(start) {    var count = start;    return {        increment: function() {            count++;        },        get: function() {            return count;        }    }}var foo = Counter(4);foo.increment();foo.get(); // 5

实际上increment和get两个函数就是两个闭包,闭包的概念可以这样说:闭包就是能够读取其他函数内部变量的函数

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成”定义在一个函数内部的函数”。

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

读取函数内部的变量是闭包存在的一个重要意义:还有一个意义就是让这些变量的值始终保持在内存中

Counter被赋值给了一个全局变量,这导致Counter会始终存在于内存中,它的局部变量count也不会被垃圾回收机制回收。

比如我们像如下这样操作

Counter(4).increment();Counter(4).get();

那么得到的结果是4,因为Counter(4)对象并没有被保存,而是调用后被垃圾回收机制回收掉了。

综上:闭包是阻止垃圾回收器将变量从内存中移除的办法,使得在创建变量的执行环境的外面能访问到该变量。

使用闭包的注意事项

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

以上仅代表个人观点,如果有什么错误的地方欢迎指正!