onload 在 Javascript 中如何工作?

How does onload work in Javascript?

Pro HTML5 Games一书中有如下一段代码:

    // Load all data and images for a specific level
load:function(number){
    // declare a new currentLevel object
    game.currentLevel = { number: number, hero: [] };
    game.score = 0;
    $('#score').html('Score: '+game.score);
    var level=levels.data[number];

    //load the background, foreground, and slingshot images
    game.currentLevel.backgroundImage=loader.loadImage("images/backgrounds/"+level.background+
    ".png");
    game.currentLevel.foregroundImage=loader.loadImage("images/backgrounds/"+level.foreground+
    ".png");
    game.slingshotImage=loader.loadImage("images/slingshot.png");
    game.slingshotFrontImage =loader.loadImage("images/slingshot-front.png");

    //Call game.start() once the assets have loaded
    if(loader.loaded){
        game.start()
    } else {
        loader.onload = game.start;
    }
}

加载器对象如下:

var loader= {
loaded:true,
loadedCount:0, // Assets that have been loaded so far
totalCount:0, // Total number of assets that need to be loaded

init:function(){
    // check for sound support
    var mp3Support,oggSupport;
    var audio =document.createElement('audio');
    if (audio.canPlayType) {
        // Currently canPlayType() returns: "", "maybe" or "probably"
        mp3Support ="" != audio.canPlayType('audio/mpeg');
        oggSupport ="" != audio.canPlayType('audio/ogg; codecs="vorbis"');
    } else {
        //The audio tag is not supported
        mp3Support =false;
        oggSupport =false;
    }
    // Check for ogg, then mp3, and finally set soundFileExtn to undefined
    loader.soundFileExtn =oggSupport?".ogg":mp3Support?".mp3":undefined;
},

loadImage:function(url){
    this.totalCount++;
    this.loaded =false;
    $('#loadingscreen').show();
    var image =new Image();
    image.src =url;
    image.onload =loader.itemLoaded;
    return image;
},

soundFileExtn:".ogg",

loadSound:function(url){
    this.totalCount++;
    this.loaded =false;
    $('#loadingscreen').show();
    var audio =new Audio();
    audio.src =url +loader.soundFileExtn;
    audio.addEventListener("canplaythrough", loader.itemLoaded, false);
    return audio;
},

itemLoaded:function(){
    loader.loadedCount++;
    $('#loadingmessage').html('Loaded '+loader.loadedCount+' of '+loader.totalCount);
    if (loader.loadedCount === loader.totalCount){
        // Loader has loaded completely..
        loader.loaded=true;
        // Hide the loading screen
        $('#loadingscreen').hide();
        //and call the loader.onload method if it exists
        if(loader.onload){
            loader.onload();
            loader.onload =undefined;
        }
    }
}

我有以下问题:

1)如果onload是一个方法,我们不应该像imageThatWeWantToLoad.onload(stuff we want to do after image has been loaded)那样使用它,而不是imageThatWeWantToLoad.onload = (do what we want to do after image has been loaded)吗?

2)loader.onload=game.start;部分(game是一个对象,start是game对象内部定义的方法)到底是做什么的? 我想我明白了 loader.onload=game.start; 的意思是加载器对象一旦被加载, game.start 就会被调用,但是既然 game.start 是一个方法,不应该是 loader.onload=game.start();

3)此外,onload 表示 'data received by the browser' ?

属性 loader.onload 是一个指向函数的指针(从技术上讲,它只是一个普通指针,但让我们暂时忽略它)。

正在做:

loader.onload = game.start;

将函数game.start赋给指针loader.onload

稍后,在加载程序代码中您会看到:

if(loader.onload){
    loader.onload();
    loader.onload =undefined;
}

它主要是检查 loader.unload 是否被赋值(undefined 在 javascript 中被认为是假的)。如果它调用了它指向的函数,则将指针设置回 undefined.

上面的解释掩盖了关于 javascript 的几个事实。但这基本上就是正在发生的事情。

  1. Loader 是对象,loadImage 是在其上定义的 属性。

  2. 属性loader.onload是一个指向函数的指针(匿名)

  3. loader.onload = game.start; // 使 loader.onload 指向 game.start。也就是说 game.start() === loader.onload();

1) image.onload 本质上不是一种方法。它只是一个属性,就像我们执行

namedog中的一个属性
dog = { name: null };

一个对象的属性是一个方法,如果它包含一个函数。所以,

dog['bark'] = function() { console.log("Woof"); };

现在我们可以dog.bark()调用这个方法。

如果在加载图像时 image.onload 是一个方法(即,如果它包含一个函数),浏览器将 运行。它不是一个让我们调用的方法,它是给我们define.

2) 它的作用与它看起来的完全一样——将 game.start(一个函数)的内容分配给 loader.onload。现在这两个属性都引用同一个函数。如果我们做loader.onload = game.start(),它会执行game.start并将执行的结果分配给loader.onload;但是我们想给函数本身赋值,所以没有括号。

Onload in JavaScript可以描述为:

  1. onload 在这里作为 属性 访问,我们将函数的结果分配给 属性。因此函数将执行,最终结果将分配给 属性。所以基本上调用函数并将结果分配给 属性 是在单行代码中同时完成的。

  2. 在这种情况下,我们想通过检查loader.loaded属性来了解加载器onload方法是否已经执行。如果它已执行,则调用 game.start() 而不分配给任何函数以在 onload 方法已执行时按顺序执行。如果它没有执行那么我们已经将 game.start 函数分配给 loaded.onload 函数所以我们使用它们作为 属性 将函数分配给另一个函数,所以现在 onload 方法将被调用,它现在将执行 game.start() 函数,因为 onload 被替换为 game.start.

  3. Onload表示对象已经加载。我们在 html 的 body 标签中使用 onload 事件来知道网页已经加载了所有内容,我们现在可以执行我们的操作以顺利运行。