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

資訊專欄INFORMATION COLUMN

《JS高級(jí)程序設(shè)計(jì)》讀書(shū)筆記----JS創(chuàng)建對(duì)象的七種模式

Dogee / 3355人閱讀

摘要:用對(duì)象字面量形式創(chuàng)建的對(duì)象,直接賦值給函數(shù)的原型對(duì)象,本質(zhì)上完全重寫(xiě)了其對(duì)象,因此屬性也就變成了新對(duì)象的屬性指向構(gòu)造函數(shù),不再指向函數(shù)。

【上一篇】:JavaScript對(duì)象內(nèi)部屬性及其特性總結(jié)

工廠模式(★★)
先在內(nèi)部顯示地創(chuàng)建一個(gè)臨時(shí)對(duì)象,根據(jù)接收的參數(shù)來(lái)構(gòu)建(賦值屬性和方法)該對(duì)象,并返回該對(duì)象。
缺點(diǎn):沒(méi)有解決對(duì)象識(shí)別的問(wèn)題(即無(wú)法確認(rèn)一個(gè)對(duì)象的類型)。
function PersonFactory (name, age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.sayName = function(){
        console.log(this.name)
    }
    return o;
}

var p1 = PersonFactory();
var p2 = PersonFactory();
p1 instanceof Object; // true
p2 instanceof Object; // true
p1 instanceof PersonFactory; // false  無(wú)法識(shí)別具體對(duì)象類型
p2 instanceof PersonFactory; // false
構(gòu)造函數(shù)模式(★★★)

函數(shù)名首字母一般大寫(xiě)(如:Person,借鑒OO語(yǔ)言命名習(xí)慣)區(qū)別于其他函數(shù);

構(gòu)造函數(shù)本身也是函數(shù),只不過(guò)可以用來(lái)參加對(duì)象而已;

每個(gè)新建的實(shí)例對(duì)象都有一個(gè)constructor屬性,該屬性指向構(gòu)造函數(shù)自身Person

構(gòu)造函數(shù)也可以被當(dāng)做普通函數(shù)來(lái)調(diào)用;

在全局作用域中調(diào)用一個(gè)函數(shù)時(shí),this對(duì)象總是指向Global對(duì)象(瀏覽器中即window對(duì)象)

【優(yōu)點(diǎn)】自定義構(gòu)造函數(shù)可以將它的實(shí)例標(biāo)識(shí)為一種特定的類型;

【缺點(diǎn)】構(gòu)造函數(shù)的主要問(wèn)題是,每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍;

調(diào)用構(gòu)造函數(shù)實(shí)際經(jīng)歷4個(gè)步驟

創(chuàng)建(隱式地)一個(gè)新對(duì)象;

將構(gòu)造函數(shù)的新對(duì)象賦值給新對(duì)象(此時(shí)this指向這個(gè)新對(duì)象);

執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性);

返回新對(duì)象(該構(gòu)造函數(shù)的實(shí)例);

與工廠模式比較

沒(méi)有顯示地創(chuàng)建對(duì)象;

直接將屬性和方法賦值給this對(duì)象;

沒(méi)有return語(yǔ)句;

優(yōu)點(diǎn):可以確認(rèn)具體對(duì)象類型;

function Person (name, age){
    this.name = name;
    this.age = age;
    this.sayName = function(){
        console.log(this.name);
    }
}
// 當(dāng)做普通函數(shù)
var p1 = new Person("Tom", 20);
var p2 = new Person("Greg", 30);
p1 instanceof Object;         // true
p2 instanceof Object;         // true
p1 instanceof PersonFactory;  // true 可以確認(rèn)具體對(duì)象類型
p2 instanceof PersonFactory;  // true

// 作為普通函數(shù)調(diào)用
Person("Green", 30);  // 屬性和方法都被添加到window對(duì)象了
window.sayName();     // "Green"

// 在另一個(gè)對(duì)象的作用域中調(diào)用
var obj = new Object();
Person.call(obj , "Jim", 23);
obj .sayName(); // "Jim"
原型模式(★★★)

構(gòu)造函數(shù)變?yōu)榭蘸瘮?shù);

將所有屬性和方法都添加到了構(gòu)造函數(shù)的prototype屬性中;

與構(gòu)造函數(shù)模式比較

不同:新對(duì)象的屬性和方法由所有實(shí)例共享(p1和p2訪問(wèn)的都是同一組屬性和同一個(gè)函數(shù));

function Person(){}

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

var p1 = new Person(), p2 = new Person();
p1.sayName();// "Tom"
p2.sayName();// "Tom"
console.log(p1.sayName === p2.sayName);// true
利用更簡(jiǎn)單的原型語(yǔ)法

每創(chuàng)建一個(gè)函數(shù),就會(huì)同時(shí)創(chuàng)建它的prototype對(duì)象,該prototype對(duì)象也會(huì)自動(dòng)獲得constructor屬性。

用對(duì)象字面量形式創(chuàng)建的對(duì)象,直接賦值給函數(shù)的原型對(duì)象(Person.prototype),本質(zhì)上完全重寫(xiě)了其prototype對(duì)象,

因此constructor屬性也就變成了新對(duì)象的constructor屬性(指向Object構(gòu)造函數(shù)),不再指向Person函數(shù)。

此時(shí)instanceof操作符可以返回正確結(jié)果,但通過(guò)constructor已經(jīng)無(wú)法確定對(duì)象類型了。

function Person(){}
Person.prototype = {
    // construtor : Person, // 需要重新指設(shè)constructor屬性
    name : "Tom",
    age : 24,
    sayName : function(){
        console.log(this.name);
    }
}

var p = new Person(); 
console.log(p instanceof Object); // ture
console.log(p instanceof Person); // ture
console.log(p.construtor == Object); // ture
console.log(p.construtor == Person); // false
安全地重設(shè)constructor
以上述方式重設(shè)constructor屬性會(huì)導(dǎo)致它的[[Enumerable]]特性被設(shè)置為true;
默認(rèn)情況下,原生的constructor屬性是不可枚舉的;
因此可利用Object.defineProperty()重設(shè);
Object.defineProperty(Person.prototype, "constructor", {
    enumerable : false,
    value : Person
});
組合模式(構(gòu)造函數(shù)模式和原型模式)(★★★★)

定義

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

構(gòu)造函數(shù)模式用于定義實(shí)例屬性,原型模式用于定義方法和共享的屬性;

優(yōu)點(diǎn):

每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,同時(shí)又共享著對(duì)方方法的引用,最大限度節(jié)省了內(nèi)存;

這種混成模式支持向構(gòu)造函數(shù)傳遞參數(shù);

目前使用最廣泛、認(rèn)同度最高的一種自定義類型的方法,可以說(shuō)是用來(lái)定義引用類型的一種默認(rèn)模式

// 實(shí)例屬性均在構(gòu)造函數(shù)中定義
function Person(name, age){
    this.name = name;
    this.age = age;
    this.friends = ["Nicholas", "Jim"];
}
// 由所有實(shí)例共享屬性constructor和方法則是在原型中定義的
Person.prototype = {
    construtor: Person,
    sayName: function(){
        console.log(this.name);
    }
}

var p1 = new Person("Tom", 25);
var p2 = new Person("Greg", 26);
p1.friends.push("Tony");
console.log(p1.friends); // ["Nicholas", "Jim", "Tony"]
console.log(p2.friends); // ["Nicholas", "Jim"]
console.log(p1.friends === p2.friends); // false
console.log(p1.sayName === p2.sayName); // true
動(dòng)態(tài)原型模式(★★★★★)

定義

動(dòng)態(tài)原型模式把所有信息都封裝在了構(gòu)造函數(shù)中;

通過(guò)在構(gòu)造函數(shù)中初始化原型(僅在必要的情況下,比如第一次新建實(shí)例時(shí));

通過(guò)檢查某個(gè)應(yīng)該存在(原型中)的方法是否有效,來(lái)決定是否需要初始化原型;

優(yōu)點(diǎn):保持了同時(shí)使用構(gòu)造函數(shù)和原型的特點(diǎn);

注意點(diǎn):

下段代碼中只會(huì)在初次調(diào)用構(gòu)造函數(shù)時(shí)才會(huì)執(zhí)行,此后原型已經(jīng)完成初始化,無(wú)需再做修改;

這里對(duì)原型所做對(duì)修改,能夠立即在所有實(shí)例中得到反映;

if語(yǔ)句檢查的可以是初始化之后應(yīng)該存在的任何屬性或方法,檢查其中一個(gè)即可;

function Person(name, age){
    // 屬性
    this.name = name;
    this.age = age;
    // 方法
    if(typeof this.sayName != "function"){
        Person.prototype.sayName = function(){
            console.log(this.name);
        }
    }
}
寄生構(gòu)造函數(shù)模式(★★)

【定義】: 基本思想是創(chuàng)建一個(gè)函數(shù),該函數(shù)的作用僅僅是封裝創(chuàng)建對(duì)象的代碼,然后再返回新創(chuàng)建的對(duì)象

【特點(diǎn)】

返回的對(duì)象與構(gòu)造函數(shù)或者與構(gòu)造函數(shù)的原型屬性之間沒(méi)有關(guān)系;

寄生構(gòu)造函數(shù)返回的對(duì)象與在寄生構(gòu)造函數(shù)外部創(chuàng)建的對(duì)象沒(méi)有什么不同;

不能依賴instanceof操作符來(lái)確定對(duì)象類型;

與工廠模式的比較

除了使用new操作符并把使用的包裝函數(shù)叫做構(gòu)造函數(shù)之外,該模式和工廠模式其實(shí)是一模一樣的;

與構(gòu)造函數(shù)模式的比較

從表面上看,很像典型的構(gòu)造函數(shù);

構(gòu)造函數(shù)在不返回值的情況下,默認(rèn)會(huì)返回新對(duì)象實(shí)例

寄生構(gòu)造函數(shù)通過(guò)在構(gòu)造函數(shù)的末尾加一個(gè)return語(yǔ)句,重寫(xiě)了調(diào)用構(gòu)造函數(shù)時(shí)返回的值

此時(shí)返回的對(duì)象的__proto__屬性指向Object;

function Person(name, age){
    // 創(chuàng)建臨時(shí)新對(duì)象
    var o = new Object();
    // 初始化該對(duì)象
    o.name = name;
    o.age = age;
    o.sayName = function(){
        console.log(this.name);
    }
    // 返回該臨時(shí)新對(duì)象
    return o;
}

var p1 = new Person("Tom", 25);
var p2 = new Person("Greg",30);
console.log(p1 instanceof Object); // true
console.log(p1 instanceof Person); // false
console.log(p1.sayName == p2.sayName); // false
console.log(p1.constructor == Object); //true
穩(wěn)妥構(gòu)造函數(shù)模式(★★)
所謂穩(wěn)妥對(duì)象,就是指沒(méi)有公共屬性,而且其方法也不引用this的對(duì)象。
穩(wěn)妥對(duì)象最適合在一些安全的環(huán)境中(這些環(huán)境會(huì)禁用thisnew),或者防止數(shù)據(jù)被其他應(yīng)用程序改動(dòng)時(shí)調(diào)用。
與寄生構(gòu)造函數(shù)模式的比較

與寄生構(gòu)造函數(shù)類似,但又不同:

一是新創(chuàng)建的對(duì)象實(shí)例方法不引用this;

二是不使用new操作符調(diào)用構(gòu)造函數(shù);

function Person (name, age){
    var o = new Object();
    // 可定義私有變量和函數(shù)
    // ...
    
    // 新創(chuàng)建的對(duì)象實(shí)例方法未引用this;
    o.sayName = function(){
        console.log(name)
    }
    return o;
}

var p = Person("Tom", 23);
p.sayName(); // "Tom"
console.log(p instanceof Person); // false

除了sayName()方法外,沒(méi)有別的方法可以訪問(wèn)其數(shù)據(jù)成員;

即使有其他代碼給這個(gè)對(duì)象添加方法或數(shù)據(jù)成員,也不可能有別的辦法訪問(wèn)傳入到構(gòu)造函數(shù)中的原始數(shù)據(jù)

與寄生構(gòu)造函數(shù)模式類似,使用穩(wěn)妥構(gòu)造函數(shù)模式創(chuàng)建的對(duì)象與構(gòu)造函數(shù)之間也沒(méi)有關(guān)系(故instanceof操作符對(duì)這種對(duì)象也無(wú)意義);

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

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

相關(guān)文章

  • 讀書(shū)筆記】JavaScriptの類型

    摘要:函數(shù)類型檢測(cè)是的子類型,其屬性為參數(shù)個(gè)數(shù),但是判斷結(jié)果有內(nèi)建函數(shù)原生函數(shù)常見(jiàn)的有,可能被當(dāng)作構(gòu)造函數(shù)來(lái)使用,創(chuàng)建出來(lái)的是封裝了的基本類型值。構(gòu)造函數(shù)可以不帶關(guān)鍵字。建議使用和來(lái)進(jìn)行顯示強(qiáng)制轉(zhuǎn)換。 前言 此篇小結(jié)來(lái)源與《你不知道的JavaScript》和《JavaScript高級(jí)程序設(shè)計(jì)》的結(jié)合??或許是的,龜速總結(jié)中... 七種內(nèi)置類型 null undefined boolean ...

    cjie 評(píng)論0 收藏0
  • 前端最實(shí)用書(shū)簽(持續(xù)更新)

    摘要:前言一直混跡社區(qū)突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來(lái)有點(diǎn)混亂所以將前端主流技術(shù)做了一個(gè)書(shū)簽整理不求最多最全但求最實(shí)用。 前言 一直混跡社區(qū),突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來(lái)有點(diǎn)混亂; 所以將前端主流技術(shù)做了一個(gè)書(shū)簽整理,不求最多最全,但求最實(shí)用。 書(shū)簽源碼 書(shū)簽導(dǎo)入瀏覽器效果截圖showImg(https://segmentfault.com/img/bVbg41b?w=107...

    sshe 評(píng)論0 收藏0
  • 《javascript高級(jí)程序設(shè)計(jì)》第六章 讀書(shū)筆記 之 javascript繼承的6種方法

    摘要:繼承的是超類型中構(gòu)造函數(shù)中的屬性,如上繼承了屬性,但沒(méi)有繼承原型中的方法。上述造成的結(jié)果是子類型實(shí)例中有兩組超類型的構(gòu)造函數(shù)中定義的屬性,一組在子類型的實(shí)例中,一組在子類型實(shí)例的原型中。 ECMAScript只支持實(shí)現(xiàn)繼承,主要依靠原型鏈來(lái)實(shí)現(xiàn)。與實(shí)現(xiàn)繼承對(duì)應(yīng)的是接口繼承,由于script中函數(shù)沒(méi)有簽名,所以無(wú)法實(shí)現(xiàn)接口繼承。 一、原型鏈 基本思想:利用原型讓一個(gè)引用類型繼承另一個(gè)引用...

    孫吉亮 評(píng)論0 收藏0
  • Javascript 設(shè)計(jì)模式讀書(shū)筆記(二)——封裝,簡(jiǎn)單的創(chuàng)建對(duì)象模式

    摘要:創(chuàng)建對(duì)象中,創(chuàng)建對(duì)象的基本模式有三種。因此,在設(shè)計(jì)構(gòu)造函數(shù)時(shí),需要進(jìn)行慎重考慮。因此在中,這種問(wèn)題被稱作繼承破壞封裝。靜態(tài)成員每個(gè)只有一份,直接通過(guò)類對(duì)象進(jìn)行訪問(wèn)。 什么是封裝 找工作時(shí)一些公司給了offer后我就想知道真正拿到手的是多少,畢竟賦稅繁重。但各種稅也好,五險(xiǎn)一金也好我實(shí)在是弄不清楚,于是我就會(huì)在網(wǎng)上的一些稅后收入計(jì)算器上進(jìn)行計(jì)算,只需要填寫(xiě)一些基本信息,比如稅前收入,所...

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

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

0條評(píng)論

Dogee

|高級(jí)講師

TA的文章

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