search

Home  >  Q&A  >  body text

javascript - 关于prototype的理解上的一个问题

var a=function(){};
a.prototype.ask=function(){console.log("ok")};
var b=new a();
b.ask();
a.ask();//error

上述代码,我知道会沿着原型链向上找函数,但是我不能说明白为什么a.ask();会是undefined

迷茫迷茫2837 days ago412

reply all(7)I'll reply

  • 伊谢尔伦

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

    从你的问题来看,你对实例和构造函数以及原型的关系没有理解透彻。
    实例和构造函数之间的关系是通过原型来链接的

    一般实例用小写字母开头,构造函数使用首字母大写,以下用a 和 A来说明,其中a = new A
    此时 a.[[proto]] = A.prototype
    A.prototype就是a的原型,即实例的原型是其构造函数的prototype对象
    ECMAScript标准规定了:当访问(get)一个对象(a)的某个属性(ask)的时候,首先检查a本身是否存在ask这个属性,如果存在,则直接返回这个值,否则就查找这个对象的原型对象(a.[[proto]])是否存在ask属性,存在则返回,不存在则继续查找a的原型的原型,以此类推,直到原型为null为止。这就是原型链。

    所以你的b.ask实际上并不是b的本身ask属性,而是来自于b的原型的ask属性。
    而你的a = function(){}a.[[proto]] = Function.prototype
    你访问a.ask时,a的本身不存在ask属性,于是去查找它的原型Function.prototype,依然不存在,于是再找Function.prototype.[[proto]],即Object.prototype,这个也不存在ask属性,以此类推,它找到链的最后都没有找到,于是a.ask返回的值是undefined,你再调用它a.ask()时就会报undefined is not a function这类的错误。

    注1:[[proto]]是ECMAScript标准规定的属性,浏览器里的实现是__proto__
    注2:原型链只存在于访问(get)属性的时候,如果是设置(set)某个值时,不会存在原型链

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 15:09:17

    a 是构造函数,只有通过 new 实例化的时候才会去继承 prototype 原型上的属性,建议好好看看手册。

    reply
    0
  • PHPz

    PHPz2017-04-10 15:09:17

    typeof afunction
    对象才能调用方法吧,应该new一个a的对象实例

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 15:09:17

    如果说a可以调用ask方法的话,那么ask就是a的一个静态方法了。

    jsa.ask = function() {};
    

    你的那种情况,可以这样理解:
    a是一个函数对象,所以说a.__proto__就是指向的Function.propotype,而不是a.prototype

    建议看看原型以及原型链知识 http://www.cnblogs.com/TomXu/archive/2012/01/05/2305453.html

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 15:09:17

    var a = function (){};  // 跟这个是一样的吧 function a(){};
    a.prototype.ask=function(){console.log("ok")};
    var b=new a();  //你这里没加分号';'
    b.ask();
    a.prototype.ask();  //改为这样
    //ok
    //ok
    

    这篇文章应该可以帮助你

    reply
    0
  • PHPz

    PHPz2017-04-10 15:09:17

    除了上面说的,麻烦编程细心点,有的有分号,有的没分号,最后还来了个中文符号在里面,虽然分号有无不会有大的影响,但是表明了你的编程规范意识还是不足的。。我不是挑刺,基本的编程素养还是要把握好的,不然会埋下很多坑!

    reply
    0
  • 迷茫

    迷茫2017-04-10 15:09:17

    最简单的一句话:

    • a可以看做帮会的接待处
    • ask方法是小弟
    • prototype是ask的堂主
    • b是新上任的帮主

    ask是prototype堂主创建出来的,所以要么听堂主的,要么听帮主b的,怎么也不会轮到听a这个帮会接待处的吧?

    reply
    0
  • Cancelreply