Как использовать Basic HTTP Auth с веб-сервисом REST (Java + Jersey)?

  1. Почему этот журнал 5, undefined, undefined, 6 вместо undefined, 6, undefined, 6?
  2. Почему замена прототипа не меняет прототип всех экземпляров объекта, как это обычно бывает?
blockquote>

По сути, это сводится к тому, что ссылки на объекты - это значения, а скорее числа, которые указывают механизм JavaScript (V8 в вашем случае), где объект находится в памяти. Когда вы копируете значение, вы делаете именно это: вы копируете значение. Копирование ссылки на объект делает копию ссылки (а не объекта) и никоим образом не связывает место назначения этого значения с источником значения больше, чем это связывает b с a:

var a = 5;
var b = a;
a = 6;
console.log(b, a); // 5, 6

Итак, ваш код регистрирует то, что он регистрирует, и не изменяет прототип instance1, по той же причине этот код записывает то же самое и не меняет значение instance1.p:

var foo = {x: 5};
var instance1 = {p: foo};

foo = {y: 6};

var instance2 = {p: foo};

console.log(instance1.p.x, instance1.p.y, instance2.p.x, instance2.p.y);

Давайте набросим на него некоторое ASCII-искусство (ну, Unicode-art), которое также ответит:

  1. Что делает двигатель V8, шаг за шагом, в этом коде?
blockquote>

После запуска этого:

var obj = function() {};
obj.prototype.x = 5;

var instance1 = new obj();

... у вас есть что-то примерно так в памяти (игнорируя некоторые детали):

                 +−−−−−−−−−−−−−−−−−−−−−+             
                 |     (function)      |             
                 +−−−−−−−−−−−−−−−−−−−−−+             
obj−−−>| prototype |−−−−−−−−−−−+
                 +−−−−−−−−−−−−−−−−−−−−−+            \ 
                                                     \     
                                                      \    
                                                       \   +−−−−−−−−−−+
                                                        +−>| (object) |
                                                       /   +−−−−−−−−−−+
                                                      /    | x<5>     |
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+    /     +−−−−−−−−−−+
                      |         (object)        |   /
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+  /
instance1−−>| [[Prototype]] |−+
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+

Поскольку ссылки на объекты являются значениями, а присваивание всегда копирует значения , когда V8 (или любой другой движок) создает instance1, он копирует значение из obj.prototype (показано здесь концептуально как ) на внутренний слот instance1 [[Prototype]].

Тогда, когда вы делаете

obj.prototype = {y: 6};

... вы меняете значение в obj.prototype (показано здесь как изменение на ), но это не влияет на значение ( ]) в слоте instance1 [[Prototype]]:

                 +−−−−−−−−−−−−−−−−−−−−−+                   
                 |     (function)      |                   
                 +−−−−−−−−−−−−−−−−−−−−−+                   +−−−−−−−−−−+
obj−−−>| prototype |−−−−−−−−−−−−−−−−−−>| (object) |
                 +−−−−−−−−−−−−−−−−−−−−−+                   +−−−−−−−−−−+
                                                           | y<6>     |
                                                           +−−−−−−−−−−+

                                                           +−−−−−−−−−−+
                                                        +−>| (object) |
                                                       /   +−−−−−−−−−−+
                                                      /    | x<5>     |
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+    /     +−−−−−−−−−−+
                      |         (object)        |   /
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+  /
instance1−−>| [[Prototype]] |−+
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+

... и поэтому, когда вы делаете

var instance2 = new obj();

... у вас есть:

                 +−−−−−−−−−−−−−−−−−−−−−+                   
                 |     (function)      |                   
                 +−−−−−−−−−−−−−−−−−−−−−+                   +−−−−−−−−−−+
obj−−−>| prototype |−−−−−−−−−−−−−−−−+−>| (object) |
                 +−−−−−−−−−−−−−−−−−−−−−+               /   +−−−−−−−−−−+
                                                      /    | y<6>     |
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+    /     +−−−−−−−−−−+
                      |         (object)        |   /      
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+  /       
instance2−−>| [[Prototype]] |−+        +−−−−−−−−−−+
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+       +−>| (object) |
                                                       /   +−−−−−−−−−−+
                                                      /    | x<5>     |
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+    /     +−−−−−−−−−−+
                      |         (object)        |   /
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+  /
instance1−−>| [[Prototype]] |−+
                      +−−−−−−−−−−−−−−−−−−−−−−−−−+

... что объясняет результат console.log.

  1. EDIT: Как мне пойти на смену прототипа всех экземпляров?
blockquote>

Если вы хотите фактически изменить какой объект, который они используют в качестве своего прототипа, вы можете сделать это только в том случае, если у вас есть ссылка на экземпляр (ы), который вы хотите изменить, и только на JavaScript-движке, поддерживающем функции ES2015, с помощью Object.setPrototypeOf или (в среде веб-браузера, и если объект в конечном итоге наследуется от Object.prototype) через аксессуар __proto__ свойство (не рекомендуется):

Object.setPrototypeOf(instance1, obj.prototype);

setPrototypeOf изменяет значение внутреннего слота [[Prototype]] в объекте (как и установка __proto__, если объект имеет его) .

Вы не можете этого сделать, если у вас нет ac

Я не думаю, что вы это делаете, учитывая этот вопрос, но если вы просто хотите изменить состояние объекта, который они используют в качестве своего прототипа (возможно, добавив y), вы можете, конечно, просто установить на нем свойства, а так как прототипное наследование JavaScript является «живым» (есть прямая ссылка на прототип из экземпляра), вы можете затем получить доступ к этим свойствам в любом экземпляре, который наследуется от прототипа, даже если они были созданы до того, как вы внесли изменение:

var Example = function() { };
Example.prototype.x = 5;

var instance1 = new Example();
console.log(instance1.x, instance1.y); // 5, undefined

Example.prototype.y = 6;
console.log(instance1.x, instance1.y); // 5, 6
13
задан user2416728 5 July 2013 в 22:32
поделиться