var a=function(){};
a.prototype.ask=function(){console.log("ok")};
var b=new a();
b.ask();
a.ask();//error
上述代码,我知道会沿着原型链向上找函数,但是我不能说明白为什么a.ask();会是undefined
伊谢尔伦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)某个值时,不会存在原型链
PHP中文网2017-04-10 15:09:17
如果说a可以调用ask方法的话,那么ask就是a的一个静态方法了。
js
a.ask = function() {};
你的那种情况,可以这样理解:
a是一个函数对象,所以说a.__proto__就是指向的Function.propotype,而不是a.prototype
建议看看原型以及原型链知识 http://www.cnblogs.com/TomXu/archive/2012/01/05/2305453.html
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
这篇文章应该可以帮助你
PHPz2017-04-10 15:09:17
除了上面说的,麻烦编程细心点,有的有分号,有的没分号,最后还来了个中文符号在里面,虽然分号有无不会有大的影响,但是表明了你的编程规范意识还是不足的。。我不是挑刺,基本的编程素养还是要把握好的,不然会埋下很多坑!
迷茫2017-04-10 15:09:17
最简单的一句话:
ask是prototype堂主创建出来的,所以要么听堂主的,要么听帮主b的,怎么也不会轮到听a这个帮会接待处的吧?