简体   繁体   English

将对象或函数的引用另存为匿名函数的变量的Javascript错误做法

[英]Javascript bad practice to save reference of object or function as a variable for anonymous function

I am developing code for a Facebook app for a website. 我正在为网站的Facebook应用程序开发代码。 I am setting it up so others can use the JavaScript I write on other pages (even if they don't know much JS -- they can mirror my examples); 我正在设置它,以便其他人可以使用我在其他页面上编写的JavaScript(即使他们不太了解JS,他们也可以反映我的示例); sort of framework-ish. 有点像框架。

Some pages we want to check if the user is logged into Facebook on page load, other times we don't. 有些页面我们想检查用户是否在页面加载时登录了Facebook,而其他时候我们不想。 So, inside the ini function I check to see if the onPgLoadCheckLogin value is set to true, then I use the Facebook toolkit to check that. 因此,在ini函数内部,我检查了onPgLoadCheckLogin值是否设置为true,然后使用Facebook工具箱进行了检查。

These functions work asynchronously and use callbacks to handle the responses. 这些函数异步工作,并使用回调来处理响应。 I want to use functions that I have set up in the (no-so-much-of-a)framework. 我想使用在(不太多)框架中设置的功能。

To do this, because its a callback, I am saving a reference to the object/function in a variable called me - just before I execute the async stuff and set up the callback. 为此,因为它是回调,所以我将对对象/函数的引用保存在名为me的变量中-在执行异步工作并设置回调之前。

Is this bad practice? 这是不好的做法吗? If so, how can I get the callback to invoke the method I want to use? 如果是这样,如何获取回调以调用要使用的方法?

Here is the code: 这是代码:

// Strict mode
"use strict";


/* Main object
 * @param config: array of app configuration
 */
var SMFbApp = function(config) {

    // app configuration
    this._config = (!!config && (typeof config).toLowerCase() == 'object') ? config : undefined;
    // check log in on page load
    this._onPgLoadCheckLogin = false;

    /*
     * ini
     * Initialize app
     */
    this.ini = function() {
        if(!this._config || (typeof this._config).toLowerCase() == 'undefined') {
            this._config = this.getDefaultConfig();
        }


        // mandatory configuration elements we need to address
        var fbini = [
            'appId', // dev facebook app id as default
            'cookie', // allow checking browser cookies
            'xfbml', // facebook markup in html doc ( example: <fb:login-button></fb:login-button> )
            'version', // sdk version
        ];

        var tmp = {}; // temp object to hold config vars
        // iterate through mandatory config and fill temp vars to init fbook sdk/api
        for(var idx in fbini) {
            if(!(fbini[idx] in this._config)) {
                console.error('Invalid configuration set passed to ShoeMoney Facebook App. Please review documentation for all necessary configuration values');
                this.exit(1);
            } else {
                tmp[fbini[idx]] = this._config[fbini[idx]];
            }
        }

        var me = this;
        // set up fb asycn init function with tmp object we just set up
        window.fbAsyncInit = function() {
            FB.init(tmp);
            if(me._onPgLoadCheckLogin) {
                var _this = me;
                FB.getLoginStatus(function(response) {
                    _this.statChange(response);
                });
            }
        };


    }

And the part I am questioning as bad practice is (i do it twice): 我所质疑的不好的做法是(我做了两次):

var me = this; // HERE!!! once
// set up fb asycn init function with tmp object we just set up
window.fbAsyncInit = function() {
    FB.init(tmp);
    if(me._onPgLoadCheckLogin) {
        var _this = me; // HERE!! twice
        FB.getLoginStatus(function(response) {
            _this.statChange(response);
        });
    }
};

What you're doing with var me = this; 您对var me = this; is a perfectly fine practice and is a common way of saving the this value for a local callback function to access. 是一种非常好的做法,并且是保存this值以供本地回调函数访问的常用方法。 Though in your specific example, you don't have to create the _this variable. 尽管在您的特定示例中,您不必创建_this变量。 You can just access me from both callbacks like this: 您可以像这样从两个回调中访问me

// save our object reference for later use in callbacks
var me = this; 
// set up fb asycn init function with tmp object we just set up
window.fbAsyncInit = function() {
    FB.init(tmp);
    if(me._onPgLoadCheckLogin) {
        FB.getLoginStatus(function(response) {
            me.statChange(response);
        });
    }
};

The other main alternative if the callbacks themselves don't use a this value that you need to access is to use .bind() , but in your specific example, you would have to use .bind() in two places to get both nested logins so your method of saving in me is probably simpler. 如果回调本身不使用您需要访问的this值,则另一种主要选择是使用.bind() ,但是在您的特定示例中,必须在两个地方使用.bind()来嵌套两者登录,因此您保存在me这里的方法可能更简单。

Here's what the .bind() alternative would look like: 这是.bind()替代品的样子:

// set up fb asycn init function with tmp object we just set up
window.fbAsyncInit = function() {
    FB.init(tmp);
    if(this._onPgLoadCheckLogin) {
        FB.getLoginStatus(function(response) {
            this.statChange(response);
        }.bind(this));
    }
}.bind(this);

For a reference, see the MDN page for .bind() . 有关参考,请参见.bind()的MDN页面

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM