我不知道为什么,当我得到错误:方法未定义,我在Safari中已经检查和内部parserDidStart这个变量()方法的类型不EpisodeController它的类型是EpisodeFeedParser的这是为什么?
<html> <head> <script type="text/javascript"> var EpisodeFeedParser = function(url){ this.url = url; this.didStartCallback = null; }; EpisodeFeedParser.prototype.parse = function(doc){ this.didStartCallback(this); }; var EpisodeController = function(){ this.episodes = new Array(); this.parser = null; //lazy }; EpisodeController.prototype.parserDidStart = function(parser){ console.log("here *this* is not of type EpisodeController but it is EpisodeFeedParser Why?"); this.testEpi(); //**********ERROR HERE!*********** }; EpisodeController.prototype.fetchEpisodes = function(urlString){ if(urlString !== undefined){ if(parser === undefined){ var parser = new EpisodeFeedParser(urlString); parser.didStartCallback = this.parserDidStart; this.parser = parser; } this.parser.parse(); } }; EpisodeController.prototype.testEpi = function(){ console.log("it worked!"); }; function testEpisode(){ var controller = new EpisodeController(); controller.fetchEpisodes("myurl"); } </script> </head> <body> <button type="button" onclick="testEpisode()">press me</button> </body> </html>
解决方法
您可以将此视为另一个无形地传递给您的函数的参数.所以当你写一个像这样的函数时,
function add (a,b) { return a+b; }
你真的在写
function add(this,a,b) { return a+b; }
这可能是显而易见的,不明显的是传递的内容,并命名为“this”.其规则如下.有四种方法可以调用一个函数,它们各自绑定一个不同的东西.
add(a,b);
在经典函数调用中,这绑定到全局对象.该规则现在普遍被视为一个错误,并且可能在将来的版本中设置为null.
new add(a,b);
在构造函数调用中,这被设置为一个全新的对象,其内部(和不可访问的)原型指针设置为add.prototype
someobject.add(a,b);
在方法调用中,这被设置为someobject.无论你最初定义添加的位置,它是在构造函数内部,特定对象的原型的一部分,还是其他什么都没关系.如果以这种方式调用函数,则将其设置为您调用它的任何对象.这是你遇到的规则.
add.call(someobject,b);
在调用/应用调用中,这被设置为传入调用方法的现在可见第一个参数的任何内容.
您的代码中发生的是:
this.parser.didStartCallback = this.parserDidStart;
当你编写parserDidStart时,期望当你的方法调用它时它会是一个EpisodeController ……实际上你正在将它从EpisodeController更改为this.parser.那个特定的代码行没有发生这种情况.直到这里,交换机才会实际发生:
this.didStartCallback(this);
在这个例子中,这是EpisodeParser,并且在运行此代码时,你已经将parserDidStart命名为didStartCallback.当你在这里调用didStartCallback时,使用这段代码,你实际上是在说……
didStartCallback.call(这一点,这一点);
通过说这个.didStartCallback(),你把它设置为……好吧……当你调用它时.
您应该知道一个名为bind的函数,这里解释如下:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind