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

23 Comments

  1. Prestige park grove
    Prestige park grove July 7, 2023

    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: The laruence2
    object has no prototype, the (constructor) function has a prototype, and the [[Prototype]] attribute in the object points to The prototype of the constructor.
    Foo is an instance of Function, and [[Prototype]] in Foo points to the prototype of Function(). Therefore, accessing Foo.label first searches for the properties of Foo, and then searches for the properties of Function.prototype.

  2. formatter json
    formatter json January 12, 2021

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

  3. Leo
    Leo September 9, 2017

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

  4. 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以下输出的内容有些让人费解

  5. […] 原型,原型链,看了忘,忘了再看。 来源 本条目发布于28 三月, […]

  6. 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的属性。

  7. Jeffry
    Jeffry November 13, 2013

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

    • sijunmanyue
      sijunmanyue February 25, 2019

      大佬是怎么有头像的

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

  9. wannianchuan
    wannianchuan June 10, 2013

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

  10. phenix
    phenix May 8, 2012

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

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

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

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

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

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

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

  14. Anonymous
    Anonymous October 14, 2010

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

  15. 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()的时候却没有报错。

  16. 牛
    May 21, 2010

    牛牛牛牛牛

Comments are closed.