search

Home  >  Q&A  >  body text

javascript - js原型问题

var F = function(){};
Object.prototype.a = function(){ console.log('a'); };
Function.prototype.b = function(){ console.log('b'); };
var f = new F();
f.a();// a
f.b();// undefined
F.a();// a
F.b();// b

为什么f继承不了b方法?

巴扎黑巴扎黑2902 days ago382

reply all(5)I'll reply

  • PHPz

    PHPz2017-04-10 15:09:47

    大概原型是这样的

    f.__proto__ -> F.prototype
    F.prototype.__proto__ -> Object.prototype
    

    所以说f是取不到b的。

    然后看F:

    F.__proto__ -> Function.prototype
    Function.prototype.__proto__ -> Object.prototype
    

    所以就能有a 还有b

    可以参考 www.cnblogs.com/TomXu/archive/2012/01/05/2305453.html

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-10 15:09:47

    在实现js的继承的时候,每一个用new 构造出来的对象都会有一个私有的属性,在firefox和chrome中这个私有的属性叫做 __proto__,在 IE中也有一个这样类的的私有属性,只不过没有暴露给用户。
    这个属性指向其构造函数的 prototype ,在执行 f = new F() 的时候会有类似这样的赋值f.__proto__ = F.prototype

    当你读取 f.pro 的时候,会现在f中寻找有没有一个叫 f 的属性,没有的话就去f.__proto__中找有没有,还没有的话,就去f.__proto__.__proto__中去找(记住一个对象的__proto__就是其构造函数的prototype)。。。这样一直下去其实最终会找到 Object.prototype,这样就实现了所有的对象都继承了Object。
    当你写入 f.pro 的时候就只会在f中查找,不会递归的查找f.__proto__,这样就会得到一个新的(如果没有的话)pro 属性,然后当你再次访问 f.pro 的时候,就是访问的这个新的属性,即使f.__proto__中有这个属性,这就完成了属性/函数的重载

    下面是我画的firefox中js继承实现的模型(橙色的是内置生成的,Fishf1 分别对应你的 Ff)

    你的f = new F(); 不是new Function() 所以 f.__proto__ !== Funtion.prototype 所以 f.b() === undefined ,而函数其实就是一个 new Function() 即使写成 var F = function (){}这样的形式,所以F.b()是可以正常调用的

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 15:09:47

    F 只是构造函数,new F 并不是说 f 是函数 F 的实例,而是说通过构造函数 F 生成新的对象。

    reply
    0
  • ringa_lee

    ringa_lee2017-04-10 15:09:47

    b方法是在Function类型上的原型上定义的,只有函数才会继承它,而通过new F()构造出来的实例f,是一个新对象,所以继承不了b
    如果想让f继承b,应该在F.prototype上定义b

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 15:09:47

    如果就这题而言,f.b()得到undefined的原因是:

    方法b不是"实例f"  的"构造函数F"的  "原型对象"上的  "方法"!
    

    话有点长,也可以换个角度想:

    实例f的"构造函数"不是Function,所以访问不了Function  的"原型对象上"的  方法!
    

    可以来试验一下:

    f.__proto__ === F.prototype // true
    f.__proto__ === Function.prototype // false
    

    本题还说到"Object" ,咱们也来比较下 :

    f.__proto__.__proto__ === Object.prototype // true
    

    可以看出f的构造函数F其实是"继承"自Object(JavaScript中没有继承,只是实现这种模式)。

    总结:
    - 构造函数在创建之初就自动生成了个指向原型对象的指针,指向它的"父类",F能访问到a和b都是你在父类的原型对象上操作添加后的结果。
    - 实例能访问到它的构造函数的原型对象上的属性或方法 和 原型对象原型对象的属性或方法 和 原型对象。。。(此处省略N个字)。(原型链

    reply
    0
  • Cancelreply