JavaScript面向?qū)ο?/h1>

一卷仑、面向?qū)ο蠡咎卣?/h4>
  1. 封裝:也就是把客觀事物封裝成抽象的類姐浮,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作浩嫌,對不可信的進行信息隱藏杂拨。
  2. 繼承:通過繼承創(chuàng)建的新類稱為“子類”或“派生類”专普。繼承的過程,就是從一般到特殊的過程弹沽。
  3. 多態(tài):對象的多功能檀夹,多方法,一個方法多種表現(xiàn)形式策橘。
  4. Javascript是一種基于對象(object-based)的語言炸渡。但是,它又不是一種真正的面向?qū)ο缶幊蹋∣OP)語言丽已,因為它的語法中沒有class(類)—–es6以前是這樣的蚌堵。所以es5只有使用函數(shù)模擬的面向?qū)ο蟆?/li>

二、對象實例化方式

  1. 原始模式:這樣的寫法有兩個缺點沛婴,一是如果多生成幾個(100個:鹞贰)實例,寫起來就非常麻煩嘁灯;二是實例與原型之間泻蚊,沒有任何辦法,可以看出沒有什么聯(lián)系旁仿。
var Car = {
    color: 'red',//車的顏色
    wheel: 4,//車輪數(shù)量
}
var Car2 = {
    color: 'blue',
    wheel: 4,
}
alert(Car.color);//red
  1. 原始模式的改進:通過寫一個函數(shù)藕夫,解決代碼重復(fù)的問題。
function createCar(color,wheel) {
    return {
        color:color,
        wheel:wheel
    }
}
//然后生成實例對象枯冈,就等于是在調(diào)用函數(shù):
var cat1 = createCar("紅色","4");
var cat2 = createCar("藍色","4");

alert(cat1.color);//紅色
  1. 工廠模式
function createCar(color,wheel){//createCar工廠
    var obj = new Object;//或obj = {} 原材料階段
    obj.color = color;//加工
    obj.wheel = wheel;//加工
    return obj;//輸出產(chǎn)品
}
//實例化
var cat1 = createCar("紅色","4");
var cat2 = createCar("藍色","4");

alert(cat1.color);//紅色
  1. 構(gòu)造函數(shù)模式:為了解決從原型對象生成實例的問題毅贮,Javascript提供了一個構(gòu)造函數(shù)(Constructor)模式。 所謂”構(gòu)造函數(shù)”尘奏,其實就是一個普通函數(shù)滩褥,但是內(nèi)部使用了this變量。對構(gòu)造函數(shù)使用new運算符炫加,就能生成實例瑰煎,并且this變量會綁定在實例對象上铺然。加new執(zhí)行的函數(shù)構(gòu)造內(nèi)部變化:自動生成一個對象,this指向這個新創(chuàng)建的對象酒甸,函數(shù)自動返回這個新創(chuàng)建的對象
function CreateCar(color,wheel){//構(gòu)造函數(shù)首字母大寫
    //不需要自己創(chuàng)建對象了
    this.color = color;//添加屬性魄健,this指向構(gòu)造函數(shù)的實例對象
    this.wheel = wheel;//添加屬性

    //不需要自己return了
}

//實例化
var cat1 = new CreateCar("紅色","4");
var cat2 = new CreateCar("藍色","4");
alert(cat1.color);//紅色

三、構(gòu)造函數(shù)注意事項

  1. 此時CreateCar稱之為構(gòu)造函數(shù)插勤,也可以稱之類沽瘦,構(gòu)造函數(shù)就是類 。
  2. cat1农尖,cat2均為CreateCar的實例對象析恋。
  3. CreateCar構(gòu)造函數(shù)中this指向CreateCar實例對象即 new CreateCar( )出來的對象。
  4. 必須帶new 盛卡。
  5. 構(gòu)造函數(shù)首字母大寫助隧,這是規(guī)范,官方都遵循這一個規(guī)范滑沧,如Number() Array()并村。
  6. contructor:這時cat1和cat2會自動含有一個constructor屬性,指向它們的構(gòu)造函數(shù),即CreateCar嚎货。
alert(cat1.constructor == CreateCar); //true
alert(cat2.constructor == CreateCar); //true
  1. 每定義一個函數(shù)橘霎,這個函數(shù)就有一個 prototype 的屬性{},__proto__ 指向被實例化的構(gòu)造函數(shù)的prototype殖属,prototype默認帶constructor屬性姐叁,constructor指向構(gòu)造函數(shù)。
  2. instanceof 運算符:object instanceof constructor運算符洗显,驗證構(gòu)造函數(shù)與實例對象之間的關(guān)系外潜。
alert(cat1 instanceof CreateCar ); //true
alert(cat2 instanceof CreateCar ); //true

四、構(gòu)造函數(shù)的問題

構(gòu)造函數(shù)方法很好用挠唆,但是存在一個浪費內(nèi)存的問題处窥。如果現(xiàn)在為其再添加一個方法showWheel。那么玄组,CreateCar就變成了下面這樣滔驾,這樣做有一個很大的弊端,對于每一個實例對象俄讹,showWheel都是一模一樣的內(nèi)容哆致,每一次生成一個實例,都必須生成重復(fù)的內(nèi)容患膛,多占用一些內(nèi)存摊阀。這樣既不環(huán)保,也缺乏效率。

function CreateCar(color,wheel){

    this.color = color;
    this.wheel = wheel;
    this.showWheel = function(){//添加一個新方法
        alert(this.wheel);
    }   
}

//還是采用同樣的方法胞此,生成實例:
var cat1 = new CreateCar("紅色","4");
var cat2 = new CreateCar("藍色","4");

alert(cat1.showWheel == cat2.showWheel); //false

五臣咖、Prototype 原型

Javascript規(guī)定,每一個構(gòu)造函數(shù)都有一個prototype屬性漱牵,指向另一個對象褐缠。這個對象的所有屬性和方法哲泊,都會被構(gòu)造函數(shù)的實例繼承开仰。 這意味著殷费,我們可以把那些不變的屬性和方法幻妓,直接定義在prototype對象上埠啃。__proto__是原型鏈坐求,指向?qū)嵗暮瘮?shù)原型讼载。

function CreateCar(color,wheel){
    //屬性寫構(gòu)造函數(shù)里面
    this.color = color;
    this.wheel = wheel;
}

//方法寫原型里面
CreateCar.prototype.showWheel = function(){
    alert(this.wheel);
}
CreateCar.prototype.showName = function(){
    alert('車');
}

//生成實例趴荸。
var cat1 = new CreateCar("紅色","4");
var cat2 = new CreateCar("藍色","4");
cat1.showName();//'車'

//這時所有實例的showWheel屬性和showName方法儒溉,其實都是同一個內(nèi)存地址,指向prototype對象发钝,因此就提高了運行效率顿涣。
alert(cat1.showWheel == cat2.showWheel );//true
alert(cat1.showName == cat2.showName );//true
console.log(cat1.__proto__ === CreateCar.prototype); //true

六、對象和函數(shù)的關(guān)系

對象是由函數(shù)構(gòu)造出來的酝豪。

  1. Object是Function 的一個實例涛碑。
Object.constructor  == Function  //true
  1. 函數(shù)是Function 的實例,但不是Object 的實例孵淘。
function fn(){}
fn.constructor  == Function  //true
fn.constructor  == Object    //false 
  1. {} 與 Object 的關(guān)系蒲障。
var obj = {};
obj.constructor  === Object   //true

七、靜態(tài)方法和靜態(tài)屬性

只屬于類而不屬于實例化對象

function foo(){
    this.show = function(){
        return this;
    }
}

foo.test = 123; //靜態(tài)屬性

foo.say = function(){
    return this;
}
foo.say();

var fn = new foo(); //實例化的新的對象瘫证,this指向這個新的對象揉阎,不能訪問類的靜態(tài)方法
fn.say(); //Noname1.html:45 Uncaught TypeError: fn.say is not a function
console.log(foo.say() == fn.say());

八、對象繼承

  1. 利用call()for in繼承 背捌。
    給對象的constructor.prototype添加方法屬性毙籽,對象就會繼承,如果要實現(xiàn)一個對象繼承其他對象毡庆,采用如下方法坑赡。
//人類
function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.run = function(){
    console.log('跑路~')
};
Person.prototype.say = function(){
    console.log('說話~')
};

console.log(Person.prototype);

//男人
function Man(){
    this.sex = "男";
}

Man.prototype = Person.prototype;

Man.prototype.yyy = function(){
    console.log('嚶嚶嚶');
}
//會發(fā)現(xiàn)Person的prototype也改變了,因為復(fù)雜對象的賦值操作是引用而不是賦值
console.log(Person.prototype);
//人類
function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.run = function(){
    console.log('跑路~')
};
Person.prototype.say = function(){
    console.log('說話~')
};

console.log(Person.prototype);

//男人
function Man(){
    this.sex = "男";
}

for(var key in Person.prototype){
    Man.prototype[key] = Person.prototype[key];
    console.log(key)
}
Man.prototype.yyy = function(){
    console.log('嚶嚶嚶');
}

console.log(Person.prototype);
var xm = new Man();
xm.yyy();
  1. 采用中介
function ClassA(name){
    this.name = name;
}
ClassA.prototype.say = function(){
    console.log(666);
}

//中繼來做準備工作
function Ready(){}//
Ready.prototype = ClassA.prototype;//引用

//需要來繼承ClassA
function ClassB(){}
ClassB.prototype = new Ready();//new 返回了一個新對象 __proto__指向被實例化的構(gòu)造函數(shù)的prototype
ClassB.prototype.constructor = ClassB;
console.log(ClassB.prototype);
  1. 采用中介么抗,使用call改變this指向
function ClassA(name){
    this.name = name;
}
ClassA.prototype.showName = function(){
    console.log(this.name);
}

//中繼來做準備工作
function Ready(){}//
Ready.prototype = ClassA.prototype;//引用

//需要來繼承ClassA
function ClassB(name){
    ClassA.call(this,name);
}
ClassB.prototype = new Ready();//new 返回了一個新對象 __proto__指向被實例化的構(gòu)造函數(shù)的prototype
ClassB.prototype.constructor = ClassB;
console.log(ClassB.prototype);
var xiaoming = new ClassB('小明');
xiaoming.showName();

九毅否、多態(tài)

同一個方法,面對不同的對象有不同的表現(xiàn)形式就叫做多態(tài)。

var obj = {
    eat : function(_type){
        if(_type == '貓'){
            console.log('貓糧')
        }else if (_type == "狗") {
            console.log('狗糧')
        }else{
            console.log("吃飯");
        }
    }
};
obj.eat("狗");

十乖坠、hasOwnProperty

查看該屬性是否在這個對象本身上搀突,只有在自身屬性上才會返回真,在原型鏈上會返回假。

function ClassA(){}
ClassA.prototype.test = function(){
    console.log('test')
}

var a = new ClassA();
a.test();
console.log(a.hasOwnProperty('test')); //false

十一仰迁、描述符(修飾符)

描述符是對一個屬性的特性的描述甸昏,defineProperty設(shè)置描述符(修飾符),value設(shè)置屬性值徐许,configurable是否允許修飾符被改變 默認為false施蜜,enumerable 是否可以被枚舉 默認為false,writable 是否可以被 = 等號改變 默認為false雌隅。

var obj = {
    a : 1
};
var c = 666;
Object.defineProperty(obj,'c',{
    //value : 233,
    //enumerable : false,
    //writable : true,//他的值能否改變
            
    //設(shè)置的時候調(diào)用
    set : function(n){
        //n 就是等號的右邊的值
        c = c*n;
    },

    //獲取的時候調(diào)用
    get : function(){
        return c;
    },

    configurable : true,//是否可以再次修改修飾符
});
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末翻默,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子恰起,更是在濱河造成了極大的恐慌修械,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件检盼,死亡現(xiàn)場離奇詭異肯污,居然都是意外死亡,警方通過查閱死者的電腦和手機吨枉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門蹦渣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人貌亭,你說我怎么就攤上這事柬唯。” “怎么了圃庭?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵锄奢,是天一觀的道長。 經(jīng)常有香客問我剧腻,道長斟薇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任恕酸,我火速辦了婚禮堪滨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蕊温。我一直安慰自己袱箱,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布义矛。 她就那樣靜靜地躺著发笔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凉翻。 梳的紋絲不亂的頭發(fā)上了讨,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音,去河邊找鬼前计。 笑死胞谭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的男杈。 我是一名探鬼主播丈屹,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伶棒!你這毒婦竟也來了旺垒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤肤无,失蹤者是張志新(化名)和其女友劉穎先蒋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宛渐,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡鞭达,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了皇忿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡坦仍,死狀恐怖鳍烁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情繁扎,我是刑警寧澤幔荒,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站梳玫,受9級特大地震影響爹梁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜提澎,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一姚垃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盼忌,春花似錦积糯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至跨嘉,卻和暖如春川慌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工梦重, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兑燥,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓忍饰,卻偏偏與公主長得像贪嫂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子艾蓝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容