2016-04-02 15 views
1

JavaScript devralma işleminde bulduğum bir örneği uygulamaya çalışıyorum ve alt nesne beklenildiği şekilde oluşturmuyor gibi görünüyor. Aşağıdaki örnekte, jill örneğini oluşturmak bir Jill nesnesini döndürmez ve alt öğe veya üst öğeden yöntemler çağrılmaz.JavaScript kurucusu çalıştırılmıyor mu?

Sen yanlış nesne başlatıyorsunuz
var Person = function() { 
    this.name = "unnamed"; 
} 
Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
} 
var Jill = function() { 
    var jill = function() { 
    Person.call(this); 
    this.name = "Jill"; 
    }; 
    jill.prototype = Object.create(Person.prototype); 
    jill.prototype.constructor = jill; 
    jill.prototype.expressJoy = function() { 
    console.log("Huray!"); 
    }; 
    return jill; 
} 
var jill = new Jill(); 
console.log(jill instanceof Jill); // false 
jill.expressJoy(); // error, is not a function 
jill.sayName(); // error, seen if comment out previous line 
+1

'jill', gerçek kurucudur. Bunu 'Jill' işlevine neden sardığınızı bilemezsiniz. Bu bir IIFE olmalıydı, belki? – Bergi

+0

Yep, @Bergi - doğru fikre sahip olduğunuza benziyor. – scader

cevap

2

çalışması gerekir Düzenli işlev, yapıcı değil. aşağıda gösterildiği gibi
kodunuzu değiştirin :

var Jill = (function() { 
    function Jill() { 
     Person.call(this); 
     this.name = "Jill"; 
    }; 
    Jill.prototype = Object.create(Person.prototype); 
    Jill.prototype.constructor = Jill; 
    Jill.prototype.expressJoy = function() { 
     console.log("Huray!"); 
    }; 
    return Jill; 
})(); 

var jill = new Jill(); 
console.log(jill); // Jill {name: "Jill"} 
console.log(jill instanceof Jill); // true 
jill.expressJoy(); // Huray! 
jill.sayName(); // My name is Jill 

Şimdi Jill Eğer beklendiği gibi nesneleri üretecek bir "gerçek" yapıcı olduğunu. (BTW, Bir kurucu adı iyi uygulamaya göre büyük harfle başlamalıdır)

+0

Teşekkürler, yanlışlıkla bu bölümü örnekden kaçırdım. – scader

+0

@scader, – RomanPerekhrest

+0

@scader'a hoş geldiniz, yani bu yöntemle her nesne yaratımı için her zaman 'new' kullandığınızdan emin olmalısınız. Eğer 'new jill()' i Jill'e döndürürseniz (örneğin benim örneğimde olduğu gibi), 'yeni' eksikliğine ve bunun neden olabileceği sorunlara endişelenmenize gerek kalmaz. Jill() 'eEvery_ çağrısı, yeni bir nesne döndürecektir. – Andy

1

,

var jill = Jill(); 
var obj = new jill(); 

fonksiyon Jill bir fonksiyon reference değil object dönüyor. Ve bunun üzerine, geri dönen fonksiyon referansı ihtiyacımız için object'u oluşturmamız gerekiyor. senin kod ile

0

yapmanız gerekenler: iç fonksiyonunda

1) return new jill(); ve sonra

2) var jill = Jill(); yeni bir örneğini oluşturur işlevi çağırmak için.

DEMO

Bu

bir daha az karmaşık bir yöntemdir.

function Person() { 
    this.name = "unnamed"; 
} 

Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
} 

function Jill() { 
    Person.call(this); 
    this.name = "Jill"; 
} 
Jill.prototype = Object.create(Person.prototype); 
Jill.prototype.constructor = Jill; 
Jill.prototype.expressJoy = function() { 
    console.log("Huray!"); 
}; 

var jill = new Jill(); 

DEMO

1

Bu, ayrıntılı açıklama ile düzeltilmiş kod düzenleyeceksiniz edilir:

JSBIN Example

// This is your Person class, all "people" will inherit from this object 

var Person = function() { 
    this.name = "unnamed"; 
}; 
// add the sayName function to this prototype 
Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
}; 

// now we make a 'Jill' constructor; 
var Jill = function() { 
    Person.call(this); // bind this (Jill) to Person 
    this.name = 'jill'; 
}; 

// create the correct prototype delegation here 
Jill.prototype = Object.create(Person.prototype); 

// the above code, sets Jill's constructor, to Person so we need to set 
// it back to Jill here: 

Jill.prototype.constructor = Jill; 

// add functions on Jill's prototype, these will only be on the Jill object not Person 

Jill.prototype.expressJoy = function() { 
    console.log("Huray!"); 
    }; 

// make a 'Jill' 

var obj = new Jill(); 
console.log(obj instanceof Jill); // true 
obj.expressJoy(); // "Huray!" 
obj.sayName(); // "My name is jill" 

Şimdi daha da önemlisi örnekleme desen iki tür karıştırma, prototypal ve pseudoclassical, İkincisi, Jill ise eskidir.

Ryan Atkinson aşağıdaki blogpost bu müthiş resme bir göz atın:

Blog Post

instantiation Patterns

+0

Bu yorumlar artık daha fazla anlam ifade etmiyor – Bergi

+0

true, sabit Teşekkürler @Bergi! – JordanHendrix

+0

Muhteşem fotoğraf için teşekkürler, @ Marmarjh. Nesnenin basitleştirilmesi mantıklıdır.Kullanmakta olduğum örnek, kodun bir modül yükleyiciye yerleştirilmesinde çalıştıkları için IIFE'nin içine koydu. – scader

0

Bu gibi durumda var Jill davranır

function Person() { 
    this.name = "unnamed"; 
}; 
Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
}; 

function Jill() { 
    Jill.prototype.__proto__ = Person.prototype; 

    this.name = "Jill"; 

    Jill.prototype.expressJoy = function() { 
     console.log("Huray!"); 
    }; 

    return Jill; 
}; 

var jill = new Jill(); 
console.log(jill instanceof Jill); // True 
jill.expressJoy(); // Hurray ! 
jill.sayName(); // My name is Jill 
+0

'__proto__', kullanımdan kaldırıldı. Kullanma. – Bergi

İlgili konular