Что означает «экземпляр» в Javascript? - PullRequest
8 голосов
/ 10 августа 2011

Ответ на этот вопрос: Каково начальное значение свойства прототипа функции JavaScript?

имеет это предложение:

Начальным значением прототипа для любого вновь созданного экземпляра функции является новый экземпляр объекта

Насколько я знаю, в Javascript нет классов, и слово «экземпляр» для них не имеет смысла в моей голове. Как следует интерпретировать «экземпляр» в Javascript?

Извините, мне не хватает представителя, чтобы поставить вопрос в ветке комментариев к этому ответу.

Ответы [ 7 ]

16 голосов
/ 10 августа 2011

Вы правы, что JavaScript не имеет классов (пока), но у него есть функции-конструкторы, оператор instanceof, который определяет отношения между объектами и конструкторами, и форма наследования, основанная на цепочках прототипов.

obj instanceof ctor истинно, когда ctor.prototype находится в цепочке прототипов obj.

По модулю предостережения ниже, вы можете реализовать instanceof в EcmaScript 5, таким образом

function isInstanceOf(obj, ctor) {
  var proto = ctor.prototype;
  if (typeof obj === "object" || typeof obj === "function") {
    while (obj) {
      if (obj === proto) { return true; }
      obj = Object.getPrototypeOf(obj);
    }
  }
  return false;
}

Если вы не будете переделывать прототипы (o = new MyConstructor(); MyConstructor.prototype = somethingElse), это должен быть случай, когда new MyConstructor() instanceof MyConstructor.

Раздел 15.3.5.3 объясняет это подробно.

15.3.5.3 [[HasInstance]] (V)

Предположим, что F является объектом Function.

Когда внутренний метод [[HasInstance]] для F вызывается со значением V, следующие шагипринимаются:

  1. Если V не является объектом, вернуть false.
  2. Пусть O будет результатом вызова внутреннего метода [[Get]] для F с именем свойства "prototype"".
  3. Если Type (O) не является Object, выдать исключение TypeError.
  4. Repeat

    1. Пусть V будет значением внутреннего свойства [[Prototype]] для V.
    2. Если V равно нулю, вернуть false.
    3. Если O и V ссылаются на один и тот же объект, верните true.

Это не вся история, потому что хост-объектам (таким как узлы DOM) разрешено реализовыватьвнутренний метод [[HasInstance]], как им нравится, но большинство браузеров реализуют хост-объекты так, чтобы они вели себя как можно ближе к нативным объектам.

5 голосов
/ 10 августа 2011

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

function Foo(initialValue) {
    this.value = initialValue || 0;
}
var foo = new Foo(17);
var fooIsAFoo = foo instanceof Foo;  // true!
var fooIsAnObject = foo instanceof Object; // also true!  We have inheritance here :)
3 голосов
/ 10 августа 2011

В JS функция - это Объект. Требуется время, чтобы привыкнуть к этому, но это правда. Бросьте это немного, и код, который вы видите, использует другие, будет иметь больше смысла. Если вы видели Javascript, где люди передают функцию () {} в качестве параметра другой функции, это доказывает, что функции являются объектами первого класса.

Как только вы сможете обернуть это вокруг (это заняло у меня некоторое время), вам нужно понять, что если вы создадите функцию, вы можете получить ее Новый экземпляр. Смотрите следующий код:

function FooName(){
    var name;
    this.setName = function(n){
        this.name = n;
    }
    this.getName = function(){
        return this.name;
    }
}
var n1 = new FooName();
var n2 = new FooName();
n1.setName("FOO");
n2.setName("BAR");

На данный момент у вас есть два экземпляра метода FooName: n1 и n2. В JS принято заключать, что ваша инстанцируемая функция называет первую букву в верхнем регистре вместо первой буквы в нижнем регистре. В этом примере я указываю, что моя функция может быть запущена, называя ее FooName вместо fooName. Я надеюсь это имеет смысл.

В приведенном выше примере n1 имеет три свойства. Частное свойство name, открытое свойство setName и открытое свойство getName. Каждый раз, когда я создаю экземпляр нового FooName, будут создаваться копии getName и setName. Это может тратить пространство в памяти. Поскольку getName и setName не собираются меняться, мне не нужна новая копия для каждого экземпляра FooName. Здесь и появляются прототипы.

Вы можете сказать следующее, и тогда getName и setName будут существовать только один раз в памяти, освобождая память, что хорошо.

FooName.prototype.setName = function(n){
    this.name = n;
}
FooName.prototype.getName = function(){
    return this.name;
}

Если вы удалите getName и setName из функции FooName, то теперь у вас будет «класс» FooName, имеющий два метода, getName и setName.

Поиграй с этим. Дайте мне знать, если у вас есть вопросы.

1 голос
/ 10 августа 2011

Javascript не использует классическое наследование, он использует прототип наследования , где все является «объектом», а наследование осуществляется путем клонирования, например:

var myPrototype = function() {
   var privateMember = "I am private";
   var publicMember = "I am public";
   var publicMethod = function () {
       alert(privateMember); 
   }
   return {
      publicMember = publicMember,
      publicMethod = publicMethod
   }
}

var myInstace = new myPrototype();
myInstance.publicMethod();

здесь myInstance можно сказать, что он является "экземпляром" myPrototype, но в действительности это произошло с использованием ключевого слова new, которое вы клонировали myPrototype для создания myInstance.

1 голос
/ 10 августа 2011

В JavaScript функции являются первоклассными объектами, это означает, что вы можете обращаться с ними как с любым объектом.

// Определить класс

   function User(name,age)
    {
        this.Name=name;
        this.Age=age
    }

// create insatnces

var user1= new User('Demo1','50');
var user2= new User('Demo2','100');


alert(user1.Name);
alert(user2.Name);

http://jsfiddle.net/praveen_prasad/hmUku/

http://en.wikipedia.org/wiki/First-class_function

0 голосов
/ 10 августа 2011

Так что теперь я изготовил страницу, описывающую то, что, по-моему, все вы, ребята *, говорите: https://docs.google.com/document/d/1VvqqO2LMmilLbIvcU2JHI9ifaoMs-DB-farEzwuVuwM/edit?hl=da

, проиллюстрировано красивой графикой:)

с уважением, Джон

* и эта ссылка: http://trephine.org/t/index.php?title=Understanding_the_JavaScript_new_keyword

0 голосов
/ 10 августа 2011

Javascript является объектно-ориентированным, поэтому у него есть классы.Просто нет явной директивы class, как это было бы в других языках ООП.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...