js建立物件的方法

歪比巴布仔發表於2020-11-20

在js中建立物件可以有多種方式,比如字面量和建構函式的方式,但是這兩種方式有缺點:產生大量重複的程式碼。

1.工廠模式: 不能確定物件的型別。(即instanceof無法判斷。p1 instanceof ob-->false

function ob(name,sex){
    var o=new Object();
    o.name=name;
    o.sex=sex,
    o.sayName=function(){
        alert(this.name);
    }
    return o;
    }
    var p1=ob("xs",1)
    var p2=ob("ys",2)
    console.log(p1.name)

2.建構函式模式:缺點時相同的方法都要在每個例項上建立一遍,建立的兩個方法是不同的,因此,例項其實並沒有共享這個方法,而是,各自建立了一個函式。如果將方法定義為全域性函式,內部方法通過指標指向這個全域性函式會讓這個自定義物件缺失封裝性。

   function ob(name,age){
        this.name=name;
        this.age=age;
        this.say=function(){
            alert(this.name)
        }
    }
    var p1=new ob("xjf",12);
    console.log(p1);
    console.log(p1 instanceof ob)//--true;

3.原型模式:將屬性和方法全部新增到這個物件的原型物件prototype中,每個物件都包含一個prototype屬性,它指向這個函式的原型物件,這個原型物件包含了所有物件例項共享的屬性和方法。

         function ob(){

    }
    ob.prototype.name="xxj";
    ob.prototype.sex="nan";
    ob.prototype.say=function(){
        return this.name
    }
    
    var p1=new ob()
    console.log(p1.name);
    console.log(p1 instanceof ob); 
    console.log(p1.say())

所有原型物件都會獲得一個constructor屬性,這個屬性指向原型物件所在函式。當為物件例項新增一個同名屬性時,這個屬性會覆蓋原型的屬性。
hasOwnProperty()方法可以檢測一個屬性是否存在於物件例項而非物件原型中。(若存在於物件例項中則返回“true”,若存在於原型中則返回“false”)。
"in"方法則無論是存在於物件例項中還是原型物件中都會返回true.
for-in迴圈,返回的是所有能通過物件訪問的,可列舉的屬性,無論是物件例項的屬性,還是物件原型上的屬性。
Object.keys(object)方法取得物件上所有可列舉的屬性,返回一個包含所有可列舉屬性的字串陣列。
更簡單的原型語法

function ob(){}
ob.prototype={
name:"xx",
sex:"nan",
say:function(){
console.log(this.name)}

這樣寫的好處是省去了很多的object.prototype程式碼。但是,每建立一個函式的同時就建立了他的prototype物件並且自動新增了coonstructor屬性。但是簡單的寫法意味著:我們重寫了整個ob的原型物件,因此,此時的constructor也不再指向建立這個原型物件的函式ob了,而是指向了object建構函式。可以在prototype物件中新增“constructor:ob”重新設定。

function ob (){}
ob.prototype.name="xx";
ob.prototype.say=function(){
    console.log();
}//第一種寫法只是在prototype物件中新增了name,say屬性而已,此時prototyp的constructor指向ob.
function ob (){}
ob.prototype={
    name:"xx",
    age:"12",
    say:function(){
        console.log()
    }
}
//第二種寫法本質上重寫了prototype物件。此時的constructor已經不再指向ob.

原型物件存在的問題,所有例項預設情況下都會取得相同的屬性值,更重要的是對於包含引用型別值的屬性來說,不同的物件例項對屬性的操作對在這些物件例項中共享。

function ob(){}
ob.prototype={
constructor:ob,
num:[1,2,3]
}
var p1=new ob();
p1.num.push('4');
var p2=new ob();
console.log(p4.num)--->1,2,3,4

4.組合使用建構函式模式和原型模式

function ob(name,sex,num){
this.name=name;
this.sex=sex;
this.num=num
}
ob.prototype={
constructor:ob,
sayname:function(){
console.log();
}
}

相關文章