2015-12-08 21 views
5

kullanarak sonuç ve bazı kod çalıştı. Bu sonucun bir sebebi var mı?tanımsız prototip [javascript] Yani javascript kullanarak prototip öğreniyorum

Birkaç testler yaptık. Prototip nesnesini yeniden atamanın, yeni atanan prototip içinde bulunan herhangi bir özelliğe erişemeyen Çalışan sınıfının daha önce oluşturulmuş örneklerine neden olduğu sonucuna vardım. Bu doğru mu?

+3

o anda şantiye prototip bir başvuru alır. Prototipi daha sonra değiştirirseniz, mevcut örnekler bunu yansıtmaz. Bir örnek oluşturduktan sonra, genellikle prototipi değiştirmekten ziyade genişletmeniz beklenir. –

+5

Örneğin prototip nesnesine yapılan başvurusu, yapım zamanında (yani, yeni olan satır) ayarlanır. 'Foo.prototype' özellik nesnesinin tamamının değiştirilmesi, bu referansın sonraki örnekte değiştirilmeyecektir. Ancak, 'Foo.prototype' nesnesindeki değişiklikler _will_ görülebilir (çünkü aynı nesne), örn. Bunun yerine Employee.prototype.isWorking = true 'yaptıysam;', size Daha fazlasını okumak için –

+0

beklediğiniz görecekti, bu prototypal mirasın aşağı gerçekten iyi run: http://markdalgleish.com/2012/10/a -touch-of-sınıf-kalıtım-in-javascript/ – br3nt

cevap

1

prototipini ayarlarsınız, böylece nesne yeni prototip değerlerini devralmayacaktır.

Ardından, prototip yeni prototip nesnesi devralır ayarladıktan sonra oluşturulan nesneler.

Son olarak, nesne yerine bir working özelliği daha isWorking özelliği olacaktır.

Yani örnek ve yeniden yapılır

function Employee(name) { this.name= name; }; 

var m1 = new Employee("Bob"); 

var working= { isWorking: true }; 
Employee.prototype = working; 

var m2 = new Employee("Sam"); 

alert(m1.isWorking); // undefined 
alert(m2.isWorking); // true 
2

prototip değiştirme önceden oluşturulmuş nesneyi etkilemez. Yalnızca bu nesneye dayalı olarak oluşturulan nesneleri etkiler.

Orada prototip değiştirmek için kullanılabilecek bir özellik __proto__, ama onun uygulanması gerekli değildir. ES6, prototipi değiştirmek için setPrototypeOf yöntemini tanımlar, ancak yalnızca ES6'da olduğundan destek farklı olabilir.

1

Basit düzeltme, düzgün bir şekilde atamaktır. Burada onunla oynayın:

function Employee(name) { 
    this.name = name; 
} 
var m = new Employee("Bob"); 
var working = { 
    isWorking: true 
}; 
Employee.prototype.working = working; 
alert(m.working.isWorking); 

BİRDEN çalışanlar için daha iyi bir düzeltme, bir sınıf, o örneklerini oluşturmak yapmaktır http://jsfiddle.net/MarkSchultheiss/p6jyqbgv/1/ Öncelikle, Employee bir örneğini önce oluşturduk

"use strict"; 
function makeClassStrict() { 
    var isInternal, instance; 
    var constructor = function(args) { 
    if (this instanceof constructor) { 
     if (typeof this.init == "function") { 
     this.init.apply(this, isInternal ? args : arguments); 
     } 
    } else { 
     isInternal = true; 
     instance = new constructor(arguments); 
     isInternal = false; 
     return instance; 
    } 
    }; 
    return constructor; 
} 
var EmployeeClass = makeClassStrict(); 
EmployeeClass.prototype.init = function(employeeName, isWorking) { 
    var defaultName = 'notbob'; 
    this.name = employeeName ? employeeName : defaultName; 
    this.working = !!isWorking; 
}; 
// call this to get the name property 
EmployeeClass.prototype.getName = function() { 
    return this.name 
}; 
//note no "new" needed due to the makeClassStrict that does that 
var m = EmployeeClass("Bob"); 
alert(m.working +":"+ m.name); 
m.working = true; 
alert(m.working +":"+ m.name); 
var notbob = EmployeeClass("Charlie",false); 
alert(notbob.working +":"+ notbob.name); 
alert(notbob.getName()+ m.getName()); 
1

Sen bütün prototip özelliği geçersiz kılamaz ve zaten çalışmak örneklerini mevcut bekliyoruz. JavaScript bu şekilde çalışmıyor. Ancak, prototip nesnesinde dolaşabilir ve önceden ayarlanmış olan herhangi bir öğeyi kaldırabilir, sonra yeni nesneyiniz arasında geçiş yapabilir ve başka bir şeye ayarlayabilirsiniz. Eğer bir örneğini oluşturduğunuzda

function Employee(name) { this.name= name; } 
var m = new Employee("Bob"); 
var working= { isWorking: true }; 
for(var j in Employee.prototype){delete Employee.prototype[j];}//unset all properties, the same as setting to {} 
for(j in working){Employee.prototype[j]=working[j];}//set the properties 
alert(m.isWorking); 
+0

Bunu gerçekten yapamazsınız, prototipin açık bir şekilde bildirilmiş nitelikleri 'delete' anahtar sözcüğü kullanılarak silinemez. –

+0

@ Æðelstan Kendiniz görün: http://jsfiddle.net/L2yvjtow/ – Ultimater

+0

İşe yaradı, iyi nokta! –

İlgili konular