阅读 199

对js闭包、作用域、原型的理解

1)闭包

理解闭包首先要理解,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

2)作用域

简单的说,作用域是针对变量的,比如我们创建一个函数a1,函数里面又包了一个子函数a2。此时就存在三个作用域:

全局作用域-a1作用域-a2作用域;即全局作用域包含了a1的作用域,a2的作用域包含了a1的作用域。

当a1在查找变量的时候会先从自身的作用域区查找,找不到再到上一级a2的作用域查找,如果还没找到就到全局作用域区查找,这样就形成了一个作用域链。

3)原型

javascript中一切皆对象,每个对象都有一个_proto_ 属性(由浏览器自动创建),该属性指向它原型。当一个对象在查找一个属性的时,自身没有就会根据_proto_向它的原型进行查找,如果都没有,直到查到Object.prototype._proto_为null,这样也就形成了原型链。

那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.prototype

console.info(foo.__proto__ === Foo.prototype)       //true

console.info(foo.prototype)                        //undefine ;只有构造函数才有prototype属性
console.info(foo.constructor);//function Foo(){……} ;其实foo并没有constructor属性,他只是继承了原型中的consturctor属性

console.info(foo.constructor === Foo.prototype.constructor)           //true
复制代码

new操作中发生了什么?

• 以构造器的prototype属性为原型,创建一个空对象,将它的引用赋给 this,继承函数的原型

• 通过 this 将属性和方法添加至这个对象

• 最后返回 this 指向的新对象,也就是实例(如果没有手动返回其他的对象,返回手动return的对象)

文章分类
前端
文章标签