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;
};
})();
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
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ı
- Çalışma zamanı açısından çok pahalı bir şeydir.
(functorObj instanceof MyClass)
true
olacak.- Ö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 iledefineProperty
ile alıcı/ayarlayıcı yerine sadece çalışırsa ihtiyacın yok çapraz motor destek/geriye uyumluluk). - 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.
functorObj(someArg)
aramaher zamanthis
bağlam nesnesifunctorObj.call(someOtherObj, someArg)
bir ismi varsa ne olursa olsun (bu yöntem çağrıları için de durum böyle değil)- 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);
JavaScript kilitler nasıl çalışır?...
Nasıl bir JavaScript nesnesinin bir öz...
Nasıl JavaScript bir zaman damgası alm...
Nasıl JavaScript panoya kopyalamak mı?...
Nasıl JavaScript yok .prototip çalışma...