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

Как создать приватную переменную, доступную для функции Prototype?

Я пытаюсь получить более глубокое удержание прототипального наследования и создания классов (я знаю, есть другие способы, но для этого я пытаюсь понять прототипы.) Мой вопрос: использование следующего кода Например, есть ли способ создать частные переменные внутри Tree и Fruit, которые не будут возвращены с помощью функции, но все еще доступны для прототипов функций genus и bulk?

var Tree = function ( name, size ) { 
    this.name = name;
    this.size = size;
};

Tree.prototype.genus = function(){
    return ((typeof this.name !== 'undefined') ? this.name : 'Hybridicus Maximus');
};
Tree.prototype.bulk = function(){
    return ((typeof this.size !== 'undefined') ? this.size : '8') + ' ft';
};


var Fruit = function( name, size ) { 
    this.name = name;
    this.size = size;
};

Fruit.prototype = new Tree();
// Fruit.prototype = Tree.prototype; -- I know this can be used, too.

Fruit.prototype.bulk =  function(){
    return ((typeof this.size !== 'undefined') ? Math.floor(this.size / 2) : '4') + ' lbs';
};

var pine = new Tree('Pine', 9);
var apple = new Fruit('Apple', 6);

console.log(pine.genus(), pine.bulk()); // Outputs: "Pine 9 ft"
console.log(apple.genus(), apple.bulk()); // Outputs: "Apple 3 lbs"

EDIT: я пытаюсь заменить this.name и this.size частными переменными, доступ к которым можно получить в функциях прототипа. Извините за отсутствие ясности!

4b9b3361

Ответ 1

Да. Вы можете сделать это:

(function() {
  var private = "hi";

  Tree.prototype.genus = function(){
    return ((typeof this.name !== 'undefined') ? this.name : 'Hybridicus Maximus');
  };
  Tree.prototype.bulk = function(){
    return ((typeof this.size !== 'undefined') ? this.size : '8') + ' ft';
  };
})();

Теперь это будет предоставлять частную переменную, которую могут видеть эти функции, но это будет приватная переменная класса. Все экземпляры будут использовать одну и ту же переменную, другими словами. Если вам нужна приватная переменная на один экземпляр, вы должны сделать это в конструкторе (или в методе "init" или что-то еще), то есть методы, которые разделяют этих рядовых, также должны быть созданы там. (Конечно, вы могли бы поместить функцию в прототип, который создавал бы методы экземпляра во время построения.)

edit — Одна вещь, которую вы могли бы сделать, - использовать такую ​​технику, чтобы построить механизм, такой как jQuery ".data()", так что у вас будет переменная класса, которая будет служить местом для хранения значений каждого экземпляра. Это было бы неловко, но это было бы выполнимо.

Ответ 2

Это то, о чем я писал в блоге о "Классы" , "Частные члены" и "Прототипальное наследование" в JavaScript. В принципе, вы хотите создать функцию private access accessor, уникальную для каждого объекта, а затем использовать эти методы прототипа для этой частной функции доступа, снабжая ее ключом, доступным только в закрытии:

(function(_) {
  Tree = function ( name, size ) { 
    var hidden = {
      name: name,
      size: size
    };
    this._ = function($) {
      return _ === $ && hidden;
    };
  };

  Tree.prototype.genus = function(){
    return ((typeof this._(_).name !== 'undefined') ? this._(_).name : 'Hybridicus Maximus');
  };
  Tree.prototype.bulk = function(){
    return ((typeof this._(_).size !== 'undefined') ? this._(_).size : '8') + ' ft';
  };

  Fruit = function( name, size ) { 
    Tree.apply(this, arguments);
  };
  Fruit.prototype = new Tree();
  // Fruit.prototype = Tree.prototype; -- I know this can be used, too.

  Fruit.prototype.bulk =  function(){
    return ((typeof this._(_).size !== 'undefined') ? Math.floor(this._(_).size / 2) : '4') + ' lbs';
  };
})({});



var pine = new Tree('Pine', 9);
var apple = new Fruit('Apple', 6);

console.log(pine.genus(), pine.bulk()); // Outputs: "Pine 9 ft"
console.log(apple.genus(), apple.bulk()); // Outputs: "Apple 3 lbs"

console.log(pine._(), pine._({})); // Outputs: "false false" because outside of closure

Вы заметите, что в последней строке показано, что частные переменные недоступны вне закрытия и, следовательно, не могут быть получены сторонним кодом, если они не доступны доступной функцией доступа.

Ответ 3

Это можно легко достичь, как это

function SharedPrivate(){
  var private = "secret";
  this.constructor.prototype.getP = function(){return private}
  this.constructor.prototype.setP = function(v){ private = v;}
}

var o1 = new SharedPrivate();
var o2 = new SharedPrivate();

console.log(o1.getP()); // secret
console.log(o2.getP()); // secret
o1.setP("Pentax Full Frame K1 is on sale..!");
console.log(o1.getP()); // Pentax Full Frame K1 is on sale..!
console.log(o2.getP()); // Pentax Full Frame K1 is on sale..!
o2.setP("And it only for $1,795._");
console.log(o1.getP()); // And it only for $1,795._

Очевидно, что ключевым моментом является создание маршрута доступа к частной переменной путем использования замыкания, а затем совместного использования этой точки доступа между создаваемыми объектами. Идеальным случаем является использование точки доступа в качестве прототипа объектов, создаваемых для естественного обмена. Соответственно, та же функциональность может быть достигнута путем использования шаблона factory и Object.create() следующим образом:

function SharedPrivate(){
var priv = "secret";
return {gp : function(){return priv},
        sp : function(v){priv = v}
       }
}
sharedProto = SharedPrivate(); // priv is now under closure to be shared
var p1 = Object.create(sharedProto); // sharedProto becomes o1.__proto__
var p2 = Object.create(sharedProto); // sharedProto becomes o2.__proto__

Прототипная структура JavaScript - золотая.!