function person() {}
person.prototype.name = 'kobe'
person.prototype.age = '23'
person.prototype.job = 'player'
person.prototype.sayname = function()
var person1 = new person()
var person2 = new person()
person1.sayname() // 'kobe'
person2.sayname() // 'kobe'
我們建立的每乙個函式都有乙個prototype屬性,這個屬性指向該函式的原型物件。那麼什麼是原型物件呢?
原型物件就是無論任何時候我們建立了乙個函式,這個函式都會有prototype屬性,而這個屬性指向函式的原型物件。也就是說只要建立了乙個函式就會自動有乙個該函式的原型物件。上面建立了乙個person函式,那麼它的原型物件就是person prototype。而原型物件中也有乙個constructor屬性指向有prototype屬性的函式。當我們為這個函式建立了例項person1和person2,person1和person2中就會有乙個[[prototype]]屬性指向原型物件。該屬性無法訪問,但是瀏覽器中表現為_proto_。
影象表示如下:
當要查詢屬性時,先會在例項中查詢,如果沒有找到,就會在原型物件中查詢,如果找到就返回,如果沒有找到就返回undefined。
如果我們在例項中新增了與原型同名的屬性,那麼例項中的屬性將會遮蔽原型中的那個屬性。
1.isprototypeof()
[[prototype]]指向呼叫isprototypeof()方法的物件,那麼就返回true。
意思就是,[[prototype]]指向乙個物件。那是哪個物件呢,就是呼叫isprototypeof()方法的物件。
alert(person.prototype.isprototypeof(person1)) //true
2.getprototypeof()
獲取乙個物件的原型。
alert(object.getprototypeof(person1)) // person.prototype
3.hasownprototype()
檢測乙個屬性時存在於例項中還是原型中,只在給定屬性存在於例項中才會返回true
alert(person1.hasownprototype("name")) //false
4.in操作符
判斷物件是否能訪問該屬性。不倫屬性是在例項還是原型中,只要能訪問就返回true
alert("name" in person1) //true
alert("***" in person1) //false
"name"屬性雖然不在例項中,但是在原型中,依然可以訪問到,返回true。但是***在例項和原型中都不存在,無法訪問,返回false。
person.prototype =
}
上面每次向原型物件新增屬性都要寫一次person.prototype,非常繁瑣,所以可以通過乙個物件字面量的形式,將屬性都寫在物件字面量裡面。但是這樣寫有乙個需要注意的地方,就是這樣寫的話,相當於我們重寫了原型物件,此時person.prototype中的constructor屬性不再指向person。而是指向object建構函式。我們可以通過新增constructor屬性,並賦值為person,保證可以訪問到正確的值。
如果我們重寫了原型物件的話,如果我們想要訪問裡面的屬性,那麼我們就必須在重寫原型物件之後例項化物件,因為重寫原型物件時切斷了現有原型與任何之前已經存在的物件例項之間的聯絡。之前存在的物件例項仍然指向原來的原型物件。
原型物件的缺點:
由於原型中的屬性都是共享的,基本型別的屬性可以通過同名屬性覆蓋,但是我們通過其中乙個例項修改了原型中的引用型別的屬性,那麼在其他例項中也是實時更新修改的資料。這或許不是我們想要的結果。
function person() {}
person.prototype =
}var person1 = new person()
var person2 = new person()
person1.friends.push("444")
console.log(person1.friends) // ["111","222","333","444"]
console.log(person2.friends)// ["111","222","333","444"]
也許我們只是想要在person1的friends中新增乙個「444」,而person2中不用。
解決方法:
組合使用建構函式模式和原型模式
建構函式模式用於定義例項屬性,原型模式用於定義方法和共享的屬性。好處就是每個例項都會有自己的乙份例項屬性副本,同時又共享著對方法的使用。
function person(name,age,job)
person.prototype =
} //這樣的寫函式的方式報錯說沒有 sayname 這個函式
}}var person1 = new person("lhd",23,"lhf")
var person2 = new person("111",23,"222")
person2.sayname()
person1.sayname() //person1中是沒有sayname這個方法的,所以這裡會報錯
這個模式就是將原型的初始化在建構函式中執行。if條件判斷裡面不需要檢查每個屬性和方法,只要檢查其中乙個就可以了。
就是if裡面有多個方法函式。
function specialarray();
return values;
}var colors = new specialarray("red", "blue", "green");
console.log(colors.topipedstring()); //"red|blue|green"
目的是給原生的建構函式定義方法,這裡就是給array建構函式新增了乙個topipedstring方法,這樣不會對原生建構函式造成汙染,減少不必要的麻煩。不建議直接在原生建構函式裡面新增方法。specialarray與array之間的區別就是比array多了乙個方法。
穩妥物件:沒有公共屬性,方法也不引用this的物件。
function person(name,age,job),
return o
}var friends = person("lhd",23,"player")
friends.sayname();
這裡除了呼叫sayname方法,沒有其他辦法可以訪問name屬性。 JavaScript中的原型和原型鏈
上面的圖看懂了麼,沒懂不要緊。先看個栗子 function foo foo.prototype.name haha const foo new foo const bar new foo console.log foo.name haha console.log bar.name haha 複製 沒...
JavaScript的原型鏈
首先介紹下原型 原型的作用 把方法放到原型中,就可以讓同型別的物件共享 當我建立乙個建構函式。建構函式裡有原型。通過 建構函式名.prototype獲取到當前建構函式的原型。function student name,age,gender this.sayhi function 原型內部自帶乙個co...
JavaScript原型以及原型鏈
原型物件的用途是為每個例項物件儲存共享的方法和屬性,它僅僅是乙個普通物件而已。並且所有的例項是共享同乙個原型物件,因此有別於例項方法或屬性,原型物件僅有乙份。在訪問乙個物件的屬性的時候,首先在當前物件中找,如果沒有在其原型物件找 復用的內容放在prototype,讓類的例項擁有相同的功能 小紅書上的...