前面有转载玉伯的 一篇关于 new functionName 猜想的blog

  new Fn() 的实际构造过程可以等价为以下伪代码:

var o = {__proto__: Fn.prototype};
Fn.apply(o);
return o;

但是有这么一个问题

因为 整个 blog 的论点都是建立在,使用一个规规矩矩的构造函数的情况下。

 

你知道的,js是弱类型语言,对于任何数据,都缺乏强制的类型检测,那么,如果

function Dog(name) {
    this.name = name;
    Dog.prototype = {
        shout: function() { alert("I am " + this.name); }
    };
}
这个构造函数里,如果编写以个不这么规矩的构造函数呢, 加一个return 语句
function Dog(name) {
    this.name = name;
    Dog.prototype = {
        shout: function() { alert("I am " + this.name); }
    };
return {name:"dog2"} }

那么 var dog = new Dog("dog1");

console.log( dog.name ) //dog2
这个,貌似 玉伯 的猜想,有点问题,

然后我再修改一下,把return 的值修改为

function Dog(name) {
    this.name = name;
    Dog.prototype = {
        shout: function() { alert("I am " + this.name); }
    };
return "dog3" }
var dog = new Dog("dog1");
console.log(dog.name) //dog1
console.log(dog == "dog3") // false
这个..... 这个时候,整个构造过程又正常了,


我的理解:

new 运算 和引擎约定 需要构造一个 object, 这里应该是个优先级 的问题,,,new 只负责构造以个object,不管这个object哪里来,如果functionName 的 returnValue 本身就是一个 object,那么new认为这个就是表达式需要的object 了,,,直接把这个object设置为 new 的returnValue,然后退出。

那么,把整个猜想稍微的修改下,

   var o = {__proto__:Fn.prototype};
   var reV = Fn.apply(o , auguments);
    if ( reV instanceof Object ){
      o = reV;
    }
   return o;

   嗯嗯,这样就可以解释的通了为什么第二个例子里面 dog !="dog3"

   因为引擎reV instanceof Object发现是个非object,那么就把reV 忽略,继续自己的构造object之路。






 posted on 2013-01-31 18:54 落叶满长沙 阅读(...) 评论(...) 编辑 收藏