建立對象 函數
(1) 工廠模式 this
function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); }; return o; } var person1 = createPerson("Nicholas", 29, "Software Engineer"); var person2 = createPerson("Greg", 27, "Doctor");
存在的問題:沒有解決對象時別問題(怎麼知道一個對象的類型)
(2)構造函數模式prototype
注意點:構造函數始終都應該以一個大寫字母開頭,而非構造函數則應該以一個小寫字母開頭指針
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; }
與上面進行比較
1/沒有顯示的建立對象
2/直接將屬性和方法賦給了this對象
3/沒有return語句
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
建立Person新實例必須使用new操做符,對應着四個步驟
1/建立新的對象
2/將構造函數的做用域給新對象
3/執行構造函數中的代碼
4/返回新對象
//做爲普通函數調用
Person(Greg,27,Doctor)//添加到window
window.sayName();
//在另外一個對象的做用域中調用
var o=new Object();
Person.call(o,Kristen,25,Nurser)
o.sayName()
存在的問題:每一個方法都要在每一個實例上從新建立一遍,person1和person2都有一個sayName()方法,但實際這兩個方法不知同樣的
(3)原型模式對象
每一個函數都有一個prototype屬性,這個屬性是一個指針,指向一個對象
好處:能夠讓全部對象實例共享它所包含的屬性和方法
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true
//說明:在ECMAScript新增方法Object.getPrototypeOf()
alert(Object.getPrototypeOf(person1) == Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //"Nicholas"blog
在這裏,解析器實際執行了兩次搜索,第一次:person1有name屬性嗎,答:沒有 ;第二次:person1的原型有這個屬性嗎,答:有。ip
//若實例存在和實例原型中同樣的屬性同名,那麼實例中的屬性會屏蔽原型中的屬性作用域
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.name = "Greg";
alert(person1.name); //"Greg"——來自實例
alert(person2.name); //"Nicholas"——來自原型
delete person1.name;
alert(person1.name); //"Nicholas" ——來自原型get
//原型與in操做符原型
in操做符會在經過對象訪問給定屬性時返回true,不管該屬性存在於實例仍是原型中
alert(person1.hasOwnProperty("name")); //false
alert(person1.hasPrototypeProperty("name")) // true
alert("name" in person1); //true
person1.name = "Greg";
alert(person1.name); //"Greg" ——來自實例
alert(person1.hasOwnProperty("name")); //true
//hasOwnProperty判斷是來自於原型屬性時 返回false;
//hasPrototypeProperty判斷是來自於原型屬性時,返回true;