SORU
24 EYLÜL 2011, CUMARTESİ


Nasıl javascript fonksiyonlarıyla mı ?

// Don't break the function prototype.
// pd - https://github.com/Raynos/pd
var proto = Object.create(Function.prototype, pd({
  "prop": 42
}));

var f = function() { return "is a function"; };
f.__proto__ = proto;

console.log(f.hasOwnProperty("prop")); // false
console.log(f.prop); // 42
console.log(f()); // "is a function"

.__proto__ standart dışı ve önerilmiyor.

Nasıl prototypically devralmak için bir nesne yaratmak ama o nesnenin bir işlevi olmak zorunda mıyım.

Object.create bir Nesne değil, bir İşlevi.

new Constructor bir Nesne değil, bir İşlevi.

Motivasyon:- Çapraz tarayıcı finherit

var finherit = function (parent, child) {
    var f = function() { 
        parent.apply(this, arguments);
        child.apply(this, arguments);
    };
    f.__proto__ = parent;
    Object.keys(child).forEach(function _copy(key) {
        f[key] = child[key];
    });
    return f;
};

Bunun mümkün olduğuna inanmıyorum, muhtemelen Function.create es-posta tartışmak için bir liste hazırlayabilir

/*
  Creates a new function whose prototype is proto.
  The function body is the same as the function fbody.
  The hash of propertydescriptors props is passed to defineproperties just like
  Object.create does.
*/
Function.create = (function() {
  var functionBody = function _getFunctionBody(f) {
    return f.toString().replace(/. \{/, "").replace(/\}$/, "");
  };
  var letters = "abcdefghijklmnopqrstuvwxyz".split("");

  return function _create(proto, fbody, props) {
    var parameters = letters.slice(0, fbody.length);
    parameters.push(functionBody(fbody));
    var f = Function.apply(this, parameters);
    f.__proto__ = proto;
    Object.defineProperties(f, props);
    return f;
  };
})();

Related es-discuss mail

Es-tartışmak iplik belirttiğim gibi bir ES:bunun için izin verecek <| prototip strawman operatör var.

<| kullanarak nasıl duracağını görelim

var f1 = function () {
  console.log("do things");
};

f1.method = function() { return 42; };

var f2 = f1 <| function () {
  super();
  console.log("do more things");
}
console.log(f1.isPrototypeOf(f2)); // true
console.log(f2()); // do things do more things
console.log(f2.hasOwnProperty("method")); // false
console.log(f2.method()); // 42

CEVAP
14 EKİM 2011, Cuma


Bu doğru anlayış olduğumu umarım.

Önceden tanımlanmış bir prototip, bir örnek, hem de bir functor (evet, bir sınıf, sadece klasik bir sınıf değil) doğrudan çağrılabilir kadar inanıyorum? Değil mi? Eğer öyleyse, o zaman bu çok mantıklı ve (özellikle JavaScript gibi son derece uyumsuz bir ortamda) çok güçlü ve esnek.Ne yazık ki bunu yapmak için bir yol yokturzarif bir şekilde__proto__ manipüle olmadan JavaScript. Dışarı isimsiz bir işlev yapabilir ve yöntemleri tüm başvurular tüm kopyalayarak yapabilirsin rumenler yönünde gibi görünüyor) bir proxy sınıf olarak hareket etmek. Bu olumsuzlukları

  1. Çalışma zamanı açısından çok pahalı bir şeydir.
  2. (functorObj instanceof MyClass) true olacak.
  3. Özellikler doğrudan erişilebilir eğer bu farklı bir hikaye olurdu, ama ilkel değer atanır, referans olarak verilmişse () olmayacaktır. Bu çözer ile set) defineProperty ya da sadece adlı erişimci yöntemleri gerekirse (görünen o ki ne aradığınızı, tüm eklenti özellikleri eşleme ile defineProperty ile alıcı/ayarlayıcı yerine sadece çalışırsa ihtiyacın yok çapraz motor destek/geriye uyumluluk).
  4. Son yerel (Nesne.prototip nerede kenar durumlarda karşılaşmak olasıdır prototip ya da Dizi.prototip halinde olan miras iseniz []) beklendiği gibi çalışmayabilir.
  5. functorObj(someArg) aramaher zamanthis bağlam nesnesi functorObj.call(someOtherObj, someArg) bir ismi varsa ne olursa olsun (bu yöntem çağrıları için de durum böyle değil)
  6. Functor nesne istek anda oluşturulduğundan, zaman içinde kilitli ve normal bir nesne (değiştirme Sınıfım.etkilenir gibi ilk prototip tahsis functor nesneleri etkilemez manipüle olacak prototip nesneleri ve tersi de geçerlidir herhangi bir functor) etkilemez.

Eğer nazikçe rağmen kullanıyorsanız, bunların hiçbiri büyük bir anlaşma olmalı.

Senin sınıfın senin prototip gibi bir şey... tanımlamak

// This is you're emulated "overloaded" call() operator.
MyClass.prototype.execute = function() {
   alert('I have been called like a function but have (semi-)proper access to this!');
};

MyClass.prototype.asFunctor = function(/* templateFunction */) {
   if ((typeof arguments[0] !== 'function') && (typeof this.execute !== 'function'))
      throw new TypeError('You really should define the calling operator for a functor shouldn\'t you?');
   // This is both the resulting functor proxy object as well as the proxy call function
   var res = function() {
      var ret;
      if (res.templateFunction !== null)
         // the this context here could be res.asObject, or res, or whatever your goal is here
         ret = res.templateFunction.call(this, arguments);
      if (typeof res.asObject.execute === 'function')
         ret = res.asObject.execute.apply(res.asObject, arguments);
      return ret;
   };
   res.asObject = this;
   res.templateFunction = (typeof arguments[0] === 'function') ? arguments[0] : null;
   for (var k in this) {
      if (typeof this[k] === 'function') {
         res[k] = (function(reference) {
            var m = function() {
               return m.proxyReference.apply((this === res) ? res.asObject : this, arguments);
            };
            m.proxyReference = reference;
            return m;
         })(this.asObject[k]);
      }
   }
   return res;
};

Sonuç kullanım gibi bir şey

var aobj = new MyClass();
var afunctor = aobj.asFunctor();
aobj.someMethodOfMine(); // << works
afunctor.someMethodOfMine(); // << works exactly like the previous call (including the this context).
afunctor('hello'); // << works by calling aobj.execute('hello');

(aobj instanceof MyClass) // << true
(afunctor instanceof MyClass) // << false
(afunctor.asObject === aobj) // << true

// to bind with a previous function...
var afunctor = (new MyClass()).asFunctor(function() { alert('I am the original call'); });
afunctor() // << first calls the original, then execute();
// To simply wrap a previous function, don't define execute() in the prototype.

İnekler eve gelene kadar bağlama fonksiyonları/diğer nesneleri/etc sayısız zincir olabilir. Sadece yeniden proxy Ara biraz.

Bu yardımcı olur umarım. Bir kurucu new operatörü olarak yeni bir nesne oluşturur ve functor nesne döndürür, böylece Oh, ve tabii ki fabrika akışını değiştirebilir. Eğer tercih ancak (mutlaka başka yollar da olabilir).

Son olarak, herhangi bir işlevi haline infaz operatör için bir functor biraz daha zarif bir şekilde, sadece proxy işlevi bir yöntem Function.prototype deki nesneye sarma yaparsan bir şey gibi (sen-cekti var takas templateFunction this this ile tartışma elbette)...

var functor = (function() { /* something */ }).asFunctor(aobj);

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FattySpins's channel

    FattySpins's

    17 Mayıs 2009
  • iNCH

    iNCH

    20 Temmuz 2009
  • Tome Rodrigo

    Tome Rodrigo

    9 Temmuz 2006