一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

簡單的this,麻煩的this

 heii2 2018-09-01

作者:  劉欣 


周末的Hello World咖啡館總是熱鬧非凡。 


Java, Python, Ruby, JavaScript圍坐在一起,一邊喝咖啡,一邊海闊天空。   


C老頭兒則待在一旁,冷眼旁觀。 


聊著聊著,這話題不知怎么著轉(zhuǎn)移到了“this”上來了。 


Java 說: “唉!你們不知道吧,對于一個初學(xué)Java的人來說,this 是非常難于理解的。”  


Python說:“this 在你那里已經(jīng)夠簡單了啊。還難于理解?”


“我們都是支持面向?qū)ο缶幊痰?,在我這里,this 可以用到實例方法或者構(gòu)造器中,表示對當(dāng)前對象實例的引用?!? 

public class Point {
   private double x = 0.0;
   private double y = 0.0;
   public Point(int x, int y) {
       this.x = x;
       this.y = y;
   }

  public double distanceTo(Point that) {
       double dx = this.x - that.x;
       double dy = this.y - that.y;
       return Math.sqrt(dx*dx + dy*dy);
   }
}


“這不很容易理解嗎? ” Ruby 問道。  


“對于第一次接觸面向?qū)ο缶幊痰娜藖碚f,他分不清這個當(dāng)前對象this到底是哪個對象。”  Java說,“我必須得再寫一段代碼給他掰扯一下?!?/span>

Point p1 = new Point(1,1);
Point p2 = new Point(2,2);

// this 指向的是p1
p1.distanceTo(p2);  

// this 指向的是p2
p2.distanceTo(p1);


“對啊,this必須得有個上下文才能準(zhǔn)確理解。” Python說,“還有,你那個this吧,是個隱式的,像我是顯式的:”  

class Point:
   def __init__(this, x, y):
       this.x = x
       this.y = y
   def distanceTo(this,point):
       dx = this.x - point.x
       dy = this.y - point.y
       return math.sqrt(dx**2+dy**2)


Java 說:“你不是一直用self嗎,怎么現(xiàn)在是this?” 


Python笑道:“我這不是為了和你Java老弟保持一致嘛,反正只是個變量名,你想用this就用this,想用that就用that,只不過我們習(xí)慣于用self ?!? 


Ruby說: “Python兄,你把this放到方法中作為一個參數(shù),實在是太丑陋了,一點(diǎn)美感都沒有?!? 


“那是我們的哲學(xué),我們信奉 Explicit is better than implicit。”  


“可是在調(diào)用的時候,怎么不把一個對象傳給那個方法?你的self去哪里了?”

p1 = Point(1,1)
p2 = Point(2,2)

p1.distanceTo(p2)
p2.distanceTo(p1)


 “你怎么不寫成: distanceTo(p1,p2) ?” 


 “那不行,” Python說,“如果那樣的話我們就不是面向?qū)ο罅耍嫦蜻^程了。 ”


 “哼哼,” C老頭兒在一旁冷笑一聲,“說來說去,還不是披了一層面向?qū)ο蟮耐庖?,?nèi)部實現(xiàn)依然是面向過程的?!”  


“此話怎講?” Java一直以正統(tǒng)的面向?qū)ο笞跃?,不像Python, Ruby ,Java即使是想輸出一個Hello World也得定義一個類不可。


 “就說你吧,Java小子,你的Java 源文件被編譯以后變成了.class文件, 這個class文件被裝載到了Java虛擬機(jī)的一個區(qū)域,這個區(qū)域叫什么?” C 老頭兒出手不凡。 


 “當(dāng)然是Method Area, 方法區(qū)了,這我會不知道?!”


 “對啊,它為什么叫方法區(qū)? 為什么不叫Class Area, 類區(qū)?”  C 老頭兒真是別出心裁。  


“這…… ”  Java 語噻了,他從來就沒有想過這個問題。


 “你的方法區(qū)是被各個線程所共享的,存儲虛擬機(jī)加載類的信息,常量池,其中最主要的就是類中定義的方法相關(guān)的代碼。 而你創(chuàng)建的對象呢,卻是放在‘堆中’,虛擬機(jī)在執(zhí)行的時候,要從方法區(qū)找到‘方法’,這些方法的字節(jié)碼在運(yùn)行的過程中,會操作位于堆中的對象。 ” 



 “所以你看,你的數(shù)據(jù)和方法是分離的,一個地方是方法(所以叫方法區(qū)),一個地方是數(shù)據(jù),和我們C寫出的程序是一樣的,都是面向過程的!” C老頭兒經(jīng)過一系列證明后做了最終陳述。


Python也沉默了,他知道,自己在運(yùn)行時也和這種方式差不多。


過了一會兒,Java 醒悟了過來:“不對,老頭兒你這是混淆概念,我們是站在程序員的角度在談?wù)撜Z言是不是面向?qū)ο蟮?,而你則把我們拉到了實現(xiàn)層面,這是不對的?!? 


Python也附和道:“對對,我們是面向?qū)ο蟮恼Z言,抽象程度比你的面向過程要高!”


 “抽象? 哼哼,” C 老頭兒又冷笑一聲,“Linus 用C 寫了Linux,用C 寫了Git, 你覺得他沒有做抽象? 笑話! 依我看來,抽象就是要在變化的東西中找到不變的東西,和具體的編程語言關(guān)系不大啊?!?nbsp; C老頭說了一句至理名言。


Java 悄悄對Python說: “老頭兒主要做操作系統(tǒng)內(nèi)核,操作系統(tǒng)中的那些虛擬內(nèi)存,進(jìn)程,線程,文件系統(tǒng)概念都很清晰, 并且很穩(wěn)定,估計他沒有接觸到應(yīng)用層變態(tài)的,不講道理的業(yè)務(wù)邏輯。 ”  


C 老頭兒說:“別以為你們面向?qū)ο笥卸嗝戳瞬黄?,我告訴你,有很多程序員,用著面向?qū)ο蟮恼Z言,寫著面向過程的程序!關(guān)鍵是人!”  


Ruby 說:“兩位兄臺,算了,不和老頭兒爭論了,來看看我的this吧, 奧不, 是self, 我這里必須用self。 我的self 和你們的都不一樣,在不同的位置表示不同的含義。比如說:”

class Point

   # 此處的Self 就是Point這個類
   puts 'Self is :#{self}'

   # 定義一個Class級別(靜態(tài))的方法,self還是Point這個類
   def self.name
       puts 'Self inside class method is: #{self}'        
   end
   # 定義一個實例方法, 此處的self 就是對象實例了
   def name
       puts 'Self inside instance method is: #{self}'  
   end
end


Java 說:“你這搞得太麻煩了,定義一個靜態(tài)方法,用static 不就結(jié)了?”  


半天都沒有說話的JavaScript突然說道:“這也叫麻煩,來看看我是怎么處理this的!”

function add(y){
   return this.x + y
}


熟悉面向?qū)ο蟮腏ava, Python看到這么古怪的代碼,大為吃驚, 這是什么鬼? add函數(shù)中的這個this 到底指向誰? 


JavaScript說:“不要大驚小怪! 我的this和你們的this ,self都不一樣,它是動態(tài)的,在定義時確定不了到底指向誰,只有等到函數(shù)調(diào)用的時候才能確定,this 指向的是最終調(diào)用它的那個對象,比如:” 

function add(y){
   //此時的this 指向的是全局的對象,在瀏覽器運(yùn)行就是window
   return this.x + y
}

x = 10
console.log(add(20))


在這里調(diào)用add函數(shù)的是全局上下文, 所以this指向的是全局對象,輸出的值是30 。 


JavaScript說:“我還可以給add函數(shù)傳遞一個對象當(dāng)作this?!? 


function add(y){
   //此時的this 指向的是對象obj,this.x 是20 ,不是10
   return this.x + y
}

x = 10

var obj = {x: 20};
//傳遞一個對象給add函數(shù)
add.call(obj,20)  // 40


大家更加吃驚了。 


JavaScript又展示了一個例子: 

var obj = {
   x:100,
   print:function(){
      console.log(this.x);
   }    
}

obj.print() //100


Python說: “這個很容易理解,這個this應(yīng)該是指向obj這個對象實例, 所以print函數(shù)輸出的x是100,對吧?!?nbsp;


“對的,再來看一個:”


var obj = {
   x:100,
   y:{
       x : 200,
       print:function(){
           console.log(this.x);
       }
   }        
}
obj.y.print() //200


Java 說道:“按照你的規(guī)則,這個this 指向的應(yīng)該是最終調(diào)用它的對象,那就是y , 在y中,x是200,所以應(yīng)該輸出200 !” 


JavaScript說:“如果我把對象y中的x:200 給去掉,輸出是什么? ” 


“難道是100 ? 不, 它不會向上一級去找,只會在y中尋找x 的值,如果沒有,就是undefined, 唉!你這this規(guī)則實在是太麻煩?!?nbsp;


 JavaScript笑了笑:“再來看個更古怪的例子:”


var obj = {
   x:100,
   y:{
       x : 200,
       print:function(){
           console.log(this.x);
       }
   }        
}

var point ={x:15,y:15, f: obj.y.print}

point.f() //輸出什么?

var x = 10
g = obj.y.print
g()  //輸出什么?


Python說:“這不還是一樣嘛, 都應(yīng)該輸出200?!? 


JavaScript說: “不,point.f() 應(yīng)該輸出15, 注意此時f 是對象point的一個函數(shù),最終調(diào)用f 的是point對象,此時x = 15 了!   ”  


Java接口說:“我明白了,調(diào)用函數(shù)g()的是全局對象,x = 10 ,所以應(yīng)該輸出10 ?!?nbsp;


Python說:“你小子號稱前端之王,就這么用this來折磨程序員?”  


JavaScript笑道:“其實吧,普通程序員直接操作this的機(jī)會也不太多,都被框架、類庫封裝好了!”


這時候就聽到C老頭兒在那里搖頭晃腦: “簡單就是美,簡單就是美啊。你們這幫小子,把世界搞得這么復(fù)雜,讓程序員們學(xué)習(xí)這么多不必要的復(fù)雜性,真是浪費(fèi)生命啊?!? 


“浪費(fèi)生命? 沒有我們這些語言,怎么可能創(chuàng)建出這么多Web應(yīng)用程序出來? 你行嗎?” 


“我是不行,我只知道你Java 虛擬機(jī)是用我C語言寫的, 你Python解釋器,Ruby解釋器也是C語言寫的, 就連JS的V8引擎也是用我的兄弟C++語言寫的?!?nbsp;


C 老頭兒把手中的咖啡往桌子上狠狠一摔,轉(zhuǎn)身就離開了咖啡館。


(完)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    中文字幕熟女人妻视频| 黄色三级日本在线观看| 亚洲黄香蕉视频免费看| 激情综合五月开心久久| 久久国产成人精品国产成人亚洲| 国产精品一区二区三区激情| 亚洲综合香蕉在线视频| 国产亚洲欧美自拍中文自拍| 最新日韩精品一推荐日韩精品| 五月婷婷六月丁香亚洲| 亚洲欧美一二区日韩高清在线| 中文字幕日韩一区二区不卡| 欧美亚洲91在线视频| 日韩人妻一区二区欧美| 国产精品午夜福利在线观看| 高清一区二区三区大伊香蕉 | 人人妻人人澡人人夜夜| 99秋霞在线观看视频| 欧美日韩精品综合在线| 老司机精品在线你懂的| 国产视频福利一区二区| 日韩在线精品视频观看| 国产精品一区欧美二区| 欧美成人免费视频午夜色| 大香蕉大香蕉手机在线视频| 久久国产青偷人人妻潘金莲| 激情综合网俺也狠狠地| 视频一区二区 国产精品| 欧美精品久久一二三区| 果冻传媒精选麻豆白晶晶| 少妇激情在线免费观看| 欧美韩国日本精品在线| 国产欧美亚洲精品自拍| 日本成人三级在线播放| 欧美自拍偷自拍亚洲精品| 91久久精品国产一区蜜臀| 亚洲欧洲在线一区二区三区| 九九热精品视频在线观看| 日韩一区中文免费视频| 高跟丝袜av在线一区二区三区| 国产成人精品午夜福利|