Sorun şu ki sen fonksiyonunu başka bir işleve bir başvuru geçiyoruz ve geçirilen fonksiyon dolayısıyla kapsamını kaybediyor olmasıdır var oldu! İşte Soruna hattı:.. Eğer Circle
prototip getRadius
yöntemi eklendiğinde
Circle.prototype.increaseRadiusBy = function(number) {
this.r = sumWithFunction(this.getRadius, number);
}
JavaScript nesneleri göründükleri daha basit bazı yönlerden, sen klasik OO senin gibi bir sınıf yöntemi olurdu tanımlayan değildi sadece vardı prototipin adlandırılmış bir özelliğini tanımlamak ve o mülkün değerine yönelik açık artırma. this.getRadius
, sumWithFunction
gibi statik bir işlev için bir argüman olarak ilettiğinizde, this
bağlamı kaybolur. window
'a bağlı this
anahtar sözcüğü ile yürütülür ve window
özelliği r
özelliğine sahip olmadığından tarayıcı tanımlanmamış bir hata atar.
Başka bir deyişle, this.getRadius()
aslında bu deyimi ile açıkça işlevini çağırarak olmadan this
ait getRadius
özelliğine atanan işlevi yürütmek ve bağlamda this
ait. bunu çalıştırmak" söylediğini açıklamada, bağlam atanır.
bu ortak bir çözüm kapsamında, başka bir fonksiyonu aldığı herhangi bir işlev için bir tahmin bağımsız değişken eklemektir.
function sumWithFunction(func, context, number) {
return func.apply(context) + number;
}
function Circle(X, Y, R) {
this.x = X;
this.y = Y;
this.r = R;
}
Circle.prototype.getRadius = function() {
return this.r;
}
Circle.prototype.increaseRadiusBy = function(number) {
this.r = sumWithFunction(this.getRadius, this, number);
}
function addFivetoIt(func, context) {
func.apply(context,[5]);
}
var MyCircle = new Circle(0, 0, 10);
addFivetoIt(MyCircle.increaseRadiusBy, myCircle);
Daha basit, ancak daha az dayanıklı bir çözüm, yerel kapatmadaki bir bağlam referansına erişebilen bir satır içi işlevi bildirmek olabilir.
function sumWithFunction(func, number) {
return func() + number;
}
function Circle(X, Y, R) {
this.x = X;
this.y = Y;
this.r = R;
}
Circle.prototype.getRadius = function() {
return this.r;
}
Circle.prototype.increaseRadiusBy = function(number) {
var me = this;
this.r = sumWithFunction(function() {
return me.getRadius()
}, number);
}
function addFivetoIt(func) {
func(5);
}
var MyCircle = new Circle(0, 0, 10);
addFivetoIt(function(number) {
return MyCircle.increaseRadiusBy(number);
});
Ama arayla basit çözüm ECMAScript'e daha yeni bir özelliğini kullanmaktır
, bir işlev yöntemi
bind
aradı. Tüm tarayıcılar tarafından desteklenmediği gerçeğini de içeren
It is explained well here. Bu nedenle jQuery, Prototype, vb. Gibi birçok kütüphanenin,
$.proxy
gibi tarayıcılar arası işlev bağlama yardımcı yöntemleri vardır. ([ `_.bindAll`] http://underscorejs.org/ [` _.bind`] (http://underscorejs.org/#bind) ve:
function sumWithFunction(func, number) {
return func() + number;
}
function Circle(X, Y, R) {
this.x = X;
this.y = Y;
this.r = R;
}
Circle.prototype.getRadius = function() {
return this.r;
}
Circle.prototype.increaseRadiusBy = function(number) {
this.r = sumWithFunction(this.getRadius.bind(this), number); // or $.proxy(this.getRadius,this)
}
function addFivetoIt(func) {
func(5);
}
var MyCircle = new Circle(0, 0, 10);
addFivetoIt(MyCircle.increaseRadiusBy.bind(MyCircle)); // or $.proxy(MyCircle.increaseRadiusBy,MyCircle)
Underscore de birkaç bağlama araçları #bindAll). –
Vay, deatailed! Teşekkürler, asla bu kadar zor beklemedim. sindirmek için biraz zamana ihtiyacım var ... – user1510539
@muistooshort True! Hemen hemen her kütüphane [Ext] (http://docs.sencha.com/ext-js/4-1/#!/api/Ext-method-bind), [MooTools] (http: // mootools) dahil. net/docs/core/Types/Function # İşlevi: bind), [YUI] (http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_bind) ... siz düşünün. – zetlen