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
WDN
Constructor 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 屬性的那份。
繼承方式一:實體化一份父物件,但是owner設成自己
//父物件
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 屬性上。
而子物件要讓孫物件繼承的屬性,也加到自己的 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()); //變成自己的屬性