2017-02-05 123 views
1

我檢查了問題: javascript what is property in hasOwnProperty?javascript hasOwnProperty and prototype 但無法找到答案我的問題。這裏是我的代碼: 但有些答案令我困惑(不像預期的那樣)。的JavaScript hasOwnProperty原型和繼承

function School(schoolName) { 
 
    this.schoolName = schoolName; 
 
} 
 
School.prototype.printSchoolName = function() { 
 
    console.log(this.schoolName); 
 
} 
 

 
function Student(studentName, schoolName) { 
 
    this.studentName = studentName; 
 
    this.schoolName = schoolName; // alternative : School.call(this, schoolName); 
 
} 
 
Student.prototype = new School(); // force l'héritage des propriétés de School 
 
Student.prototype.printStudentName = function() { 
 
    console.log(this.studentName); 
 
} 
 
var s = new Student("Victor", "IUT"); 
 
s.printStudentName(); // works fine 
 
s.printSchoolName(); // works fine 
 
console.log(Student.prototype.hasOwnProperty("printStudentName")); // works as expected: true 
 
console.log(Student.prototype.hasOwnProperty("printSchoolName")); // works as expected: false 
 
console.log(Student.prototype.hasOwnProperty("studentName")); // NOT as expected: false 
 
console.log(School.prototype.hasOwnProperty("schoolName")); // NOT as expected: false 
 
console.log(Object.getOwnPropertyNames(new School())); // schoolName 
 
console.log(Object.getOwnPropertyNames(new Student())); // studentName, schoolName

最後2個警報不提的方法,但這些方法已經被hasOwnProperty檢測。令人費解。謝謝。

+0

說**你期望什麼**,你看到了什麼,以及爲什麼這不是你的期望。 –

+1

順便說一下,我的失敗答案我也看到你的繼承是不現實的......學生繼承學校? –

+1

你爲什麼期望'Student.prototype'擁有自己的'studentName'屬性?你期望它的價值是什麼? – Bergi

回答

0

也許混淆的一部分是hasOwnProperty不像你想象中的構造函數那樣工作。 但可以作爲你所期望的實例:

a = new Student() 
a.hasOwnProperty("studentName") //true 
2

要注意的第一件事是,使用new School成立Student.prototype是一個反模式。這是一種反模式,您看到lot,但它是一種反模式。 (這也是奇怪的:StudentSchool有一個「is-a」關係嗎?!通常會有一個「有一個」關係[不是繼承],但不是「is-a」)。回到它。

應答:

console.log(Student.prototype.hasOwnProperty("studentName")); 
// NOT as expected: false 

沒什麼東西設置上Student.prototype一個studentName特性,所以一點也不奇怪,它不具備的特性。當你調用它時,Student函數將在實例上設置一個,但Student.prototype不是由new Student創建的實例,所以它從來沒有設置過它。

移動到:

console.log(School.prototype.hasOwnProperty("schoolName")); 
// NOT as expected: false 

相同的解釋。

移動到:

console.log(Object.getOwnPropertyNames(new School())); 
// schoolName 
console.log(Object.getOwnPropertyNames(new Student())); 
// studentName, schoolName 

的原因,你沒有看到原型方法有因爲getOwnPropertyNames只顯示設定直接調用它的對象屬性的名稱(中新對象School和新對象Student)。這些方法不直接設置在這些對象上,它們設置在這些對象的原型上。所以他們沒有列出。


再反模式:在ES5和更早版本的語法,建立原型繼承與構造函數的正確方法是通過Object.create,不調用構造函數。此外,更換上的功能的prototype屬性的對象之後,其constructor屬性返回設定的它應該是什麼樣的有用:

Student.prototype = Object.create(School.prototype); 
Student.prototype.constructor = Student; 

當然,在ES2015(又名「ES6」)及更高版本,可以使用class表示法(如果需要爲舊版瀏覽器進行轉譯),它可以爲您正確處理它。

+0

好的,謝謝。你的回答對我來說有點清楚。關於「反模式」腳本,我應該承認,我從網上的某個源代碼片段中獲取了這個片段,但無論如何,我正試圖在預期其他方面時發現我錯在哪裏:我懷疑在原型中添加了一個方法是simlar寫this.mymethod:function()... –

+0

@ allezl'OM:是的,我很害怕你看到那個地方,這就是爲什麼我想要把它叫出來,所以你會知道該怎麼做,而不是。 :-) –