国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Javascript重溫OOP之面向?qū)ο?

AbnerMing / 1076人閱讀

摘要:類的繼承建立繼承關(guān)系修改的指向調(diào)用父類方法調(diào)用父類的構(gòu)造器調(diào)用父類上的方法封裝命名空間是沒有命名空間的,因此可以用對(duì)象模擬。參考資料面向?qū)ο?/p>

面向?qū)ο蟪绦蛟O(shè)計(jì)(Object-oriented programming,OOP)是一種程序設(shè)計(jì)范型,同時(shí)也是一種程序開發(fā)的方法。對(duì)象指的是類的實(shí)例。它將對(duì)象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴(kuò)展性。——維基百科

一般面向?qū)ο蟀豪^承,封裝,多態(tài),抽象

對(duì)象形式的繼承 淺拷貝
var Person = {
    name: "allin",
    age: 18,
    address: {
        home: "home",
        office: "office",
    }
    sclools: ["x","z"],
};

var programer = {
    language: "js",
};

function extend(p, c){
    var c = c || {};
    for( var prop in p){
        c[prop] = p[prop];
    }
}
extend(Person, programer);
programer.name;  // allin
programer.address.home;  // home
programer.address.home = "house";  //house
Person.address.home;  // house

從上面的結(jié)果看出,淺拷貝的缺陷在于修改了子對(duì)象中引用類型的值,會(huì)影響到父對(duì)象中的值,因?yàn)樵跍\拷貝中對(duì)引用類型的拷貝只是拷貝了地址,指向了內(nèi)存中同一個(gè)副本。

深拷貝
function extendDeeply(p, c){
    var c = c || {};
    for (var prop in p){
        if(typeof p[prop] === "object"){
            c[prop] = (p[prop].constructor === Array)?[]:{};
            extendDeeply(p[prop], c[prop]);
        }else{
            c[prop] = p[prop];
        }
    }
}

利用遞歸進(jìn)行深拷貝,這樣子對(duì)象的修改就不會(huì)影響到父對(duì)象。

extendDeeply(Person, programer);
programer.address.home = "allin";
Person.address.home; // home
利用call和apply繼承
function Parent(){
    this.name = "abc";
    this.address = {home: "home"};
}
function Child(){
    Parent.call(this);
    this.language = "js"; 
}
ES5中的Object.create()
var p = { name : "allin"};
var obj = Object.create(o);
obj.name; // allin

Object.create()作為new操作符的替代方案是ES5之后才出來的。我們也可以自己模擬該方法:

//模擬Object.create()方法
function myCreate(o){
    function F(){};
    F.prototype = o;
    o = new F();
    return o;
}
var p = { name : "allin"};
var obj = myCreate(o);
obj.name; // allin

目前,各大瀏覽器的最新版本(包括IE9)都部署了這個(gè)方法。如果遇到老式瀏覽器,可以用下面的代碼自行部署。

  if (!Object.create) {
    Object.create = function (o) {
       function F() {}
      F.prototype = o;
      return new F();
    };
  }
類的繼承 Object.create()
function Person(name, age){}
Person.prototype.headCount = 1;
Person.prototype.eat = function(){
    console.log("eating...");
}
function Programmer(name, age, title){}

Programmer.prototype = Object.create(Person.prototype); //建立繼承關(guān)系
Programmer.prototype.constructor = Programmer;  // 修改constructor的指向
調(diào)用父類方法
function Person(name, age){
    this.name = name;
    this.age = age;
}
Person.prototype.headCount = 1;
Person.prototype.eat = function(){
    console.log("eating...");
}

function Programmer(name, age, title){
    Person.apply(this, arguments); // 調(diào)用父類的構(gòu)造器
}


Programmer.prototype = Object.create(Person.prototype);
Programmer.prototype.constructor = Programmer;

Programmer.prototype.language = "js";
Programmer.prototype.work = function(){
    console.log("i am working code in "+ this.language);
    Person.prototype.eat.apply(this, arguments); // 調(diào)用父類上的方法
}
封裝 命名空間

js是沒有命名空間的,因此可以用對(duì)象模擬。

var app = {};  // 命名空間app
//模塊1
app.module1 = {
    name: "allin",
    f: function(){
        console.log("hi robot");
    }
};
app.module1.name; // "allin"
app.module1.f();  // hi robot
靜態(tài)成員
function Person(name){
    var age = 100;
    this.name = name;
}
//靜態(tài)成員
Person.walk = function(){
    console.log("static");
};
Person.walk();  // static
私有與公有
function Person(id){
    // 私有屬性與方法
    var name = "allin";
    var work = function(){
        console.log(this.id);
    };
    //公有屬性與方法
    this.id = id;
    this.say = function(){
        console.log("say hello");
        work.call(this);
    };
};
var p1 = new Person(123);
p1.name; // undefined
p1.id;  // 123
p1.say();  // say hello 123
模塊化
var moduleA;
moduleA = function() {
    var prop = 1;

    function func() {}

    return {
        func: func,
        prop: prop
    };
}(); // 立即執(zhí)行匿名函數(shù)

prop,func 不會(huì)被泄露到全局作用域。或者另一種寫法,使用 new

moduleA = new function() {
    var prop = 1;

    function func() {}

    this.func = func;
    this.prop = prop;
}
多態(tài) 模擬方法重載

arguments屬性可以取得函數(shù)調(diào)用的實(shí)參個(gè)數(shù),可以利用這一點(diǎn)模擬方法的重載。

function demo(a, b ){
    console.log(demo.length); // 得到形參個(gè)數(shù)
    console.log(arguments.length); //得到實(shí)參個(gè)數(shù)
    console.log(arguments[0]);  // 第一個(gè)實(shí)參 4
    console.log(arguments[1]);  // 第二個(gè)實(shí)參 5
}

demo(4, 5, 6);
//實(shí)現(xiàn)可變長(zhǎng)度實(shí)參的相加
function add(){
    var total = 0;
    for( var i = arguments.length - 1; i >= 0; i--){
        total += arguments[i];
    }
    return total;
}

console.log(add(1));  // 1
console.log(add(1, 2, 3));  // 7


// 參數(shù)不同的情況
function fontSize(){
    var ele = document.getElementById("js");
    if(arguments.length == 0){
        return ele.style.fontSize;
    }else{
        ele.style.fontSize = arguments[0];
    }
}
fontSize(18);
console.log(fontSize());

// 類型不同的情況
function setting(){
    var ele = document.getElementById("js");
    if(typeof arguments[0] === "object"){
        for(var p in arguments[0]){
            ele.style[p] = arguments[0][p];
        }
    }else{
        ele.style.fontSize = arguments[0];
        ele.style.backgroundColor = arguments[1];
    }
}
setting(18, "red");
setting({fontSize:20, backgroundColor: "green"});
方法重寫
function F(){}
var f = new F();
F.prototype.run = function(){
    console.log("F");
}
f.run(); // F

f.run = function(){
    console.log("fff");
}
f.run();  // fff
抽象類

在構(gòu)造器中 throw new Error(""); 拋異常。這樣防止這個(gè)類被直接調(diào)用。

function DetectorBase() {
    throw new Error("Abstract class can not be invoked directly!");
}

DetectorBase.prototype.detect = function() {
    console.log("Detection starting...");
};
DetectorBase.prototype.stop = function() {
    console.log("Detection stopped.");
};
DetectorBase.prototype.init = function() {
    throw new Error("Error");
};

// var d = new DetectorBase();// Uncaught Error: Abstract class can not be invoked directly!

function LinkDetector() {}
LinkDetector.prototype = Object.create(DetectorBase.prototype);
LinkDetector.prototype.constructor = LinkDetector;

var l = new LinkDetector();
console.log(l); //LinkDetector {}__proto__: LinkDetector
l.detect(); //Detection starting...
l.init(); //Uncaught Error: Error
參考資料

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90832.html

相關(guān)文章

  • Javascript重溫OOPJS的解析與執(zhí)行過程

    摘要:了解面向?qū)ο缶幊讨埃紫纫私獾膱?zhí)行順序。的解析過程分為兩個(gè)階段預(yù)處理階段與執(zhí)行期。在執(zhí)行階段的執(zhí)行上下文對(duì)象由賦值為指向?qū)?yīng)函數(shù) 了解js面向?qū)ο缶幊讨埃紫纫私鈐s的執(zhí)行順序。js的解析過程分為兩個(gè)階段:預(yù)處理階段與執(zhí)行期。 預(yù)處理階段 在預(yù)處理階段,js會(huì)首先創(chuàng)建一個(gè)執(zhí)行上下文對(duì)象(Execute Context,然后掃描聲明式函數(shù)和用var定義的變量,將其加入執(zhí)行上下文環(huán)...

    xumenger 評(píng)論0 收藏0
  • 重溫基礎(chǔ)】15.JS對(duì)象介紹

    摘要:構(gòu)造函數(shù)通常首字母大寫,用于區(qū)分普通函數(shù)。這種關(guān)系常被稱為原型鏈,它解釋了為何一個(gè)對(duì)象會(huì)擁有定義在其他對(duì)象中的屬性和方法。中所有的對(duì)象,都有一個(gè)屬性,指向?qū)嵗龑?duì)象的構(gòu)造函數(shù)原型由于是個(gè)非標(biāo)準(zhǔn)屬性,因此只有和兩個(gè)瀏覽器支持,標(biāo)準(zhǔn)方法是。 從這篇文章開始,復(fù)習(xí) MDN 中級(jí)教程 的內(nèi)容了,在初級(jí)教程中,我和大家分享了一些比較簡(jiǎn)單基礎(chǔ)的知識(shí)點(diǎn),并放在我的 【Cute-JavaScript】系...

    booster 評(píng)論0 收藏0
  • Javascript重溫OOP原型與原型鏈

    摘要:在構(gòu)造函數(shù)中的中定義的屬性和方法,會(huì)被創(chuàng)建的對(duì)象所繼承下來。從上面的輸出結(jié)果看出,指向了其構(gòu)造函數(shù)的,而本身也是一個(gè)對(duì)象,其內(nèi)部也有屬性,其指向的是直到最后指向,這條原型鏈才結(jié)束。和都指向,說明原型鏈到終止。 prototype原型對(duì)象 每個(gè)函數(shù)都有一個(gè)默認(rèn)的prototype屬性,其實(shí)際上還是一個(gè)對(duì)象,如果被用在繼承中,姑且叫做原型對(duì)象。 在構(gòu)造函數(shù)中的prototype中定義的屬性...

    lindroid 評(píng)論0 收藏0
  • Javascript重溫OOP作用域與閉包

    摘要:的變量作用域是基于其特有的作用域鏈的。需要注意的是,用創(chuàng)建的函數(shù),其作用域指向全局作用域。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。 作用域 定義 在編程語(yǔ)言中,作用域控制著變量與參數(shù)的可見性及生命周期,它能減少名稱沖突,而且提供了自動(dòng)內(nèi)存管理 --javascript 語(yǔ)言精粹 我理解的是,一個(gè)變量、函數(shù)或者成員可以在代碼中訪問到的范圍。 js的變量作...

    JessYanCoding 評(píng)論0 收藏0
  • Javascript重溫OOP類與對(duì)象

    摘要:對(duì)構(gòu)造函數(shù)使用運(yùn)算符,就能生成實(shí)例,并且變量會(huì)綁定在實(shí)例對(duì)象上。這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)的實(shí)例繼承。 對(duì)象 對(duì)象的含義 所謂對(duì)象,就是一種無序的數(shù)據(jù)集合,由若干個(gè)鍵值對(duì)(key-value)構(gòu)成。 對(duì)象的創(chuàng)建 使用new運(yùn)算符創(chuàng)建Object var p = new Object(); p.name = Tony; 使用對(duì)象字面量的形式 //對(duì)象字面量形...

    RancherLabs 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<