摘要:屬性屬性當我們通過關鍵字構造函數實例化創建一個對象時,這個對象里面含有屬性,屬性指向構造函數屬性以及屬性下面的對象。
眾所周知,JavaScript是一門面向對象的操作語言,而我們想要用JavaScript對象化寫法的時候,不得不提出一個操作符,叫做new操作符,那么不用new操作符和用new操作符有什么區別呢?
1.用new和不用new的區別首先,我們去看下new在JavaScript里面的用法,按照javascript語言精粹中所說,如果在一個函數前面帶上new來調用該函數,那么將創建一個隱藏連接到該函數的prototype成員的新對象,同時this將被綁定到那個新對象上。這句話說得很抽象,我們根據代碼來理解。
function foo(){ this.name = "John"; this.age = 23; var born = 1993; return this.age; } //沒用new關鍵字 var foo2 = foo(); console.log(foo2);//23 //用new關鍵字 var foo3 = new foo(); console.log(foo3);//foo {name: "John", age: 23}
通過上面的代碼可以明顯看出區別,當我們不用new關鍵字的時候我們只是把foo函數運行了一遍,如果有返回值就就獲得這個返回值,沒有返回值就輸出underfind,只是簡單的函數運行一遍而已。
但是當我們用new關鍵字的時候,我們就可以看到不同了,new關鍵字是生成一個對象,并且生成的對象里面的屬性是foo函數公有屬性(即只有用this關鍵字定義的變量),而忽略掉私有變量(即用var定義的變量)和函數返回值,這樣上面關于new關鍵字的解釋就好理解了,即通過new操作符創建一個連接到foo函數的對象,對象里包含foo函數里面所有屬性和方法。這就是new關鍵字的作用,并且this是指向我們當前的對象foo3.
js語言沒有類這個概念,所以提出用原型來代替類來實現js面向對象寫法。js規定每個函數都具有prototype對象,并且prototype對象在函數外部是可以訪問的,可以通過"prototype.xxx"來為當前函數增加屬性和方法,所以prototype屬性可以理解為當我們想為這個函數添加屬性或者方法時我們可以在prototype屬性下面添加,而不需要去改變構造函數的代碼。
function foo(){ this.name = "John"; this.age = 23; var born = 1993; return this.age; } foo.prototype.ccc = function(){ console.log(this.name); } console.log(foo.prototype);//Object {}
chrome的運行結果如下圖:
可以看到foo函數里的prototype是可以訪問的,并且我們所添加的函數是在prototype對象里的。這樣,我們就可以通過prototype屬性向對象添加屬性和方法。
2.2constructor(構造器)屬性在上面的我們看到chrome瀏覽器運行結果的圖中,我們打印foo函數prototype對象可以發現里面包含有constructor屬性,所以constructor屬性的是prototype對象下的一個屬性,即:
function foo(){ this.name = "John"; this.age = 23; var born = 1993; return this.age; } console.log(foo.prototype.constructor == foo);//true
可以看到原型對象下的constructor事指向當前構造函數的,函數在創建時就會自動生成constructor屬性來指向當前對象,實例化對象時constructor屬性也會一并繼承到新的對象下面。
2.3__proto__屬性__proto__屬性當我們通過new關鍵字構造函數實例化創建一個對象時,這個對象里面含有__proto__屬性,__proto__屬性指向構造函數prototype屬性以及prototype屬性下面的對象。即:
function foo(){ this.name = "John"; this.age = 23; var born = 1993; return this.age; } foo.prototype.ccc = function(){ console.log(this.name); } var foo2 = new foo(); console.log(foo2.__proto__ == foo.prototype)//true console.log(foo2.__proto__)//Object {ccc:function(),constructor: foo()}
console.log(foo2.__proto__)在chrome里的運行結果如下圖:
可以看到__proto__對象是等于foo.prototype對象的,并且foo.prototype對象下面的方法和屬性都已經在實例化對象foo2下的__proto__下面了。
3.js的原型鏈js沒有其他面向對象編程語言的多態的概念,所以如何實現多態的概念。這時,js提出了原型鏈的概念,通過原型鏈來實現擴展方法以及屬性的功能。看如下代碼
function foo(){ this.name = "John"; this.age = 23; var born = 1993; return this.age; } foo.prototype.ccc = function(){ console.log(this.name); } var foo2 = new foo(); foo2.ccc();//John var foo3 = new foo(); foo3.ccc();//John //修改foo3對象下面ccc方法 foo3.ccc = function(){ console.log(this.age); } foo3.ccc();//23
從上面代碼實例化對象時新的對象不僅克隆了構造的函數屬性和方法,也克隆了構造函數原型下的屬性以及方法,在foo3對象中,當我們沒有修改ccc方法時,函數會在當前對像下查找,沒查找到就會去原型對象里查找該方法,在原型對象里找到了ccc方法,打印出this.name為“John”,當我們重寫了ccc方法時,ccc方法就已經foo3當前對象下面了,所以在當前對象下面找到了ccc方法,運行ccc方法,并且停止查到,不會再繼續向下查,所以js原型鏈會遵循就近查找原則,如果查找不到當前方法會到原型下去查找,查找不到再去原型下面的原型去查找,直到查找到所有原型為止。
我們答應下foo3對象,console.log(foo3),在chrome運行結果如下圖:
可以看出foo3對象下面擁有一個ccc方法,并且在原型對象下面也擁有一個ccc方法,遵循就近查找原則,會找到foo3對象下面的ccc方法,而不會去查到原型對象里的ccc方法。所以通過js的原型鏈可以修改對象的屬性和方法。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79931.html
摘要:我們通過表單驗證的功能,來逐步演進面向對象的方式對于剛剛接觸的朋友來說,如果要寫一個驗證用戶名,密碼,郵箱的功能,一般可能會這么寫表單驗證全局全局全局這種寫法,從功能上來說沒有什么問題,但是在團隊協作的時候,會造成覆蓋全局變量的問題,那要大 我們通過表單驗證的功能,來逐步演進面向對象的方式. 對于剛剛接觸javascript的朋友來說,如果要寫一個驗證用戶名,密碼,郵箱的功能, 一...
摘要:這個構造函數的不管從調用方式還是內部寫法就都很有的感覺,但是從用途上來說,它其實更靠近的概念是中的工廠方法。到這里,所有關于繼承的東西講完了,接下來準備準備說說當中的封裝 所謂的對象,就是抽象化的數據本身 一個面向對象轉向面向原型的困惑 我發現Javascript這門語言每次翻開都會帶給人新感受,尤其是看完其他語言的面向對象再來看它,但是如果你也是過來人就一定記得教科書里面冗長乏味的...
摘要:回到最開始的組件問題那么,說了這么多面向對象,現在回到最開始的那個組件的實現如何用面向對象來實現。總結從一個組件出發,一步一步爬坑,又跑去介紹中的面向對象,如果你能看到最后,那么你就可動手一步一步實現一個了,純調侃。 其實,無論是寫什么語言的程序員,最終的目的,都是把產品或代碼封裝到一起,提供接口,讓使用者很舒適的實現功能。所以對于我來說,往往頭疼的不是寫代碼,而是寫注釋和文檔!如果接...
摘要:不必在構造函數中定義對象實例的信息。其次,按照一切事物皆對象的這餓極本的面向對象的法則來說,類本身并不是一個對象,然而原型方式的構造函數和原型本身也是個對象。第二個問題就是在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。 前言 對象(Object)應該算是js中最為重要的部分,也是js中非常難懂晦澀的一部分。更是面試以及框架設計中各出沒。寫這篇文章,主要參考與JavaScrip...
閱讀 2019·2023-04-26 02:15
閱讀 2302·2021-11-19 09:40
閱讀 1038·2021-10-27 14:13
閱讀 3307·2021-08-23 09:44
閱讀 3609·2019-12-27 12:24
閱讀 652·2019-08-30 15:53
閱讀 1164·2019-08-30 10:53
閱讀 2153·2019-08-26 12:14