javascript 之 面向對象【建立對象】

建立對象 函數

    (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;

相關文章
相關標籤/搜索