『壹』 javascript是基於對象的還是面向對象的
我忘了在哪裡看到過這樣一個比喻:
基於對象,就是一個工程師建了一棟房子,然後其它的工程師按照這個房子的樣子去建造其它的房子
面向對象,就是一個工程師再圖紙上設計出一棟房子的樣子,然後其它工程師按照這個圖紙的設計去建造房子
也就是說:
基於對象是先有一個具體的對象,然後在這個對象的基礎上創建新的對象
面向對象就是先有一個抽象的對象描述,然後以此為藍本構建具體對象
『貳』 js面向對象怎麼理解
首先你的理解面向過程:加入把一件東西放到一個箱子手棗晌里,面向過程岩漏就是第一部打開箱子,然後把東西放進去,然後關閉箱子:
面向對象:就是把箱子看成一個對象,這個對象有屬性比如說長寬高尺寸畢鋒這些,他還有一個功能就是裝東西.裝東西這個就I相當於一個函數
『叄』 JS 面向對象
為了能夠清楚的解釋這一切,我先從對象講起。從其他面向對象語言(如Java)而來的人可能認為在JS里的對象也是由類來實例化出來的,並且是由屬性和方法組成的。
實際上在JS里並不是如你所想(我開始是這么想的)那樣,對象或直接稱為object,實際上只是一些映射對的集合,像Map,字典等概念。JS里有大概7種類型(加上Symbol),數字、字元串、null、undefined、布爾、Symbol、對象。除對象以外的其他類型屬於原始類型,就是說它們比較單純,包含的東西比較少,基本上就是字面量所表示的那些(像C語言中的一些類型,就是占那麼多空間,沒有其他的東西)。object基本上是一些鍵值對的集合,屬於引用類型,即是有一個名字去指向它來供別人使用的,就好像比較重的東西你拿不動,而只是拿了張記錄東西所在地的紙條。所以當A對象里嵌套了B對象,僅表示A裡面有一個引用指向了B,並不是真正把B包含在A裡面,雖然看起來是這樣(尤其是從對象的字面量上來看),所以才會有所謂的深拷貝與淺拷貝。
有句話叫「JavaScript里一切皆對象」,是因為在很多情況下原始類型會被自動的轉為對象,而函數實際上也是對象,這樣這句話看起來就很有道理了。
說明對象的本質是為了正確地認識對象,因為這關繫到後面的理解。
『肆』 如何理解Javascript中類和對象這兩個概念
在說這個話題之前,我想先說幾句題外話:最近偶然碰到有朋友問我「hoisting」的問題。即在js里所有變數的聲明都是置頂的,而賦值則是在之後發生的。可以看看這個例子:
var a = 'global';
(function () {
alert(a);
var a = 'local';
})();
大家第一眼看到這個例子覺得輸出結果是什麼?『global』?還是『local』?其實都不是,輸出的是undefined,不用迷惑,我的題外話就是為了講這個東西的。
其實很簡單,看一看JavaScript運行機制就會明白。我們可以把這種現象看做「預聲明」。但是如果稍微深究一下,會明白得更透徹。
這里其實涉及到對象屬性綁定機制。因為所有JavaScript函數都是一個對象。在函數里聲明的變數可以看做這個對象的「類似屬性」。對象屬性的綁定在語言里是有分「早綁定」和「晚綁定」之分的。
【早綁定】
是指在實例化對象之前定義其屬性和方法。解析程序時可以提前轉換為機器代碼。通常的強類型語言如C++,java等,都是早綁定機制的。而JavaScript不是強類型語言。它使用的是「晚綁定」機制。
【晚綁定】
是指在程序運行前,無需檢查對象類型,只要檢查對象是否支持特性和方法即可。可以在綁定前對對象執行大量操作而不受任何懲罰。
上面代碼出現的「預聲明」現象,我們大可用「晚綁定」機制來解釋。在函數的作用域中,所有變數都是「晚綁定」的。 即聲明是頂級的。所以上面的代碼和下面的一致:
var a = 'global';
(function () {
var a;
alert(a);
a = 'local';
})();
在alert(a)之前只對a作了聲明而沒有賦值。所以結果可想而知。
<!-- 題外話到此結束 -->
RT:本文要說的是,在JavaScript里,我所知道的幾種定義類和對象的方式:<! -- 聲明:以下內容大部分來自《JavaScript高級程序設計》,只是個人敘述方式不同而已 -- >
【直接量方式】
使用直接量構建對象是最基礎的方式,但也有很多弊端。
var Obj = new Object;
Obj.name = 'sun';
Obj.showName = function() {
alert('this.name');
}
我們構建了一個對象Obj,它有一個屬性name,一個方法showName。但是如果我們要再構建一個類似的對象呢?難道還要再重復一遍?
NO!,我們可以用一個返回特定類型對象的工廠函數來實現。就像工廠一樣,流水線的輸出我們要的特定類型結果。
【工廠方式】
function createObj(name) {
var tempObj = new Object;
tempObj.name = name;
tempObj.showName = function () {
alert(this.name);
};
return tempObj;
}
var obj1 = createObj('obj_one');
var obj2 = createObj('obj_two');
這種工廠函數很多人是不把他當做構建對象的一種形式的。一部分原因是語義:即它並不像使用了運算符new來構建的那麼正規。還有一個更大的原因,是因為這個工廠每次產出一個對象都會創建一個新函數showName(),即每個對象擁有不同的版本,但實際上他們共享的是同一個函數。
有些人把showName在工廠函數外定義,然後通過屬性指向該方法,可以避開這個問題:
代碼
可惜的是,這種方式讓showName()這個函數看起來不像對象的一個方法。
【構造函數方式】
這種方式是為了解決上面工廠函數的第一個問題,即沒有new運算符的問題。可是第二個問題它依然不能解決。我們來看看。
function Obj(name) {
this.name = name;
this.showName = function () {
alert(this.name);
}
}
var obj1 = new Obj('obj_one');
var obj2 = new Obj('obj_two');
它的好處是不用在構造函數內新建一個對象了,因為new運算符執行的時候會自動創建一個對象,並且只有通過this才能訪問這個對象。所以我們可以直接通過this來對這個對象進行賦值。而且不用再return,因為this指向默認為構造函數的返回值。
同時,用了new關鍵字來創建我們想要的對象是不是感覺更「正式」了。
可惜,它仍然不能解決會重復生成方法函數的問題,這個情況和工廠函數一樣。
【原型方式】
這種方式對比以上方式,有個很大的優勢,就是它解決了方法函數會被生成多次的問題。它利用了對象的prototype屬性。我們依賴原型可以重寫對象實例。
var Obj = function () {}
Obj.prototype.name = 'me';
Obj.prototype.showName = function () {
alert(this.name);
}
var obj1 = new Obj();
var obj2 = new Obj();
我們依賴原型對構造函數進行重寫,無論是屬性還是方法都是通過原型引用的方式給新建的對象,因此都只會被創建一次。可惜的是,這種方式存在兩個致命的問題:
1。沒辦法在構建對象的時候就寫入想要的屬性,因為原型在構造函數作用域外邊,沒辦法通過傳遞參數的方式在對象創建的時候就寫入屬性值。只能在對象創建完畢後對值進行重寫。
2。致命問題在於當屬性指向對象時,這個對象會被多個實例所共享。考慮下面的代碼:
var Obj = function () {}
Obj.prototype.name = 'me';
Obj.prototype.flag = new Array('A', 'B');
Obj.prototype.showName = function () {
alert(this.name);
}
var obj1 = new Obj();
var obj2 = new Obj();
obj1.flag.push('C');
alert(obj1.flag); // A,B,C
alert(obj2.flag); //A,B,C
是的,當flag屬性指向對象時,那麼實例obj1和obj2都共享它,哪怕我們僅僅改變了obj1的flag屬性,但是它的改變在實例obj2中任然可見。
面對這個問題,讓我們不得不想是否應該把【構造函數方式】和【原型方式】結合起來,讓他們互補。。。
【構造函數和原型混合方式】
我們讓屬性用構造函數方式創建,方法用原型方式創建即可:
var Obj = function (name) {
this.name = name;
this.flag = new Array('A', 'B');
}
Obj.prototype = {
showName : function () {
alert(this.name);
}
}
var obj1 = new Obj();
var obj2 = new Obj();
obj1.flag.push('C');
alert(obj1.flag); // A,B,C
alert(obj2.flag); //A,B
這種方式有效地結合了原型和構造函數的優勢,是目前用的最多,也是副作用最少的方式。
不過,有些追求完美的傢伙還不滿足,因為在視覺上還沒達到他們的要求,因為通過原型來創建方法的過程在視覺上還是會讓人覺得它不太像實例的方法(尤其對於傳統OOP語言的開發者來說。)
所以,我們可以讓原型活動起來,讓他也加入到構造函數裡面去,好讓這個構造函數在視覺上更為統一。而這一系列的過程只需用一個判斷即可完成。
var Obj = function (name) {
this.name = name;
this.flag = new Array('A', 'B');
if (typeof Obj._init == 'undefined') {
Obj.prototype = {
showName : function () {
alert(this.name);
}
};
Obj._init = true;
}
}
如上,用_init作為一個標志來判斷是否已經給原型創建了方法。如果是那麼就不再執行。這樣其實在本質上是沒有任何變化的,方法仍是通過原型創建,唯一的區別在於這個構造函數看起來「江山統一」了。
但是這種動態原型的方式是有問題的,《JavaScript高級程序設計》里並沒有深究。創建第一個對象的時候會因為prototype在對象實例化之前沒來的及建起來,是根本無法訪問的。所以第一個對象是無法訪問原型方法的。同時這種方式在子類繼承中也會有問題。
關於解決方案,我會在下一文中說明。
其實就使用方便來說的話,個人覺得是沒必要做這個判斷的。。。呵呵 ^_^
『伍』 js 什麼是面向對象
面向對象是一種開發方法或者是開發思想,面向對象是一種對現實世界理解和抽象的方法,是計算機編程技術發展到一定階段後的產物。
『陸』 憑什麼js基於對象呢
JS是笑旦明一門基於對象、事件驅動編程的客戶端腳碰告本語言。為什麼JS不是面向對象的語言?因為面向對象包括三大特徵:封裝、繼承、多態。JS中只有封裝,繼承也只是模擬繼承,談不上面向對象。遲搏所有說,在JS中,一切都是對象,屬性、數組、函數等等都是對象。
『柒』 js面向對象編程思想是什麼意思能不能舉個例子
面向對象的編程思想就是把你需要解決的問題中的所有具體的東西,都看成一個對象,然後把所有具有相同性質的對象組成一個類,那些與問題無關的對象則忽略。
『捌』 新手如何理解JS面向對象開發
技術不是很好,怕是要誤人子弟
舉個例子
比方說一個游戲裡面有「玩回家答」,而「玩家」就有血量、飢餓等屬性。
於是便可以把「玩家」作為一個對象:
var player = {heath: 100, hunger:100}
你會發現「對象」是幾種不同值的存儲器。
然後你就可以用player.health來獲取血量,player.hunger來獲取飢餓
player.health = xx 以及 player.hunger = xx 來設置
但是當多人游戲時,會有很多「玩家」,然後你發現創建對象很麻煩,而且也不夠「優雅」。
於是,就有了「構造方法」
不想寫了。。接下來自己查教程了解,相信你會恍然大悟的
『玖』 JS的本質是什麼
Javascript沒有傳統面向對象編程語言中的類,全部是對象。
Javascript中的對象是鍵值對的集合,鍵的類型是字元串,值可以是任意對象。創建新對象的方式有:new 函數()、{}語法、Object.create(原型對象)。
函數也是對象,是一種包含可運行的代碼的特殊對象,並且代碼能夠以函數調用的形式被執行。函數對象能通過function關鍵字定義或通過new關鍵字使用Function構造函數來創建。
所以,在深入理解Javascript的時候,要謹防長期使用C++、C#等編程語言造成的思維定勢卻給使用Javascript帶來誤導。
『拾』 javascript是面向對象還是面向過程
javascript是面向過程的,因為是解釋性預言,按照頁面載入一行一行的執行,但是可以模擬面向對象的代碼寫法