面向?qū)ο蟮奶匦裕?/p>
- 封裝
- 繼承
- 多態(tài)
封裝
作用:方便代碼的維護(hù),提高代碼的復(fù)用性,更安全的訪問(wèn)數(shù)據(jù)的方式
注意:js中的封裝多了一層意思,就是使用對(duì)象來(lái)封裝變量和函數(shù)
繼承
現(xiàn)實(shí)生活中的繼承:繼承遺產(chǎn),一個(gè)人獲得另一個(gè)人所擁有的財(cái)富或者是資源的方式。
編程語(yǔ)言中的繼承:一個(gè)類(對(duì)象)獲得另外一個(gè)類(對(duì)象)的屬性和方法的一種方式。
多態(tài)
多種表現(xiàn)形態(tài):
對(duì)于相同的操作,不同的對(duì)象表現(xiàn)出不同的行為。實(shí)現(xiàn):
js天生具備多態(tài)的特性(弱類型的語(yǔ)言)
創(chuàng)建對(duì)象的幾種方式
-
字面量法
結(jié)構(gòu)
var 對(duì)象 = {
屬性名01:屬性值,
屬性名02:屬性值,
方法01:function(){函數(shù)體}
}
適用場(chǎng)合:只需簡(jiǎn)單創(chuàng)建單個(gè)對(duì)象
問(wèn)題:如果需要?jiǎng)?chuàng)建多個(gè)相似的對(duì)象,那么代碼中冗余度太高(重復(fù)的代碼太多)
代碼:
var book1 = {
name:"悟空傳",
author:"今何在",
press:"湖南文藝出版社",
price:"28.00",
logDes:function(){
console.log("書名:" + this.name + "作者:" + this.author);
}
}
- 內(nèi)置構(gòu)造函數(shù)法
var book1 = new Object();
//01 設(shè)置屬性
book1.name = "花田半畝";
book1.author = "田維";
book1.price = "40.01";
//02 設(shè)置方法
book1.logDes = function (){
console.log("書名:" + this.name);
}
問(wèn)題:如果需要?jiǎng)?chuàng)建多個(gè)相似的對(duì)象,那么代碼中冗余度太高(重復(fù)的代碼太多)
-
工廠法
對(duì)于內(nèi)置法把固定的部分提取寫成函數(shù)的函數(shù)體,把變化的部分提取,作為參數(shù)傳遞
function createBook(name,author){
//01 創(chuàng)建空的對(duì)象
var o = new Object();
//02 設(shè)置屬性和方法
o.name = name;
o.author = author;
o.logDes = function(){
console.log("作者是:" + this.author);
}
//04 返回新創(chuàng)建的對(duì)象
return o;
}
問(wèn)題:如果創(chuàng)建多個(gè)不同類型的對(duì)象,那么我們無(wú)法分辨
function createPerson(name,age){
var o = new Object();
o.name = name;
o.age = age;
return o;
}
function createDog(name,age)
{
var o = new Object();
o.name = name;
o.age = age;
return o;
}
//創(chuàng)建具體的對(duì)象
var obj1 = createPerson("張三",88);
var obj2 = createDog("阿黃",6);
console.log(obj1.constructor); //Object
console.log(obj2.constructor); //Object
最終的返回值類型都是Object類型,只看結(jié)果不能夠準(zhǔn)確的辨認(rèn)obj1和obj2對(duì)應(yīng)的都是誰(shuí)
-
構(gòu)造法
001 提供一個(gè)構(gòu)造函數(shù)
002 通過(guò)this指針來(lái)設(shè)置屬性和方法
003 通過(guò)new操作符創(chuàng)建對(duì)象
function Person(name,age){
// 默認(rèn) 創(chuàng)建對(duì)象
//var o = new Object();
//默認(rèn)會(huì)賦值給this
//this = o;
// 01 通過(guò)this指針來(lái)設(shè)置屬性和方法
this.name = name;
this.age = age;
this.showName = function(){
console.log(this.name);
};
this.showAge = function(){
console.log(this.age);
}
//默認(rèn)返回
//return this;
}
//03 使用new操作符來(lái)創(chuàng)建對(duì)象
var p1 = new Person("張三",20);
var p2 = new Person("張老漢",200);
console.log(p1);
console.log(p2);
自定義構(gòu)造函數(shù)方式創(chuàng)建對(duì)象內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)
01 我們?cè)谑褂胣ew關(guān)鍵字調(diào)用構(gòu)造函數(shù)的時(shí)候,內(nèi)部默認(rèn)會(huì)創(chuàng)建一個(gè)空的對(duì)象
02 默認(rèn)會(huì)把這個(gè)空的對(duì)象賦值給this
03 通過(guò)this來(lái)設(shè)置新對(duì)象的屬性和方法
04 在構(gòu)造函數(shù)的最后,默認(rèn)會(huì)把新創(chuàng)建的對(duì)象返回
自定義構(gòu)造函數(shù)和工廠函數(shù)對(duì)比
001 函數(shù)的名稱不一樣,構(gòu)造函數(shù)首字母大寫
002 自定義構(gòu)造函數(shù)創(chuàng)建方式內(nèi)部會(huì)自動(dòng)的創(chuàng)建空對(duì)象并且賦值給this
003 默認(rèn)會(huì)自動(dòng)返回新創(chuàng)建的對(duì)象
返回值
01 沒(méi)有顯示的return ,默認(rèn)會(huì)把新創(chuàng)建的對(duì)象返回
02 顯示的執(zhí)行了return語(yǔ)句,就得看具體的情況
001 返回的是值類型,那么直接忽略該返回,把新創(chuàng)建的對(duì)象返回
002 返回的是引用類型的數(shù)據(jù),會(huì)覆蓋掉新創(chuàng)建的對(duì)象,直接返回引用數(shù)據(jù)類型的值
function Dog(name)
{
this.name = name;
//return "demo"; 忽略
return function (){console.log(name);};最終返回的值
}
var dog = new Dog("阿黃");
console.log(dog);
//function (){console.log(name) -->返回值
當(dāng)然這也不是自定義構(gòu)造函數(shù)的最終類型,最終類型將在下面講解。
接下來(lái)的內(nèi)容均是建立在自定義構(gòu)造函數(shù)上的
instanceOf:判斷當(dāng)前對(duì)象是否是某個(gè)對(duì)象的實(shí)例
function Person(){};
function Dog(){};
var p1 = new Person();
var dog1 = new Dog();
console.log(p1 instanceof Person);//true
console.log(dog1 instanceof Dog);//true
constructor:構(gòu)造器屬性(獲取)
console.log(p1.constructor);//function Person(){}
構(gòu)造函數(shù)原型對(duì)象
原型對(duì)象:在使用構(gòu)造函數(shù)創(chuàng)建對(duì)象的時(shí)候,默認(rèn)的會(huì)生成一個(gè)與之關(guān)聯(lián)的對(duì)象,這個(gè)對(duì)象就是原型對(duì)象。默認(rèn)情況下,該對(duì)象是一個(gè)空的對(duì)象({})
原型對(duì)象的作用:使用構(gòu)造函數(shù)創(chuàng)建的對(duì)象,能夠自動(dòng)擁有原型對(duì)象中所有的屬性和方法
如何訪問(wèn)原型對(duì)象
① 構(gòu)造函數(shù).prototype
② 對(duì)象.__proto__如何設(shè)置原型對(duì)象
① 可以像設(shè)置普通對(duì)象一樣來(lái)利用對(duì)象的動(dòng)態(tài)特性設(shè)置屬性和方法
② 使用字面量的方法來(lái)設(shè)置原型對(duì)象(直接替換)約定
正確的說(shuō)法:該對(duì)象的構(gòu)造函數(shù)的原型對(duì)象
構(gòu)造函數(shù)的原型
構(gòu)造函數(shù)的原型對(duì)象
對(duì)象的原型對(duì)象
對(duì)象的原型
以上四種說(shuō)法,她們的意思是一樣的,都是該對(duì)象的構(gòu)造函數(shù)的原型對(duì)象
原型對(duì)象的屬性和方法的設(shè)置:
構(gòu)造函數(shù).prototype.屬性
實(shí)例化:
通過(guò)構(gòu)造函數(shù)創(chuàng)建對(duì)象的過(guò)程,就叫做實(shí)例化
實(shí)例:
通過(guò)構(gòu)造函數(shù)創(chuàng)建的對(duì)象被稱為該構(gòu)造函數(shù)的實(shí)例。一般在說(shuō)實(shí)例的時(shí)候,需要指定構(gòu)造函數(shù)。也就是說(shuō),我們通常會(huì)說(shuō)這個(gè)對(duì)象是XXX構(gòu)造函數(shù)實(shí)例。
function Dog(){};
Dog.prototype.des = "描寫信息";
var dog = new Dog();
原型的使用方法
利用對(duì)象的動(dòng)態(tài)特性來(lái)設(shè)置原型對(duì)象
function Person(){
this.name = "默認(rèn)的名稱";
}
//設(shè)置原型對(duì)象
//成員= 屬性|方法
//01 增加成員
Person.prototype.des = "我是直立行走的人";
Person.prototype.logName = function(){
console.log(this.name);
};
//02 修改成員
Person.prototype.des = "我是直立行走的人++++";
//console.log(Person.prototype);
var p1 = new Person();
console.log(p1.des);
p1.logName();
//03 刪除成員
//delete關(guān)鍵字
//語(yǔ)法 delete 對(duì)象.屬性
//console.log(delete p1.des); //不能用這種方式刪除原型對(duì)象上面的屬性(刪除的是自己的屬性)
delete Person.prototype.des ;
console.log(p1.des);
替換原型對(duì)象(字面量)
注意點(diǎn):
- 如果是替換了原型對(duì)象,那么在替換之前創(chuàng)建的對(duì)象和替換之后創(chuàng)建的對(duì)象她們指向的原型對(duì)象并不是同一個(gè)
- 構(gòu)造器屬性:在替換之后創(chuàng)建的對(duì)象中,它的構(gòu)造器屬性指向的不是Person構(gòu)造函數(shù),而是Object的原型對(duì)象的構(gòu)造器屬性
建議:
在設(shè)置完原型對(duì)象之后再統(tǒng)一的創(chuàng)建對(duì)象。
function Person(){
this.age = 40;
}
var p1 = new Person();
Person.prototype.sayHi = function(){
console.log("hi");
};
//設(shè)置原型對(duì)象
Person.prototype = {
name:"默認(rèn)的名稱",
showName:function(){
console.log(this.name);
}
};
var p2 = new Person();
// p1.sayHi(); //可以
// p2.sayHi(); //不可以
// console.log(p1.name); //undefined
// console.log(p2.name); //默認(rèn)的名稱
// p1.showName(); //報(bào)錯(cuò)
// p2.showName(); //默認(rèn)的名稱
function Person(){
this.age = 40;
}
var p1 = new Person();
//var obj = new Object();
Person.prototype = {
//注意:如果替換了原型對(duì)象,那么需要在原型對(duì)象中修正構(gòu)造器屬性
constructor:Person,//***
sayHi:function (){
console.log("hi");
}
};
var p2 = new Person();
//p2.constructor = Person; //在p2對(duì)象上添加了一個(gè)屬性(constructor)
//var p3 = new Person();
//構(gòu)造器屬性
console.log(p1.constructor == p2.constructor); //如果不添加***所在句則false
// console.log(p1.constructor); //Person
// console.log(p2.constructor); //Object
// console.log(p2.constructor == p2.__proto__.constructor);
// console.log(p2.constructor == Object.prototype.constructor);
console.log(p2);
構(gòu)造器:
屬性:constructor
值:與之關(guān)聯(lián)的構(gòu)造函數(shù)
注意點(diǎn):constructor是在原型對(duì)象身上的,我們通過(guò)對(duì)象.constructor訪問(wèn)得到的值其實(shí)就是原型對(duì)象中對(duì)應(yīng)的值
暫時(shí)先更新到這里