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

資訊專欄INFORMATION COLUMN

js面向?qū)ο蠡A(chǔ)

SunZhaopeng / 742人閱讀

摘要:面向?qū)ο蠡A(chǔ)在的時(shí)候發(fā)生了什么大家在日常的開發(fā)中,會(huì)經(jīng)常見到類似于下面的代碼塊大黃黃色到這邊的話,我們就成功創(chuàng)建了一個(gè)類的對(duì)象。參考面向?qū)ο缶幊桃环庋b面向?qū)ο缶幊潭庋b面向?qū)ο缶幊倘菢?gòu)造函數(shù)的繼承

js面向?qū)ο蠡A(chǔ) javascriptnew xxx的時(shí)候發(fā)生了什么?

大家在日常的js開發(fā)中,會(huì)經(jīng)常見到類似于下面的代碼塊:

function Cat(name,color){
    this.name = name;
    this.color = color;
}
Cat.prototype.sayName = function(){
    console.log("this cat name is:"+this.name);
}
Cat.prototype.sayAge = function(){
    console.log("this cat age is:"+this.age);
}

var cat = new Cat("大黃","黃色");

到這邊的話,我們就成功創(chuàng)建了一個(gè)Cat類的對(duì)象cat。(注意下,雖然這邊我們?nèi)匀徽勵(lì)?,但是由于JS是一門鴨子類型的語言,只要具備某個(gè)類一定的特性,比如某些方法、屬性,那么我們就認(rèn)為這個(gè)對(duì)象就是這個(gè)類的)
那么在cat對(duì)象的創(chuàng)建過程中,又發(fā)生了那些事情呢?創(chuàng)建一個(gè)對(duì)象,一般會(huì)經(jīng)歷如下幾個(gè)步驟:

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

o的原型指向函數(shù)的原型

在新創(chuàng)建的對(duì)象o上執(zhí)行函數(shù),即function.apply(o,arguments)

返回對(duì)象o

經(jīng)過以上四個(gè)步驟我們就可以創(chuàng)實(shí)例化一個(gè)Cat類型的對(duì)象。

這里說個(gè)大家比較容易出錯(cuò)的地方,就是function優(yōu)惠返回值的情況。比如:

function F(name){
    this.name = name;
    return "F";
}

這邊如果執(zhí)行var f = new F("warjiang");jsnew F("warjiang")的時(shí)候回忽略F的返回值。f最后是一個(gè)對(duì)象,而不是"F".執(zhí)行結(jié)果如下:

什么時(shí)候用prototype,什么時(shí)候用this?

接著上面的例子,我們?cè)诙xCat類的時(shí)候,對(duì)于name,color這些屬性的定義是采用的this的方式。而對(duì)于sayName,sayAge的定義是采用的prototype的方式。那么什么時(shí)候該用this,什么時(shí)候該用prototype呢?在說這個(gè)問題之前,我想重新再提一下==,===。相信每個(gè)jser都應(yīng)該知道這個(gè)兩個(gè)等號(hào)與三個(gè)等號(hào)的區(qū)別,兩個(gè)等號(hào)只比較數(shù)值大小,不關(guān)心類型;三個(gè)等號(hào)不僅比較值大小,還要比較類型是否一致。下面我們先看個(gè)例子:

// number類型
var num1 = 22;
var num2 = 22;
console.log(num1 == num2);//true
console.log(num1 === num2);//true


// string類型
var str1 = "hello world";
var str2 = "hello world";
console.log(str1 == str2)//true
console.log(str1 === str2)//true

// 對(duì)象
var student1 = {
    name:"tony",
    age:22
};
var student2 = {
    name:"warjiang",
    age:22
}
console.log(student1 == student2);//false
console.log(student1 === student2);//false

// Date類型
var d1 = new Date("2017-3-15 10:23:00");
var d2 = new Date("2017-3-15 10:23:00");
console.log(d1 == d2);//false
console.log(d1 === d2);//false;

// 自定義類型
function Cat(name,color){
    this.name = name;
    this.color = color;
}
Cat.prototype.sayName = function(){
    console.log("my name is " + this.name);
}

var cat1 = new Cat("大黃","黃色");
var cat2 = new Cat("大黃","黃色");
console.log(cat1 == cat2);//false
console.log(cat1 === cat2);//false

通過上面的例子,我們可以總結(jié)出,在js中除了基本類型bool,string,number,undefined,null是按照value的方式進(jìn)行相等的比較之外,其余的對(duì)象(不管是自定義的還是JS內(nèi)置的)在做比較的時(shí)候都是比較兩個(gè)對(duì)象的內(nèi)存地址,如果兩個(gè)對(duì)象的內(nèi)存地址不相等,則表示兩個(gè)對(duì)象就是不相等的。所以才會(huì)出現(xiàn)上面例子中的,即使連個(gè)對(duì)象中所有的屬性都相等,仍然會(huì)出現(xiàn)兩個(gè)對(duì)象不相當(dāng)?shù)那闆r。
ok回到正題上了,有了這邊等號(hào)比較的基礎(chǔ)之后,我們?cè)趤砜纯粗暗膯栴},什么時(shí)候應(yīng)該使用prototype,什么時(shí)候應(yīng)該使用this。再來個(gè)?

function Cat(name,color){
    this.name = name;
    this.color = color;
    this.sayColor = function(){
        console.log(this.color);
    }
}
Cat.prototype.sayName = function(){
    console.log("my name is:"+this.name);
}

var cat1 = new Cat("大黃","黃色");
var cat2 = new Cat("大白","白色");
console.log(cat1.sayColor == cat2.sayColor);//false
console.log(cat1.sayName == cat2.sayName);//true

上面例子中兩個(gè)Cat類型的對(duì)象cat1,cat2在內(nèi)存中是什么情況呢。

通過上面的內(nèi)存圖,我們可以知道cat1sayColorcat2sayColor方法分別指向兩塊內(nèi)存地址,所以cat1.sayColor==cat2.sayColorfalse,而cat1.sayNamecat2.sayName都是來源于prototype對(duì)象上的sayName方法,他們的內(nèi)存地址其實(shí)是一個(gè),故而cat1.sayName == cat2.sayName方法為true。
通過上面的兩個(gè)例子,我們不難看出,如果我們使用this的話,則this上的屬性、方法都是屬于對(duì)象本身的,一般可以用于私有方法、屬性,而如果使用prototype的話,prototype上的屬性、方法在各個(gè)類對(duì)象上面共享,一般可以用于共有方法、屬性。

因此對(duì)于一些共有的方法、屬性,我們可以放在prototype上面,而對(duì)于一些私有的方法、屬性,我們可以放在prototype上
下面的話,我再補(bǔ)充一個(gè)額外的例子

function Cat(name,color){
    this.name = name;
    this.color = color;
}
Cat.prototype.type = "貓科動(dòng)物";
Cat.prototype.sayType = function(){
    console.log(this.type);
}
var cat1 = new Cat("大黃","黃色");
var cat2 = new Cat("大白","白色");

cat1.sayType();//貓科動(dòng)物
cat1.type = "狗科動(dòng)物";
cat2.sayType();//貓科動(dòng)物
cat1.sayType();//狗科動(dòng)物

這邊的話,可能有些同學(xué)會(huì)認(rèn)為cat1.type = "狗科動(dòng)物"這句話,修改的是prototype中的type,但是實(shí)際上cat1.type="狗科動(dòng)物",只是在cat1對(duì)象上面增加了一個(gè)type屬性,值為"狗科動(dòng)物",而原型上面的type并沒有收到影響。我們可以在控制臺(tái)中查看cat1與cat2的詳細(xì)如下:

如果想修改prototype中的type的話,可以把cat1.type修改為cat1.__proto__.type = "狗科動(dòng)物"(這邊也要注意下,__proto__并不是所有瀏覽器都支持);此時(shí)執(zhí)行結(jié)果就像大家想的那樣分別為貓科動(dòng)物,狗科動(dòng)物,狗科動(dòng)物。

JavaScript的繼承

談到j(luò)s的繼承,首先先了解下js中原型鏈。每個(gè)js對(duì)象都有一個(gè)prototype的屬性,這個(gè)屬性會(huì)指向一個(gè)新的對(duì)象,這個(gè)新的對(duì)象也會(huì)有一個(gè)prototype的屬性。這樣一直到Object.
這邊稍微提下,有些人可能會(huì)問瀏覽器中__proto__prototype的區(qū)別,可以理解為__proto__chrome、firefox這些瀏覽器對(duì)prototype的一種實(shí)現(xiàn)、表現(xiàn),東西還是一個(gè)東西。原型鏈我也舉個(gè)例子

var o = {
    name:"warjiang",
    age:24
}
var b = {
    name:"bb"
}
b.__proto__ = o;
console.log(b.name);//bb
console.log(b.age);//24
console.log(b.__proto__.name);//warjiang

講完原型鏈,我們就開始開始講講繼承。這邊的話,我看也有人說用屬性拷貝或者是方法借用這種方式來實(shí)現(xiàn)繼承,不過我不是非常認(rèn)可。這邊我主要用講原型來實(shí)現(xiàn)繼承。
用原型鏈實(shí)現(xiàn)繼承,就是讓子類的prototype指向父類的prototype,比如下面這樣:

function Parent(){
    this.type = "parent";
}
Parent.prototype.sayType = function(){
    console.log(this.type);
}

function Child(){
    
}
Child.prototype = Parent.prototype;
Child.prototype.constructor = Child;

但是如果這樣寫會(huì)有一個(gè)問題,就是我們?cè)谛薷淖宇恜rototype的constructor的同時(shí)也修改了父類的prototype的constructor,這種情況是不允許的。那么解決的思路一般就是兩種,一個(gè)是通過new Parent()來解決,我們知道new Parent()的過程幫我們創(chuàng)造一個(gè)prototype指向Parent的prototype的對(duì)象(記作o,o.prototype=parent.prototype),這個(gè)時(shí)候,讓子類prototype指向o這個(gè)對(duì)象的時(shí)候,Child.prototype->o,o.prototype->Parent.prototype,這樣一個(gè)原型鏈就這么鏈接起來了,同時(shí)這個(gè)時(shí)候如果去修正Child.prototype.constructor為Child的時(shí)候,相當(dāng)于執(zhí)行o.constructor = Child,并不會(huì)對(duì)Parent.prototype造成影響。這種做法的表現(xiàn)形式如下:

function Parent(){
    this.type = "parent";
}
Parent.prototype.sayType = function(){
    console.log(this.type);
}

function Child(){
    
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;

此時(shí)如果我們?nèi)ew Child()對(duì)象的時(shí)候,我們可以如下的繼承圖

分析Child.prototype=new Parent();這個(gè)過程我們會(huì)發(fā)現(xiàn),new Parent()其實(shí)對(duì)Parent的prototype起到保護(hù)的作用,因此我們完全可以通過一個(gè)空對(duì)象來完成這樣的功能,如下:

function Parent(){
    this.type = "parent";
}
Parent.prototype.sayType = function(){
    console.log(this.type);
}
var f = function(){}
f.prototype = Parent.prototype;
function Child(){
    
}
Child.prototype = new f();
Child.prototype.constructor = Child;

這么做的好處在于new f()的過程相對(duì)于new Parent()的過程更加輕量,更加節(jié)約內(nèi)存。

參考

Prototye inheritance

Javascript 面向?qū)ο缶幊蹋ㄒ唬悍庋b

Javascript 面向?qū)ο缶幊蹋ǘ悍庋b

Javascript面向?qū)ο缶幊蹋ㄈ悍菢?gòu)造函數(shù)的繼承

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

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

相關(guān)文章

  • 大前端2018現(xiàn)在上車還還得及么

    摘要:面向?qū)ο笕筇卣骼^承性多態(tài)性封裝性接口。第五階段封裝一個(gè)屬于自己的框架框架封裝基礎(chǔ)事件流冒泡捕獲事件對(duì)象事件框架選擇框架。核心模塊和對(duì)象全局對(duì)象,,,事件驅(qū)動(dòng),事件發(fā)射器加密解密,路徑操作,序列化和反序列化文件流操作服務(wù)端與客戶端。 第一階段: HTML+CSS:HTML進(jìn)階、CSS進(jìn)階、div+css布局、HTML+css整站開發(fā)、 JavaScript基礎(chǔ):Js基礎(chǔ)教程、js內(nèi)置對(duì)...

    stormgens 評(píng)論0 收藏0
  • 大前端2018現(xiàn)在上車還還得及么

    摘要:面向?qū)ο笕筇卣骼^承性多態(tài)性封裝性接口。第五階段封裝一個(gè)屬于自己的框架框架封裝基礎(chǔ)事件流冒泡捕獲事件對(duì)象事件框架選擇框架。核心模塊和對(duì)象全局對(duì)象,,,事件驅(qū)動(dòng),事件發(fā)射器加密解密,路徑操作,序列化和反序列化文件流操作服務(wù)端與客戶端。 第一階段: HTML+CSS:HTML進(jìn)階、CSS進(jìn)階、div+css布局、HTML+css整站開發(fā)、 JavaScript基礎(chǔ):Js基礎(chǔ)教程、js內(nèi)置對(duì)...

    mylxsw 評(píng)論0 收藏0
  • js面向對(duì)象基礎(chǔ)

    摘要:面向?qū)ο笕腴T基礎(chǔ)我們?cè)谌粘>幊讨?,用到的大多都是面向過程的編程,但是的編程我們要運(yùn)到面向?qū)ο?,?chuàng)建對(duì)象實(shí)例類,下邊說一下,我們創(chuàng)建對(duì)象的幾種方法我們創(chuàng)建對(duì)象有下邊幾種方法第一個(gè)方法第二種方法直接創(chuàng)建一個(gè)對(duì)象,字面量形式上邊的方法我們經(jīng)常用來 js面向?qū)ο笕腴T基礎(chǔ) 我們?cè)谌粘>幊讨?,用到的大多都是js面向過程的編程,但是20%的編程我們要運(yùn)到面向?qū)ο螅瑒?chuàng)建對(duì)象實(shí)例(類),下邊說一下,我們...

    WalkerXu 評(píng)論0 收藏0
  • JS基礎(chǔ)入門篇(三十四)— 面向對(duì)象(一)

    摘要:對(duì)象對(duì)象的定義對(duì)象是由鍵值對(duì)組成的無序集合。創(chuàng)建對(duì)象兩種方法方法一字面量方法方法二構(gòu)造函數(shù)創(chuàng)建面向?qū)ο蠛兔嫦蜻^程的比較如果想要把大象放進(jìn)冰箱。 1.對(duì)象 對(duì)象的定義 : 對(duì)象 是 由 鍵值對(duì) 組成的無序集合。 創(chuàng)建對(duì)象兩種方法 : 方法一 : 字面量方法 var obj = {name: k}; 方法二 : new Object( ) 構(gòu)造函數(shù)創(chuàng)建 var a = n...

    fantix 評(píng)論0 收藏0
  • JS基礎(chǔ)入門篇(三十四)— 面向對(duì)象(一)

    摘要:對(duì)象對(duì)象的定義對(duì)象是由鍵值對(duì)組成的無序集合。創(chuàng)建對(duì)象兩種方法方法一字面量方法方法二構(gòu)造函數(shù)創(chuàng)建面向?qū)ο蠛兔嫦蜻^程的比較如果想要把大象放進(jìn)冰箱。 1.對(duì)象 對(duì)象的定義 : 對(duì)象 是 由 鍵值對(duì) 組成的無序集合。 創(chuàng)建對(duì)象兩種方法 : 方法一 : 字面量方法 var obj = {name: k}; 方法二 : new Object( ) 構(gòu)造函數(shù)創(chuàng)建 var a = n...

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

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

0條評(píng)論

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