JavaScript是一種基于對(duì)象(object-based)的語(yǔ)言。但是,又不同于其他的面向?qū)ο缶幊陶Z(yǔ)言。并不是一種真正的面向?qū)ο缶幊?OOP)語(yǔ)言,因?yàn)樗恼Z(yǔ)法中沒(méi)有類(class)。
我們?nèi)绾伟选皩傩浴?property)和“方法”(method),封裝成一個(gè)對(duì)象,如何從原型對(duì)象生成一個(gè)實(shí)例化對(duì)象?
一、生成實(shí)例對(duì)象的原始模型
var Cat = {
name:"",
color:""
}
根據(jù)這個(gè)原型對(duì)象的規(guī)格,生成兩個(gè)實(shí)例化對(duì)象
var cat1 = {};
cat1.name = "球球";
cat1.color = "yellow";
var cat2 = {};
cat2.name = "豆豆";
cat2.color = "黑色";
這樣的寫法有兩個(gè)缺點(diǎn),一是如果多生成幾個(gè)實(shí)例,寫起來(lái)就非常麻煩;二是實(shí)例與原型之間,沒(méi)有任何辦法,可以看出有什么聯(lián)系。
二、原始模式的改進(jìn)
function Cat(name,color) {
return {
name:name,
color:color
}
}
var cat1 = Cat("球球","yellow");
var cat2 = Cat("豆豆","黑色");
存在問(wèn)題:cat1和cat2之間沒(méi)有內(nèi)在的聯(lián)系,不能反映出它們是同一個(gè)原型對(duì)象的實(shí)例。
三、構(gòu)造函數(shù)模式
為了解決從原型對(duì)象生成實(shí)例化的問(wèn)題,JavaScript提供了一個(gè)構(gòu)造函數(shù)(Constructor)模式。所謂"構(gòu)造函數(shù)",其實(shí)就是一個(gè)普通函數(shù),但是內(nèi)部使用了this變量。對(duì)構(gòu)造函數(shù)使用了new運(yùn)算符,就能生成實(shí)例,并且this變量會(huì)綁定在實(shí)例對(duì)象上。
function Cat(name,color){
this.name=name;
this.color=color;
}
var cat1 = new Cat("球球","yellow");
var cat2 = new Cat("豆豆","yellow黑色");
alert(cat1.name);
alert(cat1.color);
四、使用工廠模式創(chuàng)建得到
基于工廠模式的定義方式定義對(duì)象,在一個(gè)方法中定義一個(gè)對(duì)象,將傳遞進(jìn)來(lái)的屬性賦給這個(gè)對(duì)象
function createOb(name,age){
var o = new Object();
o.name = name;
o.age = age;
o.say = function(){
alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");
}
return o;
}
//使用工廠模式的定義方法,有效的解決了對(duì)象無(wú)法重用的問(wèn)題
var p1 = creataOb("老王",18);
p1.say();
var p2 = createOb("老謝",19);
p2.say();
使用了工廠模式定義了對(duì)象,這樣就很好的解決了對(duì)象無(wú)法重用的問(wèn)題,但是此時(shí)
又存在了另一個(gè)問(wèn)題,就是我們無(wú)法判斷得到的對(duì)象的類型了,如typeof或者instanceof
來(lái)判斷類型,僅僅得到一個(gè)Object類型,所以就推出了基于構(gòu)造函數(shù)的方式。
//ES6之前,JavaScript沒(méi)有方法描述類,我們只能構(gòu)造函數(shù)模擬類,但是
//它一直將class作為一個(gè)保留字存在。
//在ES6中,JavaScript可以定義類
/*
* class 類名{
* constructor(屬性列表){
* this.屬性1 = 屬性1;
* this.屬性2 = 屬性2;
* ......
* }
* 方法名稱(參數(shù)列表){
* //方法體
* }
* }
*
* */
//封裝
//定義一個(gè)類
class Person {
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
say(msg) {
alert(msg);
}
showInfos(){
alert(this.name+"---"+this.age+"---"+this.sex);
}
/*
* 靜態(tài)方法調(diào)用
*
*/
static show(msg) {
alert(msg);
}
}
var p1 = new Person("老王",18,"男");
p1.say("嘿嘿,果然是個(gè)大帥哥");
p1.showInfos();
Person.show("嘿嘿");
//繼承 繼承上面的屬性
class Children extends Person {
constructor(name,sex,age,height){
super(name,age,sex);
this.height = height;
}
}
var s1 = new Children("小明","男",5,150);
s1.say("我是小明");