var obj = function () {
            this.name = "test";
            this.age = "100";
        }
        obj.prototype = function{
        var a="覆盖后的函数";
        };
        var o = new obj();
        document.writeln(o.constructor);

解决方案 »

  1.   

    原型害人。
    prototype就是个属性.
    看调试器最清楚了。
      

  2.   

    alert输出的是toString方法的返回值
    toString方法在原型prototype上,你重新给obj函数prototype赋值后,obj函数原型上没有了toString方法,根据原型链机制,将从其原型的原型上查找该方法,所以调用了其基类Object类的toString方法
      

  3.   


    obj.prototype = {
        toString:function(){ alert('楼上的回答很强悍'); }
            };//
    var obj = function () {
                this.name = "test";
                this.age = "100";
            }
            obj.prototype = {
                   constructor:obj    
     
            };//有时候 你看到的就是因
      

  4.   

    一个平常容易被忽略的问题啊~~用楼主的代码和控制台的显示结果来解释一下(chrome浏览器):
    (1)
    代码稍作改动,如下:var obj = function () {
    this.name = "test";
    this.age = "100";
    }
    //给原型随便加上一个属性foo(原型为空的时候,控制台显示出的对象结构不完整)
    obj.prototype = {
    foo: function(){}
    };
    var o = new obj();
    //用console.log直接在控制台输出(在浏览器原型链之类的是无法正常输出的)
    console.log(o)
    最终,控制台输出的对象o如下:
    (2)
    首先应该知道的是:在实例化之后,实例化对象中会有一个__proto__属性,这个属性的值便是原型对象;在上面的代码里就是:"原型对象=obj.prototype=o.__proto__={ foo:function(){} }"。
    其次:在实例化之后,当读取实例化对象的某个属性时:会先在对象身上找这个属性,如果找不到再到原型对象里找。结合上面的图:当你读取o.constructor属性时,首先在o中在找,显然o自身的属性只有name和age,所以到o的原型对象即:o.__proto__中继续找;
    因为原型对象也是对象,所以寻找属性也会遵循“先自身后原型”的方法,因此会先在o的原型对象本身找constructor,显然原型对象自身只有foo这么一个属性,所以继续到原型对象的原型对象(有点绕)中找,即图中的“o.__proto__.__proto__”,结果如图所示找到了!所以最终显示的值如楼主所见。PS: __proto__虽然在控制台中的显示与对象的自身属性并无两样,但是严格来讲它并不是对象自身的属性,它只是用来将对象和原型对象联系起来的一个桥梁,只在底层操作中会用到。
      

  5.   

    6楼说的是对的,但是可能不是那么好理解,我来说一下我的理解吧:首先,为了说明这个问题,我们来探讨一下new一个对象时究竟发生了什么:
    function obj(){
        //...
    };
    var o = new obj();
    相信这样的代码大家都经常写, 按照我们的传统面向对象语言(C#, java等), 这叫做new了一个obj类.
    但是在js中又没有什么class关键字, 叫起来好像有点怪怪的, 于是更常见的是称呼obj是一个类构造函数. 
    不过其实在javascript中吧, obj其实就是一个Object, 一个很特殊的Object.
    这货与new出来的对象o之间的区别在哪里呢?区别就在于function定义的对象有一个prototype属性,
    而这个prototype属性中呢又有一个constructor属性, 这个属性就指向obj函数本身。
    (好吧, A爱着B, 而B又爱着C, 剧终才发现C原来就是A - - )那么new一个对象时又发生了什么呢?
    其实 var o = new obj() 可以拆成这几步:
    var o={} //创建一个新对象o
    obj.call(o) //o作为this参数调用构造函数obj, 喏, 这样你赋值的name, age都赋值给新对象o. 
    还有一个很重要的一步,我把它放到最后来说了(它发生在创建新对象o的后面):
    任何一个对象, 都有一个属性名叫__proto__, 我们称之为内置原型对象,(当然, 你可别把它和prototype混淆了)
    紧接在新创建对象后, o就被设置为了obj.prototype的值.话说, 到了这里, 你应该能明白你的问题了吧?
    在你未设置obj.prototype之前:
    function obj(){
       //...
    }
    var o = new obj();
    alert(o.constructor);
    喏: alert(o.constructor) --> alert(o.__proto__.constructor) --> alert(obj.prototype.constructor) --> alert(obj) --> alert(obj.toString())
    发现了吧, 调用的是obj函数的toString方法, 函数的toString方法会输出该方法的代码
    那么在你设置obj.prototype之后呢?
    function obj(){
       //...
    }
    obj.prototype={}
    var o = new obj();
    alert(o.constructor);
    显然可以看到, 你把obj.prototype给赋值成了一个新对象, 而且还是个空的新对象, 那么此时此刻会发生什么呢?
    我们不难想到, o在找constructor的时候找到的是Object.constructor:
    o.constructor --> o.__proto__.constructor --> obj.prototype.constructor --> {}.constructor --> {}.prototype.constructor --> Object
    最终,输出了Object的构造函数。嗯,你看,其实一点也不复杂,一点也不难理解,就是这么简单。。嗯唔~~
    (PS: By the way, 我发现这是我在CSDN回复过的有史以来最长的帖, 哈哈哈)
      

  6.   

    更正一下, 发现了一个笔误:
    紧接在新创建对象后, o就被设置为了obj.prototype的值.
    我是想说o.__proto__就被设置为了obj.prototype的值.太粗糙了,咳。。
      

  7.   

    8楼这块讲的很经典那。其实,这个是我简化版的说明,此说法还不够准确的。。
    既然有哥们专门引用这段了,我就再补充点吧: 
    好吧,我想想, 应该用这样的伪代码来描述一下 new obj():
    function obj(){
    // var tmp={}; //new 操作符会创建一个新对象
    // this = tmp; //这个函数的this指针被设置为该新对象

        this.name="xxx"; //用this添加属性的语句, 都赋值到了这个新对象中
        this.age="ooo";

    //return tmp; //如果没有显式的return语句, 那么将返回这个新对象
    }var o = new obj(); //o 被设置为这个新对象其中要说明的是, 如果obj有显式的return语句, 那么也必须是return 一个对象才是有效的, 比如看:
    function obj(){
    return 2; //返回数字字面值 2
    }var x = new obj();
    可以试试看, 返回的是什么?
    返回的其实是一个空对象, 而不是2:
    function obj(){
    // var tmp={}; //new 操作符会创建一个新对象
    // this = tmp; //这个函数的this指针被设置为该新对象

    return 2; //显式返回的不是一个对象, 该语句无效

    //return tmp; //返回这个新对象
    }OK, 写完了, 希望没有误人子弟..
      

  8.   

    前面想复杂了,
    其实这个比想的更简单,首先 对象o自身没有o.constructor属性,
    故根据原型机制,o.constructor===o.prototype.constructor;而o.prototype===obj.prototype==={}
    而显然{}的构造函数是Object,
    故最终o.constructor===({}).constructor===Object