Подтвердить что ты не робот

Доступ к родительскому объекту в javascript

    var user = {
        Name: "Some user",
        Methods: {
            ShowGreetings: function() {
                    // at this point i want to access variable "Name", 
                    //i dont want to use user.Name
                    // **please suggest me how??**
                 },
            GetUserName: function() { }
        }
    }
4b9b3361

Ответ 1

Вы не можете.

В JavaScript нет восходящих отношений.

Возьмем, например:

var foo = {
    bar: [1,2,3]
}

var baz = {};
baz.bar = foo.bar;

Объект с единственным массивом теперь имеет два "родителя".

Что вы можете сделать, это что-то вроде:

var User = function User(name) {
    this.name = name;
};

User.prototype = {};
User.prototype.ShowGreetings = function () {
    alert(this.name);
};

var user = new User('For Example');
user.ShowGreetings();

Ответ 2

var user = {
    Name: "Some user",
    Methods: {
        ShowGreetings: function() {
            alert(this.Parent.Name); // "this" is the Methods object
        },
        GetUserName: function() { }
    },
    Init: function() {
        this.Methods.Parent = this; // it allows the Methods object to know who its Parent is
        delete this.Init; // if you don't need the Init method anymore after the you instanced the object you can remove it
        return this; // it gives back the object itself to instance it
    }
}.Init();

Ответ 3

Crockford:

"Привилегированный метод имеет доступ к частным переменным и методов и сам доступен для публичных методов и вне"

Например:

function user(name) {
     var username = name;

     this.showGreetings = function()
     {
       alert(username);
     }  
}

Ответ 4

Вы можете попробовать другой подход, используя закрытие:

function userFn(name){
    return {
        Methods: {
            ShowGreetings: function() {
                alert(name);
            }
        }
    }
}
var user = new userFn('some user');
user.Methods.ShowGreetings();

Ответ 5

Как уже говорили другие, с простым объектом невозможно найти родителя от вложенного потомка.

Однако это возможно, если вы используете рекурсивные прокси ES6 в качестве помощников.

Я написал библиотеку с именем ObservableSlim, которая, помимо прочего, позволяет вам переходить от дочернего объекта к родительскому.

Вот простой пример (демонстрация jsFiddle):

var test = {"hello":{"foo":{"bar":"world"}}};
var proxy = ObservableSlim.create(test, true, function() { return false });

function traverseUp(childObj) {
    console.log(JSON.stringify(childObj.__getParent())); // returns test.hello: {"foo":{"bar":"world"}}
    console.log(childObj.__getParent(2)); // attempts to traverse up two levels, returns undefined because test.hello does not have a parent object
};

traverseUp(proxy.hello.foo);

Ответ 6

Дэвид Дорвард прямо здесь. Самое простое решение, tho, было бы получить доступ к user.Name, так как user эффективно является одиночным.

Ответ 7

Старый вопрос, но почему вы не можете просто сделать что-то вроде этого:

var user = {
        Name: "Some user",
        Methods: {
            ShowGreetings: function() {
                    // at this point i want to access variable "Name", 
                    //i dont want to use user.Name
                    // **please suggest me how??**
                    var thisName = user.Name; //<<<<<<<<<
                 },
            GetUserName: function() { }
        }
    }

Потому что вы будете вызывать только user.Methods.ShowGreetings() после того, как пользователь был создан. Значит, вы узнаете о переменной "пользователь", когда хотите использовать ее имя?

Ответ 8

Как насчет этого пути?

user.Methods.ShowGreetings.call(user, args);

Итак, вы можете получить доступ к user.Name в ShowGreetings

var user = {
    Name: "Some user",
    Methods: {
        ShowGreetings: function(arg) {
            console.log(arg, this.Name);
        },
        GetUserName: function() { }
    },
    Init: function() {
        this.Methods.ShowGreetings.call(this, 1);
    }
};

user.Init(); // => 1 "Some user"

Ответ 9

Как вариант:

var user = (obj => { 
    Object.keys(obj.Methods).map(option => {
        const currOpt = obj.Methods[option];
        if (currOpt instanceof Function) {
            obj.Methods[option] = currOpt.bind(obj);
        };
    });
    return obj;
})({
    Name: "Some user",
    Methods: {
        Greeting: function () { return this.Name },
        GetUserName: function() { console.log(this) }
    },
});

Но я не знаю, почему кто-то может использовать этот странный подход

Ответ 10

// Make user global
window.user = {
    name: "Some user",
    methods: {
        showGreetings: function () {
            window.alert("Hello " + this.getUserName());
        },
        getUserName: function () {
            return this.getParent().name;
        }
    }
};
// Add some JavaScript magic
(function () {
    var makeClass = function (className) {
        createClass.call(this, className);
        for (key in this[className]) {
            if (typeof this[className][key] === "object") {
                makeClass.call(this[className], key);
            }
        }
    }
    var createClass = function (className) {
        // private
        var _parent = this;
        var _namespace = className;
        // public
        this[className] = this[className] || {};
        this[className].getType = function () {
            var o = this,
                ret = "";
            while (typeof o.getParent === "function") {
                ret = o.getNamespace() + (ret.length === 0 ? "" : ".") + ret;
                o = o.getParent();
            }
            return ret;
        };
        this[className].getParent = function () {
            return _parent;
        };
        this[className].getNamespace = function () {
            return _namespace;
        }
    };
    makeClass.call(window, "user");
})();

user.methods.showGreetings();

Ответ 11

Я наткнулся на этот старый пост, пытаясь вспомнить, как решить проблему. Вот решение, которое я использовал. Это происходит от шаблонов проектирования Pro JavaScript от Harmes и Diaz (Apress 2008) на стр. 8. Вам нужно объявить функцию, а затем создать ее новый экземпляр, как показано ниже. Обратите внимание, что метод Store может получить доступ к "this".

function Test() {            
  this.x = 1;
}
Test.prototype = {
  Store: function (y) { this.x = y; },
}
var t1 = new Test();
var t2 = new Test();    
t1.Store(3);
t2.Store(5);    
console.log(t1);
console.log(t2);