javascript:如何访问正确的上下文

时间:2018-01-22 10:23:49

标签: javascript

我需要编写如下所示的Javascript代码。问题是我无法从_notifHandlers.typeA_notifHandlers.typeB_notifHandlers.typeGeneric中访问“this”(它应该指向第1行的“obj”)。

我知道我可以将“this”作为参数传递给这些函数,并使用它来访问正确的上下文。但是有更好的方法吗?

var obj = {
    handleNotification : function(managedObj) {

        if (this._notifHandlers.hasOwnProperty(managedObj.id)) {
            this._notifHandlers[managedObj.id](managedObj);
        } else {
            this._notifHandlers.typeGeneric(managedObj);
        }

    },

    _notifHandlers : {
        typeA : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelA"; // TODO:
            this.showUI(managedObj, model);
        },
        typeB : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelB"; // TODO:
            this.showUI(managedObj, model);
        },
        typeGeneric : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "typeGeneric"; // TODO:
            this.showUI(managedObj, model);
        }
    },

    showUI : function(managedObj, model) {
        // TODO:
        console.log("In showUI(): model -> " + model)
    }
}

var managedObject = {
    id : "typeB"
}

obj.handleNotification(managedObject);

2 个答案:

答案 0 :(得分:1)

您始终可以使用bind创建正确初始化上下文的函数实例

function show(){
    console.log(this.x);
}

x = 10;
var obj = {
    x: 5,
    y:{}
}

// Use bind to create an instance of the function show with the context set to obj and set it to an inner proerty of obj (to mimic the structure of the original posted code)
obj.y.show = show.bind(obj);

show(); //Logs 10 from the global window context
obj.y.show() // Logs 5 with this bound to obj

您还可以使用callapply来设置调用时的上下文。

show.call(obj);  // Logs 5
show.apply(obj);  // Logs 5

答案 1 :(得分:1)

使用call方法

工作小提琴https://jsfiddle.net/andreitodorut/an15zkja/

var obj = {
    handleNotification : function(managedObj) {

        if (this._notifHandlers.hasOwnProperty(managedObj.id)) {
            this._notifHandlers[managedObj.id].call(this,managedObj);
        } else {
            this._notifHandlers.typeGeneric.call(this,managedObj);
        }

    },

    _notifHandlers : {
        typeA : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelA"; // TODO:
            this.showUI(managedObj, model);
        },
        typeB : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "modelB"; // TODO:
            this.showUI(managedObj, model);
        },
        typeGeneric : function(managedObj) {
            console.info("_notifHandlers " + managedObj.id + " selected.");
            var model = "typeGeneric"; // TODO:
            this.showUI(managedObj, model);
        }
    },

    showUI : function(managedObj, model) {
        // TODO:
        console.log("In showUI(): model -> " + model)
    }
}

var managedObject = {
    id : "typeB"
}

obj.handleNotification.call(obj,managedObject);