javascript构造函数小记

1 function outer(){
2   function inner(){}
3   return inner;
4 }
5 
6 var a=outer();
7 var b=outer();
8 var c=new outer();
9 var d=new outer();

问题:这些的值都是什么?

a==b;
a.constructor==b.constructor;
b.constructor==c.constructor;
a.prototype.constructor;
b.prototype.constructor==c.prototype.constructor;

答案: false;true;true;function inner(){};false; 

解析:知识点为函数调用的返回值,new 构造器的实例对象,原型,construcor构造器指向等。

  • var a=outer();var b=outer(); 调用了outer函数并执行,outer函数返回了对inner函数的引用,这个引用保存在a,b变量中。误区在于我曾经以为返回的是同一个引用以为a,b指向内存中的同一个inner。实际是两个不同的引用,虽然他们的内容都相同,可以这么理解,a保存的引用指向复制了一份inner的内存区域,b保存的引用指向另一份复制inner的内存区域
  • 由于调用执行outer后返回的是一个对于函数的引用,我们知道所有函数的constructor属性都指向function Function() { [native code] }这个总的构造器,所以a.constructor==b.constructor;指向的就是同一个Function,当然为true啦。
  • var c=new outer();var d=new outer();看似是用new构造函数形式返回实例对象,而执行构造函数outer的时候执行有return语句,这似乎不多见,常见的返回值就是此构造函数的实例化对象。但是js大法牛逼啊,js的构造函数可以有返回值也可以没有(分为三种情况:没有返回值则返回实例化对象;若有返回值检查其返回值是否有引用类型,如果为非引用类型比如基本类型时就无视,还是返回其实例化对象;若返回值为引用类型,比如return {}对象,比如return fun函数等,则实际返回值为这个引用类型。(参考自:http://www.cnblogs.com/xxcanghai/p/5189353.html#3361101)。这里c,d均保存返回的引用,指向自己inner函数对象,所以c.constructor也是指向Function的,b.constructor==c.constructor;就为true啦。
  • a现在指向内存区域中某块地方,类型是函数,函数内容和inner函数内容一样,既然是函数那这个函数就有自己的prototype原型属性,而a.prototype原型属性又有constructor属性,该constructor属性又指向拥有prototype的函数,就是这里a指向的函数。
  • b同理,b.prototype.constructor指向b指向的函数,c.prototype.constructor;c本身也指向函数,所以也同理c.prototype.constructor也指向c指向的函数。

虽然看起来constructor看起来一样,其实是不一样的!

关于作用域的一点说明:a,b,c,d都有自己的作用域链,然后延伸到全局环境的。

posted @ 2016-02-16 17:29  venoral  阅读(432)  评论(0编辑  收藏  举报