我們可以通過創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。
例如:
function Person(name.age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.sayName = function(){ alert(this.name); }
}
然後我們實例一個Person
var person1 = new Person("john",18,"男");
var person1 = new Person("Rose",17,"女");
我們注意到,Person()中的代碼:
沒有顯式地創建對象;
直接將屬性和方法賦給了this 對象;
沒有return 語句。
此外,還應該注意到函數名Person 使用的是大寫字母P。按照慣例,構造函數始終都應該以一個大寫字母開頭,而非構造函數則應該以一個小寫字母開頭。這個做法借鑑自其他OO 語言,主要是爲了區別於ECMAScript 中的其他函數;因爲構造函數本身也是函數,只不過可以用來創建對象而已。
要創建Person 的新實例,必須使用new 操作符。以這種方式調用構造函數實際上會經歷以下4個步驟:
(1) 創建一個新對象;
(2) 將構造函數的作用域賦給新對象(因此this 就指向了這個新對象);
(3) 執行構造函數中的代碼(爲這個新對象添加屬性);
(4) 返回新對象。
person1 和person2 分別保存着Person 的一個不同的實例。這兩個對象都有一個constructor(構造函數)屬性,該屬性指向Person,如下所示。
alert(person1.constructor == Person); //true
alert(person2.constructor == Person); //true
對象的constructor 屬性最初是用來標識對象類型的。但是,提到檢測對象類型,還是instanceof 操作符要更可靠一些。我們在這個例子中創建的所有對象既是Object 的實例,同時也是Person的實例,這一點通過instanceof 操作符可以得到驗證。
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
1.將構造函數當作函數
// 當作構造函數使用
var person = new Person("Nicholas", 29, "man");
person.sayName(); //"Nicholas"
// 作爲普通函數調用
Person("Greg", 27, "women"); // 添加到window
window.sayName(); //"Greg"
// 在另一個對象的作用域中調用
var o = new Object();
Person.call(o, "Kristen", 25, "Nurse");
o.sayName(); //"Kristen"
2.構造函數的問題
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = new Function("alert(this.name)"); // 與聲明函數在邏輯上是等價的
}
alert(person1.sayName == person2.sayName); //false
function Person(name, age, sex){
this.name = name;
this.age = age;
this.sex= sex;
this.sayName = sayName;
}
function sayName(){
alert(this.name);
}
var person1 = new Person("Nicholas", 29, "man");
var person2 = new Person("Greg", 27, "woman");