關(guān)鍵點(diǎn)
每一個(gè)函數(shù)在定義的時(shí)候,都會(huì)有跟它關(guān)聯(lián)的一個(gè)對(duì)象被創(chuàng)建出來
每一個(gè)由構(gòu)造函數(shù)創(chuàng)建出來的對(duì)象,都會(huì)默認(rèn)的和構(gòu)造函數(shù)的神秘對(duì)象關(guān)聯(lián)
當(dāng)使用一個(gè)方法進(jìn)行屬性或者方法訪問的時(shí)候,會(huì)先在當(dāng)前對(duì)象內(nèi)查找該屬性和方法
如果當(dāng)前對(duì)象內(nèi)未找到,就回去跟它關(guān)聯(lián)的神秘對(duì)象內(nèi)進(jìn)行查找
function Person(name, age){
this.name = name;
this.age = age;
this.sayHi = function(){
console.log("Hello!");
};
}
var p = new Person("張三", 18);
p.sayHi(); //當(dāng)前對(duì)象內(nèi)有這個(gè)方法,所以不會(huì)去神秘對(duì)象內(nèi)進(jìn)行查找
var p1 = new Person("李四", 19);
p1.sayHello(); //當(dāng)前對(duì)象沒沒有找到這個(gè)方法,所以去神秘對(duì)象內(nèi)進(jìn)行查找
如何訪問到這個(gè)神秘對(duì)象呢?
//可以通過 構(gòu)造函數(shù).prototype 訪問這個(gè)神秘對(duì)象
console.log(Person.prototype);
當(dāng)嘗試給這個(gè)對(duì)象新增一個(gè)方法之后:
Person.prototype.sayHello = function(){
console.log("我是神秘對(duì)象中的方法");
};
使用p,p1都可以訪問這個(gè)方法:
p.sayHello();
p1.sayHello();
總結(jié):
所有對(duì)象共享神秘對(duì)象(構(gòu)造函數(shù).prototype)內(nèi)的屬性和方法。
解決方案
既然所有對(duì)象共享神秘對(duì)象(構(gòu)造函數(shù).prototype)內(nèi)的屬性和方法。我們只需要將需要共享的東西,也就是重復(fù)占用內(nèi)存的東西,全部都放到 神秘對(duì)象(構(gòu)造函數(shù).prototype)中,那么所有對(duì)象就都可以使用,并且內(nèi)存里面也只有一份了。
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
console.log("你好");
};
//測(cè)試
var p = new Person("張三", 18);
var p1 = new Person("李四", 19);
console.log(p.sayHi == p1.sayHi); //輸出true
常見的錯(cuò)誤
將屬性寫在神秘對(duì)象(構(gòu)造函數(shù).prototype)內(nèi)
function Car(name){
this.name = name;
}
function Person() {}
Person.prototype.name = '張三'; //基本類型的屬性影響不大
Person.prototype.car = new Car("法拉利"); //引用類型的屬性,會(huì)被所有的對(duì)象共享
var p = new Person();
賦值的錯(cuò)誤
function Person() {}
Person.prototype.name = '張三';
var p1 = new Person();
var p2 = new Person();
p1.name = '李四';
console.log( p1.name );
console.log( p2.name );
// 如果是訪問數(shù)據(jù), 當(dāng)前對(duì)象中如果沒有該數(shù)據(jù)就到構(gòu)造函數(shù)的原型屬性中去找
// 如果是寫數(shù)據(jù), 當(dāng)對(duì)象中有該數(shù)據(jù)的時(shí)候, 就是修改值; 如果對(duì)象沒有該數(shù)據(jù), 那么就添加值