Я делаю что-то не так с этим прототипом в JavaScript, есть идеи? - PullRequest
2 голосов
/ 07 июля 2011

Следующий код не создает прототип, как я думал.Кто-нибудь может увидеть, что я делаю не так?

var A = function () {
    return {
        workingTest: function () {return "OK";}
    };
};

A.prototype.notWorkingTest = function () {return "Not so much";};

var a = new A();

a.workingTest(); // "OK"
a.notWorkingTest(); // TypeError: "undefined_method"

Есть идеи?Я думал, что это правильный путь для расширения классов JS, но я что-то упускаю.

Ответы [ 5 ]

3 голосов
/ 07 июля 2011

Измените А на

var A = function () {
  this.workingTest = function () {return "OK";};
};

Проблема в том, что ваша оригинальная функция A создавала и возвращала прямой экземпляр Object вместо использования экземпляра A, который был создан оператором new и привязан к this.

Чтобы понять это, попробуйте запустить

var B = function () { return { x: 42 }; }
var C = function () { this.x = 42; }
var b = new B;
var c = new C;
alert("b.constructor === B : " + (b.constructor === B));  // false
alert("b.constructor === Object : " + (b.constructor === Object));  // true
alert("c.constructor === C : " + (c.constructor === C));  // true

Так как B возвращает новый объект, возвращаемое им значение больше не является instanceof B и не использует прототип B.

0 голосов
/ 07 июля 2011

Вы определили A как функцию, которая возвращает литерал объекта.Использование ключевого слова new при вызове функции подразумевает, что это особый тип функции, а именно конструктор.Конструкторы в JavaScript должны быть написаны особым образом, устанавливая свойства с помощью ключевого слова this.

var A = function () {
  this.workingTest = function () {return "OK";};
};
0 голосов
/ 07 июля 2011

В современном браузере вы можете сохранить интересный подход к созданию прототипов с помощью:

var A = {
  workingTest: function () {return "OK";}
};
A.notWorkingTest = function () {return "Yes it does";};

var a = Object.create (A);
a.workingTest(); // "OK"
a.notWorkingTest(); // "Yes it does"

a.extending = function () {return "extended";};
var b = Object.create(a);
b.workingTest(); // "OK"
b.extending();  // "extended"

Работает в соответствии со спецификацией ES5.

0 голосов
/ 07 июля 2011

Поскольку вы расширяете прототип A, а new A() возвращает «анонимный» объект.

0 голосов
/ 07 июля 2011

Поскольку A возвращает отдельный объект, a не является экземпляром класса A; скорее это обычный объект, который возвращается функцией A.
Он не подключен к A или prototype вообще.

Вместо этого вам нужно присвоить workingTest для this внутри конструктора и вообще ничего не возвращать:

var A = function () {
    this.workingTest = function () { return "OK"; };
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...