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

資訊專欄INFORMATION COLUMN

JavaScript基礎(chǔ)---面向?qū)ο?

jsummer / 1880人閱讀

摘要:子類型最終回報(bào)寒潮類型對(duì)象的全部實(shí)例屬性,但是我們不得不在調(diào)用子類型構(gòu)造函數(shù)時(shí)重寫這些屬性處理引用類型共用問題組合式繼承代碼如下第二次調(diào)用第一次調(diào)用寄生組合式繼承代碼如下

面向?qū)ο笳Z(yǔ)言都有類的概念,但是ECMAScript沒有類的概念,所以它的對(duì)象與基于類的語(yǔ)言中的對(duì)象有所不同。

一、創(chuàng)建對(duì)象的幾種方式及對(duì)比 1.對(duì)象字面量與創(chuàng)建Object實(shí)例方式
var person = {
    name:"Zhangsan",
    age:20,
    gender: "male",
    sayName: function(){
        console.log(this.name);
    }
}
var person = new Object();
person.name = "Zhangsan";
person.age = 20;
person.gender = "male";
person.sayName = function(){
    console.log(this.name);
}

缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對(duì)象,會(huì)產(chǎn)生大量的重復(fù)代碼

2.工廠模式

因?yàn)镋CMAScript沒有類的概念,所以用函數(shù)來(lái)封裝創(chuàng)建對(duì)象的細(xì)節(jié)

function createPerson(name,age,gender){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.gender = gender;
    o.sayName = function(){
        console.log(this.name);
    }
    return o;
}
var person1 = createPerson("Zhangsan",20,"male");
var person2 = createPerson("Lisi",24,"male");
console.log(person1 instanceof Object); //true

缺點(diǎn):工廠模式解決了創(chuàng)建多個(gè)相似對(duì)象的重復(fù)代碼問題,但沒有解決對(duì)象類型識(shí)別的問題

3.構(gòu)造函數(shù)模式
function Person(name, age, gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.sayName = function(){
        console.log(this.name);
    }
}
var person1 = new Person("Zhangsan",20,"male");
var person2 = new Person("Lisi",24,"male");
console.log(person1 instanceof Person); //true
console.log(person1 instanceof Object); //true
console.log(person1.constructor == Person); //true
console.log(person1.sayName == person2.sayName); //false

以這種方式調(diào)用構(gòu)造函數(shù)會(huì)經(jīng)歷以下四步:

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

將構(gòu)造函數(shù)的作用域賦給新對(duì)象

執(zhí)行構(gòu)造函數(shù)中的代碼

返回新對(duì)象

任何函數(shù),只要通過new操作符來(lái)調(diào)用,那它就可以作為構(gòu)造函數(shù);如果不通過new操作符來(lái)調(diào)用,那它就是普通函數(shù)

var person = new Person("Zhangsan",20,"male");
person.sayName(); //"Zhangsan"

Person("Lisi",24,"male");
window.sayName(); //"Lisi"

var o = new Object();
Person.call(o,"Wangwu",22,"female");
o.sayName(); //"Wangwu"

缺點(diǎn):每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍,上述例子中的sayName方法就會(huì)在每個(gè)實(shí)例中重新創(chuàng)建一遍

function Person(name, age, gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.sayName = sayName;
}
function sayName(){
    console.log(this.name);
}
var person1 = new Person("Zhangsan",20,"male");
var person2 = new Person("Lisi",24,"male");

上述代碼將sayName()函數(shù)的定義轉(zhuǎn)移到構(gòu)造函數(shù)外部,這樣構(gòu)造函數(shù)中的的sayName是一個(gè)指向函數(shù)的指針,因此person1、person2就共享了在全局作用域定義的同一個(gè)sayName()函數(shù)。這么做雖然解決了問題但卻帶來(lái)了新問題:如果對(duì)象需要定義很多方法那么就需要定義很多全局函數(shù),那么自定義的引用類型就絲毫沒有封裝性可言了

4.原型模式 4.1原型對(duì)象

每個(gè)函數(shù)都有一個(gè)prototype屬性,這個(gè)屬性是一個(gè)指針指向一個(gè)對(duì)象,而這個(gè)對(duì)象包含可以由特定類型的所有實(shí)例共享的屬性和方法。使用原型對(duì)象的好處就是讓所有對(duì)象實(shí)例共享它所包含的屬性和方法

function Person(){

}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.gender = "male";
Person.prototype.sayName = function(){
    console.log(this.name);
};
var person1 = new Person();
person1.sayName(); //Nicholas
var person2 = new Person();
person2.sayName(); //Nicholas
console.log(Person.prototype.isPrototypeOf(person1));//true
console.log(Person.prototype.isPrototypeOf(person2));//true
console.log(Object.getPrototypeOf(person1) == Person.prototype);//true
console.log(Object.getPrototypeOf(person1).name);//Nicholas


當(dāng)代碼讀取某個(gè)對(duì)象的某個(gè)屬性時(shí),先從對(duì)象實(shí)例本身開始搜索,如果找到給定名稱的屬性則返回該屬性的值;如果沒找到則搜索其指針指向的原型。當(dāng)為對(duì)象實(shí)例添加一個(gè)屬性時(shí),則這個(gè)屬性就會(huì)屏蔽原型對(duì)象中保存的同名屬性

person1.name = "Zhangsan";
console.log(person1.name); //Zhangsan
console.log(person1.hasOwnProperty("name")); //true
console.log(person2.hasOwnProperty("name")); //false
delete person1.name;
console.log(person1.name); //Nicholas
4.2原型對(duì)象賦值
function Person(){

}
Person.prototype = {
    name:"Nicholas",
    age:29,
    gender:"male",
    sayName:function(){
        console.log(this.name);
    }
}
var person = new Person();
console.log(person instanceof Object); //true
console.log(person instanceof Person); //true
console.log(person.constructor == Person); //false
console.log(person.constructor == Object); //true
Person.prototype.constructor = Person;
console.log(person.constructor == Person); //true

使用原型對(duì)象賦值操作是會(huì)覆蓋原型對(duì)象中的constructor屬性,就會(huì)切斷原型與構(gòu)造函數(shù)之間的關(guān)聯(lián)

function Person(){

}
var person = new Person();
Person.prototype = {
    name:"Nicholas",
    age:29,
    gender:"male",
    sayName:function(){
        console.log(this.name);
    }
}
person.sayName(); //error


缺點(diǎn):由于原型中的所有屬性和方法都是共享的,所以對(duì)于引用類型屬性問題就比較突出

function Person(){

}
Person.prototype = {
    constructor:Person,
    name:"Nicholas",
    age:29,
    gender:"male",
    love:["swimming","running"],
    sayName:function(){
        console.log(this.name);
    }
}
var person1 = new Person();
var person2 = new Person();
person1.love.push("playing games"); 
console.log(person1.love); //["swimming", "running", "playing games"]
console.log(person2.love); //["swimming", "running", "playing games"]
console.log(person1.love == person2.love); //true
5.組合使用構(gòu)造函數(shù)和原型模式
function Person(name,age,gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.love = ["swimming","running"];
}
Person.prototype = {
    constructor:Person,
    sayName:function(){
        console.log(this.name);
    }
}
var person1 = new Person("Zhangsan",20,"male");
var person2 = new Person("Lisi",24,"male");
person1.love.push("playing games"); 
console.log(person1.love); //["swimming", "running", "playing games"]
console.log(person2.love); //["swimming", "running"]
console.log(person1.love == person2.love); //false

這種模式是使用最廣泛、認(rèn)同度最高的一種創(chuàng)建自定義類型的方法

6.寄生構(gòu)造函數(shù)模式
function SpecialArray(name,age,gender){
    var array = new Array();
    array.push.apply(array,arguments);
    array.toPipedString = function(){
        return this.join("|");
    }
    return array;
}

這種模式可以用來(lái)為原生引用類型做擴(kuò)展,寄生構(gòu)造函數(shù)模式返回的對(duì)象與構(gòu)造函數(shù)或者與構(gòu)造函數(shù)原型之間沒有關(guān)系,因此不能依賴instanceof操作符來(lái)確定對(duì)象類型

二、繼承 1.原型鏈
function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function (){
    return this.property;
}

function SubType(){
    this.subproperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
    return this.subproperty;
}
var instance = new SubType();
console.log(instance.getSuperValue()); //true


原型鏈雖然很強(qiáng)大,可以用它來(lái)實(shí)現(xiàn)繼承,但它也存在一些問題,其中,最主要的問題來(lái)自包含引用類型值的原型;第二個(gè)問題是創(chuàng)建子類型的實(shí)例時(shí)不能向超類的構(gòu)造函數(shù)中傳遞參數(shù)。

function SuperType(){
    this.colors = ["red","yellow","blue"];
}
function SubType(){
    
}
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push("green");
console.log(instance1.colors); //["red", "yellow", "blue", "green"]
var instance2 = new SubType();
console.log(instance2.colors); //["red", "yellow", "blue", "green"]
2.借用構(gòu)造函數(shù)

借用構(gòu)造函數(shù)用于解決原型鏈中包含引用類型值所帶來(lái)的問題

function SuperType(){
    this.colors = ["red","yellow","blue"];
}
function SubType(){
    SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("green");
console.log(instance1.colors); //["red", "yellow", "blue", "green"]
var instance2 = new SubType();
console.log(instance2.colors); //["red", "yellow", "blue"]

問題:方法都在構(gòu)造函數(shù)中定義,因此函數(shù)復(fù)用無(wú)從談起,而且在超類原型中定義的方法對(duì)子類而言也是不可見的,結(jié)果所有類型都只能使用構(gòu)造函數(shù)模式

3.組合繼承
function SuperType(name){
    this.name = name;
    this.colors = ["red", "yellow", "blue"];
}
SuperType.prototype.sayName = function(){
    console.log(this.name);
}

function SubType(name, age){
    SuperType.call(this,name);
    this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    console.log(this.age);
}

var instance1 = new SubType("Zhangsan",20);
instance1.colors.push("green");
console.log(instance1.colors); //["red", "yellow", "blue", "green"]
instance1.sayName(); //Zhangsan
instance1.sayAge(); //20

var instance2 = new SubType("Lisi", 24);
console.log(instance2.colors); //["red", "yellow", "blue"]
instance2.sayName(); //Lisi
instance2.sayAge(); //24

組合繼承避免了原型鏈和借用構(gòu)造函數(shù)的缺陷,融合了他們的優(yōu)點(diǎn),成為JavaScript中最常用的繼承模式

4.原型式繼承
var person = {
    name : "Zhangsan",
    colors : ["red", "yellow", "blue"]
}
var anotherPerson = Object.create(person);
anotherPerson.name = "Lisi";
anotherPerson.colors.push("green");

var otherPerson = Object.create(person);
otherPerson.name = "Wangwu";
otherPerson.colors.push("black");

console.log(person.colors); //["red", "yellow", "blue", "green", "black"]
console.log(person.name); //Zhangsan

這種繼承方式在想讓一個(gè)對(duì)象與另一個(gè)對(duì)象保持類似的情況下是完全可以勝任的

5.寄生式繼承
var person = {
    name : "Zhangsan",
    colors : ["red", "yellow", "blue"]
}
var anotherPerson = Object.create(person);
anotherPerson.sayHi = function(){
    console.log("hi");
}
anotherPerson.sayHi();

使用寄生式繼承不能做到函數(shù)復(fù)用而降低效率

6.寄生組合式繼承

組合繼承最大的問題就在于無(wú)論什么情況下都會(huì)調(diào)用兩次超類型構(gòu)造函數(shù):一次是在創(chuàng)建子類型原型的時(shí)候,另一次是在子類型構(gòu)造函數(shù)內(nèi)部。子類型最終回報(bào)寒潮類型對(duì)象的全部實(shí)例屬性,但是我們不得不在調(diào)用子類型構(gòu)造函數(shù)時(shí)重寫這些屬性(處理引用類型共用問題)
組合式繼承代碼如下:

function SuperType(name){
    this.name = name;
    this.colors = ["red", "yellow", "blue"];
}
SuperType.prototype.sayName = function(){
    console.log(this.name);
}

function SubType(name, age){
    SuperType.call(this,name); //第二次調(diào)用
    this.age = age;
}
SubType.prototype = new SuperType(); //第一次調(diào)用
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    console.log(this.age);
}

寄生組合式繼承代碼如下:

function SuperType(name){
    this.name = name;
    this.colors = ["red", "yellow", "blue"];
}
SuperType.prototype.sayName = function(){
    console.log(this.name);
}

function SubType(name, age){
    SuperType.call(this,name); 
    this.age = age;
}
SubType.prototype = Object.create(SuperType.prototype);
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    console.log(this.age);
}

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

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

相關(guān)文章

  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    李昌杰 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    Lyux 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    AaronYuan 評(píng)論0 收藏0
  • 2017年 最好的javascript 書籍

    摘要:請(qǐng)記住,這些書中的一些可能不是最新的,但概念和基礎(chǔ)仍應(yīng)適用。是最好的老師之一。的秘密由部分組成。在你完成這些書后,查看書籍和最好的本土?xí)? 我看過三本,第1本,第二本,第四本。第一本買的的實(shí)體書,其他兩本看的是電子書。第一本是大名鼎鼎老道寫的,書很薄,但是非常經(jīng)典。javascirpt忍者秘籍是jquery的作者寫的,也是非常經(jīng)典。you dont kown js系列也是非常好。看了...

    mingzhong 評(píng)論0 收藏0
  • 學(xué)Java編程需要注意的地方

    摘要:學(xué)編程真的不是一件容易的事不管你多喜歡或是多會(huì)編程,在學(xué)習(xí)和解決問題上總會(huì)碰到障礙。熟練掌握核心內(nèi)容,特別是和多線程初步具備面向?qū)ο笤O(shè)計(jì)和編程的能力掌握基本的優(yōu)化策略。   學(xué)Java編程真的不是一件容易的事,不管你多喜歡或是多會(huì)Java編程,在學(xué)習(xí)和解決問題上總會(huì)碰到障礙。工作的時(shí)間越久就越能明白這個(gè)道理。不過這倒是一個(gè)讓人進(jìn)步的機(jī)會(huì),因?yàn)槟阋恢辈粩嗟膶W(xué)習(xí)才能很好的解決你面前的難題...

    leanxi 評(píng)論0 收藏0
  • JavaScript編程全解 —— 基礎(chǔ)

    摘要:函數(shù)式編程最后介紹一下函數(shù)式編程。函數(shù)式編程是一種歷史悠久,而又在最近頗為熱門的話題。函數(shù)式編程在面向?qū)ο笠辉~誕生以前就已經(jīng)存在,不過它在很長(zhǎng)一段時(shí)間里都被隱藏于過程式編程面向?qū)ο笠彩沁^程式編程的一種的概念之下。 2.1 JavaScript特點(diǎn) 總結(jié)以下幾個(gè)特點(diǎn): 解釋型語(yǔ)言 類似與C和Java的語(yǔ)法結(jié)構(gòu) 動(dòng)態(tài)語(yǔ)言 基于原型的面向?qū)ο?字面量的表現(xiàn)能力 函數(shù)式編程 解釋型語(yǔ)言:...

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

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

0條評(píng)論

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