成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

<筆記>面向?qū)ο蟮脑O(shè)計(jì)模式

warkiz / 2945人閱讀

摘要:創(chuàng)建對(duì)象什么是工廠模式封裝一個(gè)函數(shù)用來(lái)創(chuàng)建對(duì)象并給對(duì)象中特定的屬性添加值優(yōu)點(diǎn)是可以循環(huán)調(diào)用缺點(diǎn)是每一個(gè)創(chuàng)建出來(lái)的對(duì)象都是獨(dú)立的不能確定它是哪個(gè)類型的對(duì)象或者說(shuō)是想要將哪個(gè)對(duì)象作為模板進(jìn)行創(chuàng)建每個(gè)對(duì)象都是獨(dú)立的并且指向的不能辨別基于哪個(gè)對(duì)象為

創(chuàng)建對(duì)象 什么是工廠模式 ?

封裝一個(gè)函數(shù) , 用來(lái)創(chuàng)建對(duì)象并給對(duì)象中特定的屬性添加值 , 優(yōu)點(diǎn)是可以循環(huán)調(diào)用 , 缺點(diǎn)是每一個(gè)創(chuàng)建出來(lái)的對(duì)象都是獨(dú)立的 , 不能確定它是哪個(gè)類型的對(duì)象 ( 或者說(shuō)是想要將哪個(gè)對(duì)象作為模板進(jìn)行創(chuàng)建 )

function func(name, age) {
    var o = {
        "name" : name,
        "age" : age
    };
    return o;
}
var person = func("oswald", 24);
var person2 = func("oswald", 24);
// {name: "oswald", age: 24}
console.log(person === person2);
// false
console.log(person.__proto__ === Object.prototype);     // true
console.log(person2.__proto__ === Object.prototype);    // true
// 每個(gè)對(duì)象都是獨(dú)立的并且指向 Object.prototype 的 , 不能辨別基于哪個(gè)對(duì)象為原型
什么是構(gòu)造函數(shù)模式 構(gòu)造函數(shù)模式和工廠模式的區(qū)別

構(gòu)造函數(shù)模式就是通過(guò)構(gòu)造函數(shù)來(lái)創(chuàng)建自定義類型的對(duì)象 , 創(chuàng)建出來(lái)的對(duì)象都指向了同一個(gè)構(gòu)造函數(shù)的 prototype , 解決了工廠模式中不能識(shí)別對(duì)象模板的問(wèn)題

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.sayName = function(){
        console.log(this.name);
    };
    /*  沒(méi)有顯式的創(chuàng)建對(duì)象
        用 this 代替新對(duì)象
        沒(méi)有 return 語(yǔ)句    */
}
var person1 = new Person("oswald", 24);
console.log(person1);    // {name: "oswald", age: 24}
console.log(person1.__proto__ === Person.prototype);    // true
// person1 指向了 構(gòu)造函數(shù) func.prototype
console.log(person1 instanceof Person);     // true
// person1 對(duì)象是構(gòu)造函數(shù) Person ( 也可以叫做 Person 類型 ) 的實(shí)例
console.log(person1 instanceof Object);     // true
// person1 對(duì)象也是 Object 類型的實(shí)例 
構(gòu)造函數(shù)模式的缺點(diǎn)

但是 , 上面的構(gòu)造函數(shù)模式也不是沒(méi)有缺點(diǎn)的 : 單純的構(gòu)造函數(shù)模式創(chuàng)建對(duì)象的時(shí)候 , 對(duì)象中每個(gè)方法都會(huì)在實(shí)例對(duì)象上重新創(chuàng)建一次 , 也就是說(shuō)每次都會(huì)創(chuàng)建一個(gè)看起來(lái)相同但是完全不是一個(gè)"方法"的方法

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.sayName = function(){
        console.log(this.name);
    };
}
var person1 = new Person("oswald", 24);
var person2 = new Person("oswald", 24);
console.log(person1.sayName = person2.sayName);     // false
// 每次創(chuàng)建對(duì)象的時(shí)候 , 都會(huì)生成一個(gè)功能一樣但是是不同 Function 實(shí)例的方法
什么是原型模式

每個(gè)函數(shù)在創(chuàng)建的時(shí)候都會(huì)有一個(gè) prototype 屬性 , 這個(gè)屬性指向一個(gè)對(duì)象

所有以這個(gè)函數(shù)為構(gòu)造函數(shù)創(chuàng)建的實(shí)例對(duì)象 , 都會(huì)連接到構(gòu)造函數(shù)的 prototype 屬性指向的這個(gè)對(duì)象上 , 并且可以訪問(wèn)這個(gè)對(duì)象的所有屬性和方法 , 這個(gè)對(duì)象就叫做原型對(duì)象

原型對(duì)象在創(chuàng)建的時(shí)候自帶一個(gè)不可枚舉的 constructor 屬性 , 指向構(gòu)造函數(shù)

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
    Person.prototype.sayName = function(){
        console.log(this.name);
    };
}

var person1 = new Person();
console.log(person1);
// {} 得到一個(gè)空對(duì)象 , 因?yàn)閯?chuàng)建的屬性和方法都在實(shí)例的原型對(duì)象上
console.log(Person.prototype);
// {name: "oswald", age: 24, sayName: f(...)}
console.log(person1.name);
// oswald 得到一個(gè)名字 , 因?yàn)閷?shí)例對(duì)象可以從它的原型對(duì)象上查找屬性和方法

var person2 = new Person();
console.log(person2.sayName === person1.sayName);   // true
// person1 和 person2 訪問(wèn)的 sayName 方法都是原型對(duì)象上的方法 , 不是它們自身的 , 這樣就解決了構(gòu)造函數(shù)模式多次創(chuàng)建方法實(shí)例的缺點(diǎn)
原型對(duì)象中的屬性和方法會(huì)和實(shí)例對(duì)象自有的沖突嗎

如果當(dāng)前實(shí)例對(duì)象中已經(jīng)有了想要查找的屬性和方法 , 會(huì)直接使用實(shí)例對(duì)象的屬性和方法 , 如果沒(méi)有才去原型對(duì)象中查找

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
}
var person1 = new Person();
console.log(person1.name);  // oswald
person1.name = "yin";
console.log(person1.name);  // yin
實(shí)例對(duì)象怎么訪問(wèn)原型對(duì)象

在火狐、谷歌等瀏覽器中提供了一個(gè) __proto__ 的屬性 , 可以訪問(wèn)它的原型對(duì)象

ECMAScript 5 中提供了 Object.getPrototypeOf( ) 方法可以檢測(cè)并返回它的原型對(duì)象

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
}
var person1 = new Person();
console.log(person1.__proto__ === Person.prototype);
// true
console.log(Object.getPrototypeOf(person1) === Person.prototype);
// true
原型對(duì)象和原型屬性有什么區(qū)別

實(shí)例對(duì)象 ( person1 ) 的原型對(duì)象 ( __proto__ ) 是創(chuàng)建當(dāng)前對(duì)象的構(gòu)造函數(shù) ( Person ) 的原型屬性 ( prototype ) , 個(gè)人用來(lái)區(qū)別訪問(wèn)途徑 , 便于理解

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
}
var person1 = new Person();
console.log(person1.__proto__ === Person.prototype);
// true

實(shí)例對(duì)象可以查找它的原型對(duì)象 , 但是不能查找它自己的原型屬性

function Person(){
}
var person1 = new Person();
person1.prototype = {
    name: "yin",
    age: 23
}
console.log(person1.name);  // undefined
怎么檢測(cè)屬性或者方法在實(shí)例對(duì)象中是否存在

使用繼承自 Object 對(duì)象的 hasOwnProperty( ) 方法可以檢車要查找的屬性或方法是否來(lái)自實(shí)例對(duì)象而不是實(shí)例對(duì)象的原型對(duì)象

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
}
var person1 = new Person();
console.log(person1.name);  // oswald
console.log(person1.hasOwnProperty("name"));
// false 當(dāng)前查找到的 name 屬性來(lái)自原型對(duì)象
person1.name = "yin";
console.log(person1.name);  // yin
console.log(person1.hasOwnProperty("name"));
// true 當(dāng)前查找到的 name 屬性來(lái)自實(shí)例對(duì)象
枚舉對(duì)象中的屬性和方法有哪些方法

for - in 遍歷 , 會(huì)將當(dāng)前對(duì)象和當(dāng)前對(duì)象的原型對(duì)象上所有可以枚舉的屬性和方法都返回

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
}
var person1 = new Person();
person1.color = "red";
for( poop in person1 ){
    console.log(poop);
    // color, name, age
}

ECMAScript 5 的 Object.key( ) 方法 , 遍歷當(dāng)前對(duì)象的可枚舉屬性和方法 , 不會(huì)去找原型對(duì)象

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
}
var person1 = new Person();
person1.color = "red";
var p1keys = Object.key(person1);
console.log(p1keys);    // color

Object.getOwnPropertyNames( ) 方法 , 遍歷當(dāng)前對(duì)象的所有屬性和方法 , 包括不可枚舉的 , 不會(huì)去找原型對(duì)象

function Person(){
    Person.prototype.name = "oswald";
    Person.prototype.age = 24;
}
var person1 = new Person();
person1.color = "red";
var p1keys = Object.getOwnPropertyNames(person1);
console.log(p1keys);
// color
var Ppkeys = Object.getOwnPropertyNames(Person.prototype);
console.log(Ppkeys);
// constructor、name、age
原型模式創(chuàng)建對(duì)象的缺點(diǎn)

原型中的所有屬性和方法都是共享的 , 如果有多個(gè)實(shí)例 , 通過(guò)其中一個(gè)實(shí)例改變?cè)蛯?duì)象中的屬性和方法 , 其他實(shí)例訪問(wèn)的屬性會(huì)跟著改變

組合使用構(gòu)造函數(shù)模式和原型模式

將對(duì)象的私有屬性和方法通過(guò)構(gòu)造函數(shù)模式創(chuàng)建 , 將對(duì)象的公共屬性和方法通過(guò)原型模式創(chuàng)建

function Person(name,age){
    /* 私有屬性 */
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function(){
    /* 公共方法 */
    console.log(this.name);
}
var person1 = new Person("oswald", 24);
person1.sayName();  // oswald
繼承 什么是原型鏈

原型鏈就是連接實(shí)例對(duì)象和原型對(duì)象的鏈接

/* 一般函數(shù)的原型鏈 */
function func(){
    console.log(123);
}

console.log(func.__proto__);    // Function.prototype
// func 函數(shù)是 Function 構(gòu)造函數(shù)的實(shí)例對(duì)象
console.log(func.__proto__.__proto__);  // Object.prototype
// func 函數(shù)的原型對(duì)象是 Object 構(gòu)造函數(shù)的實(shí)例對(duì)象
console.log(func.__proto__.__proto__.proto__);  // null
// 這里就是原型鏈的頭了 , 所有原型鏈查到 Object.prototype 再往上就會(huì)返回 null

/* 一般構(gòu)造函數(shù)的原型鏈 */
function Obj(){
    Func.prototype.name = "oswald";
}
var obj = new Obj();
console.log(obj);    // {}
console.log(obj.name);    // oswald
// obj 對(duì)象通過(guò)原型鏈查找到了 name 屬性
console.log(Obj.__proto__);    // Obj.prototype
// obj 對(duì)象是 Obj 構(gòu)造函數(shù)的實(shí)例對(duì)象
console.log(Obj.__proto__.__proto__);    // Object.prototype
// obj 對(duì)象的原型對(duì)象是 Object 構(gòu)造函數(shù)的實(shí)例
console.log(Obj.__proto__.__proto__.__proto__);    // null
// 到頭了
原型鏈繼承

原型鏈繼承的原理就是實(shí)例對(duì)象可以訪問(wèn)原型對(duì)象的屬性和方法 , 并通過(guò)原型鏈向上查找

function Oswald(){
    this.color = "red";
    Oswald.prototype.sayName = function(){
        console.log(this.name)
    };
}
var oswald = new Oswald();

function Yin(name, age){
    this.name = name;
    this.age = age;
    Yin.prototype.sayAge = function(){
        console.log(this.age);
    }
}
Yin.prototype = oswald;
/*
原型鏈繼承的核心 , 把父類型 ( Oswald ) 的實(shí)例對(duì)象 ( oswald )
設(shè)置為子類型 ( Yin ) 的原型屬性 ( Yin.prototype )
*/

var yin = new Yin("oswald", 24);
// 必須要先繼承再創(chuàng)建實(shí)例 , 否則會(huì)出現(xiàn) Yin.prototype != yin.__proto__ 的情況

yin.sayName();    // oswald  繼承了 Oswald 類型原型上的方法
yin.sayAge();     // 24      繼承了 Yin 類型原型上的方法
借用構(gòu)造函數(shù)式繼承

我們之前討論的原型鏈繼承 , 不能在創(chuàng)建子類型的實(shí)例對(duì)象的時(shí)候 , 給父類型的構(gòu)造函數(shù)傳遞參數(shù) , 如果要給父類型的構(gòu)造函數(shù)傳遞參數(shù) , 就會(huì)影響所有的子類型實(shí)例對(duì)象

如果我們想要解決這個(gè)問(wèn)題 , 可以借調(diào)父類型的構(gòu)造函數(shù) , 在新創(chuàng)建的對(duì)象上執(zhí)行構(gòu)造函數(shù)

function Oswald(color){
    this.color = color;
    this.sayName = function(){
        console.log(this.name)
    };
}

function Yin(name, age, color){
    Oswald.call(this, color);
    // 在 Yin 構(gòu)造函數(shù)創(chuàng)建的新對(duì)象中調(diào)用 Oswald 函數(shù)
    this.name = name;
    this.age = age;
}

var yin = new Yin("yin", 24, "red");

yin.sayName();      // yin
組合式繼承

但是借用構(gòu)造函數(shù)繼承只能夠繼承父類型自己的屬性和方法 , 不能繼承原型鏈上 , 這個(gè)時(shí)候我們可以使用原型鏈和借用構(gòu)造函數(shù)的組合式繼承 , 但是這個(gè)方法會(huì)調(diào)用兩次父類型構(gòu)造函數(shù)

function Super(color){
    this.color = color;
    // 自己的屬性
    Super.prototype.sayName = function(){
        console.log(this.name)
    };
    // 原型鏈上的方法
}

function Sub(name, age, color){
    Super.call(this, color);        // 第二次調(diào)用 Super , 被當(dāng)做普通函數(shù)調(diào)用
    // 繼承 Super 構(gòu)造函數(shù)自己的屬性和方法
    this.name = name;
    this.age = age;
}
Sub.prototype = new Super();        // 第一次調(diào)用 Super , 被當(dāng)做構(gòu)造函數(shù)調(diào)用
// 繼承 Super 原型鏈上的屬性和方法
var yin = new Sub("yin", 24, "red");

yin.sayName();      // yin
原型式繼承

ES 5 中使用 Object.create( o ) 方法規(guī)范了原型式繼承 , 這個(gè)方法會(huì)返回一個(gè)新對(duì)象 , 新對(duì)象的原型對(duì)象指向傳入的參數(shù)對(duì)象 o

function obj(o){    // Object.create( ) 方法的原理
    function F(){};
    F.prototype = o;
    return new F();
}
var person = {
    name: "oswald",
    color: ["red"]
}

var person1 = obj(person);
var person2 = Object.create(person);

console.log(person1 === person2);   // false
console.log(person1.__proto__ === person2.__proto__);   // true
寄生組合式繼承

目前最優(yōu)的繼承模式

function Super(color){
    this.color = color;
    Super.prototype.sayName = function(){
        console.log(this.name);
    }
}
function Sub(name, color){
    Super.call(this, color);
    // 借調(diào) Super 構(gòu)造函數(shù)繼承實(shí)例屬性
    this.name = name;
}

var F = Object.create(Super.prototype);
F.constructor = Sub;
Sub.prototype = F;


var yin = new Sub("oswald","red");

yin.sayName();      // oswald

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108272.html

相關(guān)文章

  • &lt;&lt;深入PHP面向對(duì)象、模式與實(shí)踐&gt;&gt;讀書(shū)筆記:面向對(duì)象設(shè)計(jì)和過(guò)程式編程

    摘要:注本文內(nèi)容來(lái)深入面向?qū)ο竽J脚c實(shí)踐中節(jié)。面向?qū)ο笤O(shè)計(jì)與過(guò)程式編程面向?qū)ο笤O(shè)計(jì)和過(guò)程式編程有什么不同呢可能有些人認(rèn)為最大的不同在于面向?qū)ο缶幊讨邪瑢?duì)象。面向?qū)ο缶幊毯瓦^(guò)程式編程的一個(gè)核心區(qū)別是如何分配職責(zé)。 注:本文內(nèi)容來(lái)中6.2節(jié)。 6.2 面向?qū)ο笤O(shè)計(jì)與過(guò)程式編程 ??面向?qū)ο笤O(shè)計(jì)和過(guò)程式編程有什么不同呢?可能有些人認(rèn)為最大的不同在于面向?qū)ο缶幊讨邪瑢?duì)象。事實(shí)上,這種說(shuō)法不準(zhǔn)確。...

    xiao7cn 評(píng)論0 收藏0
  • Python超細(xì)膩研究面向對(duì)象設(shè)計(jì)

      面向?qū)ο笤O(shè)計(jì)是一類編程方式,此編程方式的落地式需要使用類和目標(biāo)來(lái)達(dá)到,因此,面向?qū)ο笤O(shè)計(jì)本身就是對(duì)類和目標(biāo)的應(yīng)用,今日給大家介紹一下python面向?qū)ο笤O(shè)計(jì)開(kāi)發(fā)設(shè)計(jì)及本質(zhì)特征,感興趣的小伙伴一起了解一下吧  序言  面向?qū)ο笤O(shè)計(jì)對(duì)新手而言不難理解但無(wú)法運(yùn)用,盡管我們給大家匯總過(guò)面向?qū)ο髴?zhàn)略部署方式(定義類、創(chuàng)建對(duì)象、給目標(biāo)發(fā)信息),可是看似簡(jiǎn)單其實(shí)不簡(jiǎn)單。大量程序編寫(xiě)訓(xùn)練與閱讀高質(zhì)量的編碼有可...

    89542767 評(píng)論0 收藏0
  • Python面向對(duì)象三大特性封裝、繼承、多態(tài)

      小編寫(xiě)這篇文章的主要目的,主要是來(lái)給大家介紹關(guān)于Python的一些事情,主要還是涉及到面對(duì)面對(duì)象編程的一些實(shí)例,其中,主要涉及到的內(nèi)容涵蓋封裝、繼承、多態(tài)等多種形式,就具體的形式,下面就給大家詳細(xì)解答下?! ython是一門(mén)面向?qū)ο蟮恼Z(yǔ)言。面向?qū)ο蠖加腥筇匦裕悍庋b、繼承、多態(tài)。  下面分別來(lái)說(shuō)說(shuō)這三大特性:  1、封裝  隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外提供公共訪問(wèn)方式。在python中用...

    89542767 評(píng)論0 收藏0
  • python命令 – 解釋器、交互式、面向對(duì)象編程語(yǔ)言

    Python 是一種解釋型的、交互式的、面向?qū)ο蟮木幊陶Z(yǔ)言,它結(jié)合了非凡的功能和非常清晰的語(yǔ)法。Python Library Reference 記錄了內(nèi)置的和標(biāo)準(zhǔn)的類型、常量、函數(shù)和模塊。語(yǔ)法格式:python [參數(shù)]常用參數(shù):參數(shù) 描述-c 直接運(yùn)行 python 語(yǔ)句-v 會(huì)輸出每一個(gè)模塊引用信息-i 運(yùn)行完 python 腳本文件以后打開(kāi)一個(gè) python 環(huán)境-m 將模塊按照腳本執(zhí)行命...

    社區(qū)管理員 評(píng)論0 收藏0
  • Python學(xué)習(xí)筆記

    入坑 Python自從進(jìn)入公司,到現(xiàn)在也有半年的時(shí)間。這半年的時(shí)間從 python 到入門(mén)到開(kāi)發(fā)了幾個(gè)小項(xiàng)目,類型涵蓋了web應(yīng)用 程序、爬蟲(chóng)程序 (scrapy),python腳本工具,自動(dòng)化工具。對(duì) python 語(yǔ)言也越來(lái)越熟悉,當(dāng)然也有所感悟和總結(jié)。首先 Python 真的讓語(yǔ)言成 了一個(gè)工具,入門(mén)代價(jià)很小,上手能夠開(kāi)發(fā)出小工具,可以更快體驗(yàn)到編程的樂(lè)趣。但是做到pythonic需要更多的...

    社區(qū)管理員 評(píng)論0 收藏0

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

0條評(píng)論

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