js闭包和作用域(js中闭包的优缺点)
导语:对js中闭包,作用域,原型的理解
前几天,和朋友聊天,聊到一些js的基础的时候,有一种‘好像知道,好像又不不知道怎么讲的感觉’。。。于是捡起书,自己理一理,欢迎拍砖。
闭包
理解闭包首先要理解,js垃圾回收机制,也就是当一个函数被执行完后,其作用域会被收回,如果形成了闭包,执行完后其作用域就不会被收回。
如果某个函数被他的父函数之外的一个变量引用,就会形成闭包
闭包的作用,就是保存自己私有的变量,通过提供的接口(方法)给外部使用,但外部不能直接访问该变量。
例子(使用闭包):
var test=(function{ var a=0; return function{ ++a console.info(a); } }) test;// 1 test;// 2 test;// 3
例子(不使用闭包):
var test=function{ var a=0; ++a console.info(a); } test;// 1 test;// 1 test;// 1
上面例子形成了闭包,函数第一次执行完后,作用域没有被回收机制销毁,所以变量a也被保存下来了,每次调用test,执行后a都会自加1。如果没有形成闭包,每次调用test,执行后a都会销毁染后重新创建,执行结果都为1.
作用域
简单的说,作用域是针对变量的,比如我们创建一个函数a1,函数里面又包了一个子函数a2。此时就存在三个作用域:
全局作用域-a1作用域-a2作用域;即全局作用域包含了a1的作用域,a2的作用域包含了a1的作用域。
当a1在查找变量的时候会先从自身的作用域区查找,找不到再到上一级a2的作用域查找,如果还没找到就到全局作用域区查找,这样就形成了一个作用域链。
原型
javascript中一切皆对象,每个对象都有一个__proto_ 属性(由浏览器自动创建),该属性指向它原型。当一个对象在查找一个属性的时,自身没有就会根据__proto__ 向它的原型进行查找,如果都没有,直到查到Object.prototype._proto_为nul,这样也就形成了原型链。
那prototype又是什么?!我们知道可以通过构造函数来创造一个类,prototype的作用就是,让类的属性可以被继承。所以只有构造函数才会有prototype这个属性。
下面直接用代码来验证下:
function Foo{ this.name='xiaoming'}var foo=new Foo;foo.age="22"console.info(foo.name)//xiaoming ; foo集成了Foo的name属性console.info(foo.__proto__)//object ; 指向了她的原型Foo.prototypeconsole.info(foo.__proto__ === Foo.prototype)//trueconsole.info(foo.prototype)//undefine ; 只有构造函数才有prototype属性console.info(foo.constructor)//function Foo{……} ; 其实foo并没有constructor属性,他只是继承了原型中的consturctor属性console.info(foo.constructor === Foo.prototype.constructor)//true
本文内容由快快网络小迪创作整理编辑!