javascript – 为什么*这个*不是*这个*?

前端之家收集整理的这篇文章主要介绍了javascript – 为什么*这个*不是*这个*?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我刚写了这段代码来表示这个错误就是杀了我(Grrr!)

我不知道为什么,当我得到错误方法未定义,我在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>

解决方法

这是Javascript经常被误解的方面. (以及“这个”,我的意思是这个)

您可以将此视为另一个无形地传递给您的函数的参数.所以当你写一个像这样的函数时,

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

Bind从现有函数创建一个新函数,该函数固定(绑定)到您明确传入的任何对象.

猜你在找的JavaScript相关文章