2013-03-10 6 views
1

Название действительно сбивает с толку, я не мог найти лучшего.Получение ссылки на объект, который содержит свойство, являющееся конструктором

Предположим, у меня есть:

var A = function(){ 
    this.pa = { x: 1 }; 
}; 

A.prototype.B = function(){ 
    this.pb = /* a reference to { x: 1 } */; 
}; 

var a = new A(); 
var b = new a.B(); 
console.log (b.pb.x); //should print 1 
a.pa.x = 2; 
console.log (b.pb.x); //should print 2 

Я хочу сохранить в pb ссылку на pa объекта. Является ли это возможным?

+1

'новый aB' не создает связь между новым экземпляром 'A.prototype.B' и' a'. Конструкторские вызовы очень отличаются от вызовов методов тем, что они не получают ссылку на цель метода. –

+0

Вот почему я спрашиваю. Любой взлом, чтобы получить ссылку на 'a'? –

+0

Вы можете создать свойство 'b' getter, которое возвращает связанную валюту. –

ответ

0

Ну, это не совсем то, что я хочу, но это очень близко:

var A = function (pa){ 
    this.pa = pa; 
}; 

A.prototype.B = function (a){ 
    if (this instanceof A.prototype.B){ 
     if (!a) throw "error"; 
     this.pb = a.pa; 
     return; 
    } 
    return new A.prototype.B (this); 
}; 

var a = new A ({ x: 1 }); 
var b = a.B(); 
console.log (b.pb.x); //1 
a.pa.x = 2; 
console.log (b.pb.x); //2 

new a.B() //throws "error" 
+0

Это не работает, если вы назначили 'new A' чем-нибудь еще, чем' a'. – Bergi

+0

Можете ли вы уточнить комментарий? Я не понимаю :) –

+0

Извините, я не заметил, что 'a' был параметром конструктора и что вы что-то передали. – Bergi

0
var A = function(){ 
    this.pa = { x: 1 }; 
}; 

A.prototype.B = function (a){ 

    this.pb = a.pa; 
}; 
var a = new A(); 

var b = new a.B(a); 
console.log(b.pb.x); //should print 1 
a.pa.x = 2; 
console.log(b.pb.x); 
+0

Это не работает, если вы назначили 'new A' для чего-либо еще, кроме' a'. – Bergi

+0

Извините, если я не понимаю вас, но вы можете объяснить, что означает u, потому что это не сработает, если вы назначите новый A другому, чем a. Потому что, хотя ваше решение более элегантно, разве ваш B все еще привязан к конкретному экземпляру A? – Rohit

+0

О, извините, я полностью забыл, что 'a' был параметром для вашего конструктора' B'; Я предположил, что вы пытались получить доступ к глобальной переменной 'a'. – Bergi

1

Функция used as a constructor имеет только ссылку на новый экземпляр, унаследовав от своего прототипа.

Для того, чтобы это сохранить ссылку на оригинальный A Например, вам нужно будет поставить B конструктор в затворе:

function A() { 
    var that = this; 
    this.pa = { x: 1 }; 

    this.B = function() { 
     this.pb = that.pa; 
    }; 
}; 

var a = new A(); 
var b = new a.B(); 
console.log (b.pb.x); // does print 1 
a.pa.x = 2; 
console.log (b.pb.x); // does print 2 

Однако это имеет тот недостаток, что создание нового B конструктора (с его собственный объект-прототип) для каждого экземпляра A. Лучше бы что-то вроде

function A() { 
    this.pa = { x: 1 }; 
} 
A.B = function() { 
    this.pb = null; 
}; 
A.prototype.makeB = function() { 
    var b = new A.B(); 
    b.pb = this.pa; 
    return b; 
}; 
// you can modify the common A.B.prototype as well 

var a = new A(); 
var b = a.makeB(); 
console.log (b.pb.x); // does print 1 
a.pa.x = 2; 
console.log (b.pb.x); // does print 2 

Тем не менее, мы могли бы смешивать эти два подхода, так что у вас есть только один прототип, но различные конструкторы:

function A() { 
    var that = this; 
    this.pa = { x: 1 }; 

    this.B = function() { 
     this.pb = that.pa; 
    }; 
    this.B.prototype = A.Bproto; 
} 
A.Bproto = { 
    … 
}; 
+0

Я не могу использовать второй вариант, потому что метод' B' называется 'create() '. Фактически, настоящее имя 'B' является' User', поэтому я не могу создать экземпляр пользователя с помощью метода makeUser() ',' createUser() ',' newUser() 'или' newUserInstance() '; это вопрос дизайна –

+0

Первый вариант - это то, чего я хочу достичь, но я должен создать прототип функций 'B' внутри конструктора' A'. Каждый раз, когда вызывается новый A', создается новый прототип 'B'. Я мог бы использовать это решение, потому что оно действительно и работает, но оно неэффективно и возвращает меня в прошлое, в ранние годы, когда я начинал изучать javascript и делал уродливые вещи, подобные этому. –

Смежные вопросы