Nano Hash - криптовалюты, майнинг, программирование

javascript как создать ссылку

Не могли бы вы предложить какие-либо обходные пути для реализации ссылки на переменную с использованием замыканий или любых других приемов?

createReference = function() {
    // TODO: how to implement?
};

var x = 5;
var refX = createReference(x); // could be any parameters needed to implement the logic
x = 6;
alert(refX()); // should alert 6

Как насчет передачи контекста в качестве первого аргумента и передачи имени переменной (в виде строки), а затем каким-то образом оценить эту ссылку в предопределенном контексте. Возможно ли это?

Вот более полный сценарий:

createReference = function(context, prop) {
    return function() {
        return context[prop];
    };
};

Provider = function() {
};
Provider.prototype.x = 5;
Provider.prototype.getXRef = function() {
    return createReference(this, 'x');
};
Provider.prototype.incrementX = function() {
    this.x = this.x + 1;
};

var provider = new Provider();
var refX = provider.getXRef();
provider.incrementX();
alert(refX());

  • В будущем, пожалуйста, не задавайте свои вопросы в виде встроенных комментариев в код. Из-за этого очень трудно увидеть вопрос, и вы рискуете, что люди закроют его как не вопрос. 28.04.2011
  • Я рад, что ответил на ваш вопрос, но в вашем обновленном сценарии, почему бы просто не использовать: Provider.prototype.getXRef = function () { var that = this; return function() { return that.x; }; };, чтобы вы могли избежать использования строки? 29.04.2011
  • createReference — универсальный способ сделать трюк. Тогда в другой ситуации я просто воспользуюсь этим универсальным способом. В вашем комментарии: холодно не быть методом Provider.prototype.getXRef, но в каком-то другом методе, возможно, я хотел бы передать ссылку на какой-то другой объект в качестве параметра обратного вызова и т. д. Будет более читабельно написать createReference(this, 'x'), затем функция () { var that = this; return function() { return that.x; }; }; в повседневном использовании. 29.04.2011
  • Понимаю. Пожалуйста, взгляните на последнее редактирование моего ответа для более общего решения. Я действительно думаю, что вам следует избегать использования строк, но я оставлю это на ваше усмотрение :) 29.04.2011

Ответы:


1

Вы должны использовать строку имени переменной, но я думаю, что это самое близкое, что вы когда-либо получали в JavaScript:

var createReference = function (context, prop) {
  return function () { return context[prop]; };
};

var x = 5;
var refX = createReference(this, 'x');
x = 6;

alert(refX()); // alerts 6

Изменить:

В вашем обновленном сценарии было бы лучше использовать закрытие напрямую, чтобы вам не приходилось использовать строку имени переменной:

var createReference = function (context, func) {
    return function () { return func.call(context); }
};

Provider = function() {
};
Provider.prototype.x = 5;
Provider.prototype.getXRef = function() {

    return createReference(this, function () { return this.x; });

    // OR if you happen to be running in a 
    // JavaScript 1.8 environment like Firefox 3+,
    // you can use "expression closures" for more
    // concise code:

    // return createReference(this, function () this.x);
};
Provider.prototype.incrementX = function() {
    this.x = this.x + 1;
};

var provider = new Provider();
var refX = provider.getXRef();
provider.incrementX();
alert(refX()); // alerts 6
28.04.2011
  • Да, хорошие альтернативы. Но javascript в любом случае не сохраняет тип, и не будет ошибок «времени компиляции» при неправильном использовании имен, поэтому я думаю, что лучше использовать подход с более коротким и немного более читаемым (как по мне) кодом в пользу подхода без строк. 29.04.2011

  • 2

    В JavaScript вы не можете передавать примитивные значения (числа, строки и т. д.) по ссылке. Однако каждый объект, который вы передаете, всегда будет ссылкой. (включая массивы)

    Чтобы использовать ваш пример:

    var foo = { x: 5 };
    var refFoo = foo;
    
    // foo.x => 5
    // refFoo.x => 5
    
    foo.x = 6;
    
    // foo.x => 6
    // refFoo.x => 6
    
    28.04.2011
  • Есть ли способ сделать это с помощью new Number(4)? Это объект. Можете ли вы (повторно) установить его значение, чтобы «оставить его живым» и передать его? Что-то вроде n=new Number(4); n2=n; n2.setValue(7); alert(n); 28.04.2011
  • Да, это будет объект. Практически все в JS технически является объектом. Однако скалярные значения (числа, строки и т. д.) вообще не передаются по ссылке, просто так работает JS. 29.04.2011
  • Я знаю, что это объект, но как изменить значение объекта Number? .setValue не существует, и вы не можете переназначить новый объект, потому что тогда вы потеряете ссылку на n. Не работают: n2=7;, n2=new Number(7);, n2.setValue(7);. Первые два теряют ссылку, третьего не существует. Как изменить значение числового объекта? 29.04.2011

  • 3

    Вы не можете просто сделать x референсом.

    28.04.2011

    4

    В качестве ссылки могут быть переданы только нескалярные типы, и они всегда будут передаваться в качестве ссылки:

    var reference = {};
    my_function(reference);
    console.log(reference); // will show property - a property value
    
    function my_function(my_reference) {
        my_reference.property = "a property value";
    }
    
    var not_a_reference = [];
    my_function(not_a_reference);
    console.log(not_a_reference); // will NOT show 'a value'
    
    function my_function() {
        my_reference.push("a value");
    }
    

    Ближе к вашему примеру:

    function show(value) {
        alert(value.data);
    }
    
    var value = { 'data': 5 };
    show(value); // alerts 5
    value.data = 6;
    show(value); // alerts 6
    
    28.04.2011

    5

    Поскольку объекты всегда будут статической ссылкой, вы можете сделать это:

    var o = {};
    o.x = 5;
    var oRef = o;
    alert(oRef.x); // -> 5
    o.x = 6;
    alert(oRef.x); // -> 6
    
    28.04.2011
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..