Как мне создать дочерний класс класса Function Javascript? - PullRequest
0 голосов
/ 27 января 2010

Я хотел бы создать класс Javascript, который я могу использовать следующим образом:

var f = new myFunction(arg1, arg2);
f.arg1; // -> whatever was passed as arg1 in the constructor
f();
f instanceof myFunction // -> true
typeof f // -> function

Я могу рассматривать его как обычный объект, даже добавляя нативный Function объект в цепочку прототипов, но я не могу вызвать его как функцию:

function myFunction(arg1, arg2) {
  this.arg1 = arg1;
  this.arg2 = arg2;
}
myFunction.prototype = Function
var f = new myFunction(arg1, arg2); // ok
f.arg1; // ok
f(); // TypeError: f is not a function, it is object.
f instanceof myFunction // -> true
typeof f // -> object

Я могу заставить конструктор вернуть функцию, но тогда это не экземпляр myFunction:

function myFunction(arg1, arg2) {
  var anonFunction = function() {
  };
  anonFunction.arg1 = arg1;
  anonFunction.arg2 = arg2;
  return anonFunction;
}
var f = new myFunction(arg1, arg2); // ok
f.arg1; // ok
f(); // ok
f instanceof myFunction // -> false
typeof f // -> function

Есть предложения? Я должен добавить, что я действительно хочу избежать использования new Function(), так как я ненавижу блоки строк кода.

Ответы [ 5 ]

1 голос
/ 27 января 2010

function Foo() { var o = function() {return "FOO"}; o.__proto__ = Foo.prototype; return o; }

(new Foo()) instanceof Foo: правда

(new Foo())(): FOO

1 голос
/ 27 января 2010

Прежде всего, вы, вероятно, должны подумать о другом способе сделать это, потому что он вряд ли будет переносимым.Я просто собираюсь принять Rhino за мой ответ.

Во-вторых, я не знаю ни одного способа в Javascript назначить тело функции после построения.Тело всегда указывается при создании объекта:

// Normal function definitions
function doSomething() { return 3 };
var doSomethingElse = function() { return 6; };

// Creates an anonymous function with an empty body
var doSomethingWeird = new Function;

Теперь для каждого объекта есть нестандартное расширение Mozilla в виде свойства __proto__.Это позволяет вам изменить цепочку наследования любого объекта.Вы можете применить это к своему объекту функции, чтобы дать ему другой прототип после построения:

// Let's define a simple prototype for our special set of functions:
var OddFunction = {
  foobar: 3
};

// Now we want a real function with this prototype as it's parent.
// Create a regular function first:
var doSomething = function() {
  return: 9;
};

// And then, change it's prototype
doSomething.__proto__ = OddFunction;

// It now has the 'foobar' attribute!
doSomething.foobar;  // => 3
// And is still callable too!
doSomething();  // => 9

// And some of the output from your example:
doSomething instanceof OddFunction;  // => true
typeof doSomething;  // => function
0 голосов
/ 28 января 2010

Вот то, что я думаю, более javascript способ делать то, что вы хотите, за исключением того, что он не использует instanceof для объектов, но внутренний.

var f = function(arg1, arg2){
    return {
        instanceOf:arguments.callee,
        arg1:arg1,
        arg2:arg2
    };
};
var fn = f(1, function(p){ alert(p); });
fn.arg1; // 1
fn.instanceOf === f; //true
typeof f; //function
typeof fn; //object
fn.arg2('hello'); //show alert hello
0 голосов
/ 27 января 2010

Я не знаю, почему вы хотели бы сделать что-то подобное. Но вот фрагмент, который приближается,

function MyFunction(arg1, arg2)
{
    this.firstProp = arg1;
    this.secondProp = arg2;
}

var f = function(arg1, arg2) {
    return new MyFunction(arg1, arg2);
}(12,13);

alert("Arg1 " + f.firstProp) // 12;

alert("Arg2 " + f.secondProp) // 13;

alert(f instanceof MyFunction) // true;
0 голосов
/ 27 января 2010

Это невозможно. Если это должен быть экземпляр вашей функции, то это должен быть объект. Зачем тебе это?

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