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

資訊專欄INFORMATION COLUMN

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

SunZhaopeng / 737人閱讀

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

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

大家在日常的js開發(fā)中,會經(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)建了一個Cat類的對象cat。(注意下,雖然這邊我們?nèi)匀徽勵悾怯捎贘S是一門鴨子類型的語言,只要具備某個類一定的特性,比如某些方法、屬性,那么我們就認(rèn)為這個對象就是這個類的)
那么在cat對象的創(chuàng)建過程中,又發(fā)生了那些事情呢?創(chuàng)建一個對象,一般會經(jīng)歷如下幾個步驟:

創(chuàng)建一個空對象o

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

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

返回對象o

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

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

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

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

什么時候用prototype,什么時候用this

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

// 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

// 對象
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的方式進行相等的比較之外,其余的對象(不管是自定義的還是JS內(nèi)置的)在做比較的時候都是比較兩個對象的內(nèi)存地址,如果兩個對象的內(nèi)存地址不相等,則表示兩個對象就是不相等的。所以才會出現(xiàn)上面例子中的,即使連個對象中所有的屬性都相等,仍然會出現(xiàn)兩個對象不相當(dāng)?shù)那闆r。
ok回到正題上了,有了這邊等號比較的基礎(chǔ)之后,我們在來看看之前的問題,什么時候應(yīng)該使用prototype,什么時候應(yīng)該使用this。再來個?

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

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

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

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

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

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

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

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

JavaScript的繼承

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

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

講完原型鏈,我們就開始開始講講繼承。這邊的話,我看也有人說用屬性拷貝或者是方法借用這種方式來實現(xiàn)繼承,不過我不是非常認(rèn)可。這邊我主要用講原型來實現(xiàn)繼承。
用原型鏈實現(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;

但是如果這樣寫會有一個問題,就是我們在修改子類prototype的constructor的同時也修改了父類的prototype的constructor,這種情況是不允許的。那么解決的思路一般就是兩種,一個是通過new Parent()來解決,我們知道new Parent()的過程幫我們創(chuàng)造一個prototype指向Parent的prototype的對象(記作o,o.prototype=parent.prototype),這個時候,讓子類prototype指向o這個對象的時候,Child.prototype->o,o.prototype->Parent.prototype,這樣一個原型鏈就這么鏈接起來了,同時這個時候如果去修正Child.prototype.constructor為Child的時候,相當(dāng)于執(zhí)行o.constructor = Child,并不會對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;

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

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

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()的過程相對于new Parent()的過程更加輕量,更加節(jié)約內(nèi)存。

參考

Prototye inheritance

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

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

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

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

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

相關(guān)文章

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

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

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

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

    mylxsw 評論0 收藏0
  • js面向對象基礎(chǔ)

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

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

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

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

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

    fish 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<