prototype 語言
Javascript 是基於 prototype 的語言,意思是他是利用 prototype 建立起整個語言架構。
有一個最基礎的 null,
然後所有物件的基礎物件 Object 就是繼承自 null 這個 prototype,
Object 本身自己有一個 prototype 屬性,
這個屬性是他讓別人繼承的,
也就是別的物件要繼承自 Object 時,
他其實繼承的是 Object 的 prototype 屬性(這個屬性裡可以包含很多東西)。
所以用 Javascript 寫的程式,
就是這樣,一個物件繼承自另一個物件的 prototype 屬性,逐步建立起整個程式。
建立物件的方式一:function 回傳物件
利用函式回傳一個物件。沒彈性,而且每一個物件都是 object。
function createNewPerson(name) { var obj = {}; obj.name = name; obj.greeting = function () { alert('Hi! I\'m ' + this.name + '.'); } return obj; }
建立物件的方式二:Object()建構子
//new Object() 建立空白物件 //再把屬性加上去 var person1 = new Object(); person1.name = 'Chris'; person1['age'] = 38; person1.greeting = function() { alert('Hi! I\'m ' + this.name + '.'); } //或是直接傳入一個物件當參數 var person1 = new Object({ name : 'Chris', age : 38, greeting : function() { alert('Hi! I\'m ' + this.name + '.'); } });
建立物件的方式三:Object.create() 函式 IE8不支援
var person2 = Object.create(person1); //person2.name //person2.greeting()
建立物件的方式四:建構子函式 constructor function
WDNConstructor funciton 是一種特殊的函式,
用來建立物件。
比用傳統方式建立物件好很多。
function Person(name,interests) { this.name = name; this.interests=interests; this.greeting = function() { alert('Hi! I\'m ' + this.name + '.'); }; } var person1 = new Person('Bob',[1,2,3]); var person2 = new Person('Sarah',[1,2,3]); console.log(person1['name']); //可以這樣取 console.log(person1.interests[1]); //可以這樣取 console.log(person1.greeting()); console.log(person2.name); console.log(person2.greeting());
用建構子函式實體化的物件
建構子函式實體化的物件,建構子函式定義的prototype屬性,只會有一份,
不會複製到每個實體上。
繼承(更接近於delegate 委託)
Javascript 的繼承,是[原型繼承](Prototypal inheritance)。子物件不會把父物件可繼承的屬性複製過來,
而是用原型鍊連結他繼承的屬性。
子物件的繼承其實不是繼承,而是連接,
連接父物件prototype屬性。
所以一個父物件,不管延伸出多少子物件,
子物件繼承的屬性都只有一份,
就是存在父物件 prototype 屬性的那份。
//父物件 function Person(first, last, age, gender, interests) { this.name = { first, last }; this.age = age; this.gender = gender; this.interests = interests; }; Person.prototype.greeting = function() { alert('Hi! I\'m ' + this.name.first + '.'); }; //子物件 function Teacher(first, last, age, gender, interests, subject) { //用call 呼叫實體化父物件,把this 傳進去當作owner Person.call(this, first, last, age, gender, interests); //Teacher 新增的屬性 this.subject=subject; } var t=new Teacher("a","b",3,1,"book","math"); console.log(t.name); //{"a","b"}
每個物件的 prototype 屬性,是要繼承下去的。
所以父物件的 prototype 屬性要連結在子物件的 prototype 屬性上。
而子物件要讓孫物件繼承的屬性,也加到自己的 prototype 屬性上。
//父物件 function Person(first, last, age, gender, interests) { this.name = { first, last }; this.age = age; this.gender = gender; this.interests = interests; }; Person.prototype.greeting = function() { alert('Hi! I\'m ' + this.name.first + '.'); }; //子物件 function Teacher(first, last, age, gender, interests, subject) { //用call 呼叫實體化父物件,把this 傳進去當作owner Person.call(this, first, last, age, gender, interests); //Teacher 新增的屬性 this.subject=subject; } //繼承父物件的 prototype 屬性 Teacher.prototype=Object(Person.prototype); //**記得要把 constructor 設成自己,否則會是 Person Teacher.prototype.constructor = Teacher; var t=new Teacher("a","b",3,1,"book","math"); console.log(t.name); //{"a","b"} console.log(t.greeting()); //繼承自父物件的屬性
複寫繼承自父物件的屬性
//父物件 function Person(first, last, age, gender, interests) { this.name = { first, last }; this.age = age; this.gender = gender; this.interests = interests; }; Person.prototype.greeting = function() { console.log('Hi! I\'m ' + this.name.first + '.'); }; //子物件 function Teacher(first, last, age, gender, interests, subject) { //用call 呼叫實體化父物件,把this 傳進去當作owner Person.call(this, first, last, age, gender, interests); //Teacher 新增的屬性 this.subject=subject; } //繼承父物件的 prototype 屬性 Teacher.prototype=Object(Person.prototype); //**記得要把 constructor 設成自己,否則會是 Person Teacher.prototype.constructor = Teacher; //複寫父物件的 greeting //**要在 Teacher.prototype=Object(Person.prototype) 之後,才有複寫到 Teacher.prototype.greeting=function(){ console.log('Hi! I\'m teacher.'); } var t=new Teacher("a","b",3,1,"book","math"); console.log(t.name); //{"a","b"} console.log(t.greeting()); //變成自己的屬性
沒有留言:
張貼留言