原型對象
01 原型對象概念
- 在構(gòu)造函數(shù)創(chuàng)建出來的時(shí)候,系統(tǒng)會(huì)默認(rèn)幫構(gòu)造函數(shù)創(chuàng)建一個(gè)關(guān)聯(lián)的新對象,就是原型對象,其默認(rèn)為一個(gè)空對象
- 構(gòu)造函數(shù)找到原型對象:prototype
- 原型對象找到構(gòu)造函數(shù):constructor
注意:原型對象本身也是一個(gè)對象,這個(gè)對象是Object類型,有一個(gè)屬性constructor
02 原型對象的作用
- 構(gòu)造函數(shù)的原型對象的屬性與方法可以被構(gòu)造函數(shù)創(chuàng)建的對象共享
03 如何訪問原型對象
- 構(gòu)造函數(shù).prototype
- 對象.__ proto__(注意:正常開發(fā)中不要使用這個(gè)屬性,因?yàn)镋CMA標(biāo)準(zhǔn)中并沒有這個(gè)屬性,是瀏覽器開發(fā)商提供的方便調(diào)試,直到E6納入了標(biāo)準(zhǔn)中)
- Object.getPrototypeOf(對象)
04 如何使用原型對象
-
利用對象的動(dòng)態(tài)特性
實(shí)例成員:實(shí)例對象的屬性與方法 原型成員:原型對象上的屬性與方法
代碼示例
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.showName = function () {
console.log(this.name);
}
Person.prototype.showAge = function () {
console.log(this.age);
};
Person.prototype.des = "描述信息";
var p1 = new Person("張三",20);
console.log(p1);
console.log(Person.prototype);
//刪除原型對象上面的屬性
//delete Person.prototype.des; //刪除成功
console.log(p1.des);
//刪除對象中不存在的屬性,返回true
console.log(delete p1.des); //不能使用這種方式直接刪除原型對象上面的屬性
console.log(p1.des);
- 字面量的方式直接替換
代碼示例1
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype = {
showName:function () {
console.log(this.name);
},
showAge:function () {
console.log(this.age);
},
des:"描述信息",
friends:["烏拉烏拉","嘩啦嘩啦","滴答滴答"]
}
var p1 = new Person("張三",20);
var p2 = new Person("張四",20);
p1.showName();
p2.showName();
//原型成員會(huì)被所有的對象(構(gòu)造函數(shù))共享
p1.des = "測試"; //該行代碼添加屬性在p1上面,并不會(huì)改變原型屬性
console.log(p2.des); //描述信息
console.log(p1);
console.log(p2);
p1.friends.push("巴拉巴拉");
console.log(p1);
console.log(p2); //會(huì)受到影響
//使用對象.這種方式來設(shè)置屬性的時(shí)候,
// 如果這個(gè)屬性是值類型那么表示添加一個(gè)實(shí)例屬性des,不會(huì)修改原型屬性
// 如果這個(gè)屬性是引用類型,那么可以修改到原型屬性
Person.prototype.des = "0000";
console.log(p1.des); //測試
console.log(p2.des); //0000
注意:使用字面量方式替換原來的原型對象,需要手動(dòng)添加構(gòu)造器屬性,因?yàn)樽置媪縿?chuàng)建的對象本身沒有構(gòu)造器屬性,那么會(huì)去他的原型對象上找,而通過字面量創(chuàng)建的對象是由Object創(chuàng)建的,其原型對象的構(gòu)造器屬性為object,所以在沒有添加構(gòu)造器屬性之前,Person.prototype.constructor = Object
代碼示例2
function Person(name,age) {
this.name = name;
this.age = age;
}
// var o = {};
// var o = new Object();
//字面量創(chuàng)建的對象是Object創(chuàng)建的
//該對象的構(gòu)造函數(shù)是 Object
//該對象的構(gòu)造函數(shù)也有自己的原型對象 Object.prototype
//該對象的構(gòu)造函數(shù)也有自己的原型對象,內(nèi)部有構(gòu)造器屬性 Object.prototype.constructor =》Object,所以需要手動(dòng)添加一個(gè)構(gòu)造器屬性
//對象本身并沒有構(gòu)造器屬性,在訪問該屬性的時(shí)候訪問的是其原型對象上面的屬性
Person.prototype = {
constructor:Person,
showName:function () {
console.log(this.name);
},
showAge:function () {
console.log(this.age);
}
};
var p1 = new Person("張三",20);
console.log(Person.prototype.constructor == Person); //Person
console.log(p1);
代碼示例
function Dog() {
}
//構(gòu)造函數(shù) Dog
//構(gòu)造函數(shù)的原型對象 Dog.prototype
//原型對象找到構(gòu)造函數(shù) Dog.prototype.constructor ==>Dog
Dog.prototype.name = "默認(rèn)的名稱";
// Dog.prototype = {
// name:"默認(rèn)的名稱"
// };
console.log(Dog.prototype);
var dog1 = new Dog();
var dog2 = new Dog();
console.log(dog1.name);
console.log(dog2.name);
console.log(dog1.\_\_ proto\_\_== Dog.prototype); //true
console.log(Object.getPrototypeOf(dog2) == Dog.prototype); //true
05 構(gòu)造函數(shù),原型對象與對象的關(guān)系

06 原型對象解決函數(shù)共享問題
建議:屬性寫在構(gòu)造函數(shù)上,方法寫在原型對象上
注意:對象訪問屬性與方法時(shí),會(huì)先在自己身上查找,沒有再去原型對象上查找。
代碼示例
function Person(name) {
this.name = name;
}
//設(shè)置構(gòu)造函數(shù)的原型對象
Person.prototype.showName = function () {
console.log(this.name);
}
var p1 = new Person("張三");
var p2 = new Person("張三豐");
p1.showName(); //張三
p2.showName(); //張三豐
console.log(p1.showName == p2.showName); //true
//注意:下面的代碼在p1上面添加了一個(gè)showName方法并沒有修改原型對象。
p1.showName = function () {
console.log("測試");
};
p1.showName(); //測試
p2.showName(); //張三豐
07 原型對象位置設(shè)置問題
注意:在設(shè)置(替換)原型對象前后創(chuàng)建的對象指向的原型對象不是同一個(gè)
代碼示例
//01 提供構(gòu)造函數(shù)
function Person(name,age) {
this.name = name;
this.age = age;
}
//03 創(chuàng)建實(shí)例對象
var p1 = new Person("張三",20);
//02 設(shè)置原型對象
Person.prototype = {
constructor:Person,
showName:function () {
console.log(this.name);
}
}
var p2 = new Person("李四",20);
p2.showName(); //李四
p1.showName(); //報(bào)錯(cuò),因?yàn)閜1是在替換原型對象之前創(chuàng)建的,其原型對象只有一個(gè)constructor屬性,沒有showName方法,所以報(bào)錯(cuò)。
08 hasOwnProperty方法
hasOwnProperty:判斷某個(gè)對象是否擁有指定的實(shí)例屬性(不包括原型成員)
in關(guān)鍵字 :檢查對象是否擁有指定的成員(實(shí)例成員與原型成員)
代碼示例
function Person(name) {
this.name = name;
}
Person.prototype.hi = "hi";
Person.prototype.show = function () {
};
var p1 = new Person();
//語法 對象.hasOwnProperty("屬性")
console.log(p1.hasOwnProperty("name")); //true
console.log(p1.hasOwnProperty("age")); //false
console.log(p1.hasOwnProperty("hi")); //false
//語法 “屬性” in 對象
console.log("name" in p1); //true
console.log("age" in p1); //false
console.log("hi" in p1); //true
console.log("show" in p1); //true
09 isPrototypeOf方法
isPrototypeOf:判斷某個(gè)對象是否是另一個(gè)對象的原型對象
代碼示例
function Person(name) {
this.name = name;
}
var obj = {};
var o = {
hi:"hi"
}
Person.prototype = o;
var p1 = new Person("李四");
//Object.prototype Object構(gòu)造函數(shù)的原型對象
console.log(o.isPrototypeOf(p1)); //true 判斷o是否是p1的原型對象
console.log(Object.prototype.isPrototypeOf(p1)); //true
實(shí)例化與實(shí)例
實(shí)例化:構(gòu)造函數(shù)創(chuàng)建對象的過程
實(shí)例(對象):構(gòu)造函數(shù)創(chuàng)建出來的對象是該構(gòu)造函數(shù)的一個(gè)實(shí)例對象;在說實(shí)例的時(shí)候需要指明構(gòu)造函數(shù)。