Press "Enter" to skip to content

Javascript原型链和原型的一个误区

之前我对Javascript的原型链中, 原型继承与标识符查找有些迷惑,
如, 如下的代码:

function Foo() {};
var foo = new Foo();
Foo.prototype.label = "laruence";
alert(foo.label); //output: laruence
alert(Foo.label);//output: undefined

今天看到了如下这个图:

Javascript object layout
Javascript object layout

另外, 在Javascript Object Hierarchy看到:

The prototype is only used for properties inherited by objects/instances created by that function. The function itself does not use the associated prototype.

也就是说, 函数对象的prototype并不作用于原型链查找过程中,
今天在firefox下发现(因为firefox通过__proto__暴露了[[prototype]]), 真正参与标识符查找的是函数对象的__proto__,

function Foo() {};
var foo = new Foo();
Foo.__proto__.label = "laruence";
alert(Foo.label); //output: laruence
alert(foo.label);//output: undefined

而, 显然的:

function Foo() {};
alert(Foo.__proto__ === Foo.prototype); //output: false

另外, 也解释了,

alert(Object.forEach); // undefined
Function.prototype.forEach = function(object, block, context) {
    for (var key in object) {
        if (typeof this.prototype[key] == "undefined") {
            block.call(context, object[key], key, object);
        }
    }
};
alert(Object.forEach);
alert(Function.forEach);
alert(Object.forEach === Function.forEach); // true

21 Comments

  1. formatter json
    formatter json January 12, 2021

    确实遇到过这个坑 印象很深
    还有有的帖子怎么回复不了了呢

  2. Leo
    Leo September 9, 2017

    鸟哥,我是这么理解的 : 所有函数都是new Funciton()的结果
    , 那么Function.prototype就是每个函数的原型对象 , 往原型对象里增加属性, 那么每个函数都自然会继承所添加的属性 , 所以Object.forEach === Function.forEach是毋庸置疑的 , 那么相同的还有String.forEach === Array.forEach …..只要是个函数 都有forEach这个属性 (不知道理解的对不对,望指正)

  3. Decimal0.5
    Decimal0.5 April 20, 2016

    function free(){}
    function son(){}
    function man(){}
    son.prototype=new free();
    man.prototype=new son();
    var c=new man();
    console.log(c);//man
    console.log(c.__proto__);//son
    console.log(c.__proto__.__proto__);//free
    console.log(c.__proto__.__proto__.__proto__);//free
    console.log(c.__proto__.__proto__.__proto__.__proto__);//object
    console.log(c.__proto__.__proto__.__proto__.__proto__.__proto__);//null
    console.log(“————————————————–“)//### 2 #####
    console.log(c.constructor);//free
    console.log(c.__proto__.constructor);//free
    console.log(c.__proto__.__proto__.constructor);//free
    console.log(c.__proto__.__proto__.__proto__.constructor);//free
    console.log(c.__proto__.__proto__.__proto__.__proto__.constructor);//object
    console.log(c.__proto__.__proto__.__proto__.__proto__.__proto__.constructor);//error
    这段代码的输出中,标号2以下输出的内容有些让人费解

  4. csyangchsh
    csyangchsh November 18, 2013

    function Foo() {};
    var foo = new Foo();
    Foo.prototype.label = “laruence”;
    Function.prototype.label = “laruence1”;
    alert(foo.label); //output: laruence
    alert(Foo.label);//output: laruence1
    Foo.label = “laruence2”;
    alert(Foo.label);//output: laruence2
    对象没有原型,(构造)函数有原型,对象中[[Prototype]]属性指向了构造函数的原型。
    Foo是Function实例,Foo中的[[Prototype]]指向了Function()的原型。所以,访问Foo.label先搜索Foo的属性,再搜索Function.prototype的属性。

  5. Jeffry
    Jeffry November 13, 2013

    博主的问题是,__proto__与prototype傻傻分不清楚。

  6. […] 今天想起了javascript有原型和原型链这俩东西,虽然只差一个字,但是貌似这俩是不太一样的,于是乎谷歌之,第一篇博文就是我大鸟哥的博客,其中有个图,仔细看之,甚是头晕。强忍之,继续看,似乎明白了些什么,看到评论里有个博客,就继续看。感觉第二个更好理解一些,看完了再看鸟哥的更好。 […]

  7. wannianchuan
    wannianchuan June 10, 2013

    Javascript原型链是很容易让人迷惑的一个地方 看了这篇文章就清楚多了

  8. phenix
    phenix May 8, 2012

    javascript的原型链实现了继承树的建立,使用了构造器的prototype属性[原型]与对象的constructor属性;由于js采取的是读遍历方式构建对象,故使用内部原型__proto__指向原型成员列表,用于成员检索,它保证了父类与子类的继承特性。

  9. 拇指玩
    拇指玩 April 10, 2012

    其实就是类属性、对象属性的区别..呵,很容易混。

  10. 丁小倪
    丁小倪 March 27, 2012

    function Foo() {};
    var foo = new Foo();
    Foo.prototype.label = “laruence”;
    alert(foo.label); //output: laruence
    alert(Foo.label);//output: undefined
    第一段实例代码最后的注释输出错误,应该都为laruence

  11. jQuery教程
    jQuery教程 January 14, 2011

    关于javascript的机制,老兄是相当的了解呀~~
    学习了~~
    现在我正在慢慢补充这方面的知识~~

  12. Anonymous
    Anonymous October 14, 2010

    f.prototype = obj;
    fo = new f;
    fo的__proto__链存在obj

  13. J
    J July 2, 2010

    你好,想请教一个问题。
    var A = (window.getSelection)?window.getSelection():document.selection;
    if(!A) {
    return NULL;
    }
    var B = (A.rangeCount>0)?A.getRangeAt(0):A.createRange()
    //alert(A.rangeCount>0);
    obj.currPos = B.duplicate();
    if (obj.currPos) {
    //alert(obj.currPos.htmlText);
    //obj.currPos.text = str
    obj.currPos.htmlText = str //!!!!!!!!!!!!!
    }
    else {obj.innerHTML+=str}//直接把参数str的值添加到对象obj的值后面
    为什么在obj.currPos.htmlText会报doesn’t support this action这个错呢?alert()的时候却没有报错。

  14. 牛
    May 21, 2010

    牛牛牛牛牛

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.