摘要:但是,中并沒有類的概念,而是通過構造函數替代了類的功能,為某一類的對象提供共同的屬性和方法。一只名叫的狗,首先繼承了構造函數的原型對象,而的原型對象中的有繼承了函數的原型對象,函數對象中的有繼承了的原型對象。
《圣經》里的第一章創世紀中其中有一段經典記載上帝是如何創造人的。
神說:“我們要照著我們的形象,按照我們的樣式造人”。不謀而合的是,JavaScript中似乎也遵循著上帝的旨意去創造程序世界,一切皆對象的認知里背后是世間萬物皆源于一個原型,一個統一的形式,一個柏拉圖口中的理念......
JavaScript的編程藝術也由此演繹開來~~~
目錄:
1.面向對象編程的一些初步思考
2.類與對象
3.構造函數constructor
3.1 new命令
3.2 this關鍵字
3.3.原型對象
4.一些相關的方法
"面向對象編程"(Object Oriented Programming,縮寫為OOP)本身是一種編程的思維模式,它把世界的一切看作是對象的集合,世界的運轉就是靠一個個對象分工、合作的結果。
有了這么一種宏觀維度的編程認知,那么我們在編程時也就不會困在代碼的死胡同了出不來。
給一段小代碼做初步解釋:
我們在網頁開發中,經常要進行事件綁定。
var btn = document.getElementById("button"); btn.addEventListener("click",function(){console.log("click me")})
初學時,筆者也是無意識的看到addEventListener()方法可以進行事件綁定以實現點擊特定元素后,就可以實現需求就沒有再往深層次去想太多;
隨著學習的深入,在進入OOP的章節,我們就會發現“一切皆對象”這句話的深刻性。
上面的代碼中,btn本身就一個對象,點擊時該對象將會調用自身的方法addEventListener()去干事。
一個完整的解釋就是誰(對象)干了什么(方法),btn被點擊時干了輸出‘click me ’。
當然這只是其中一個案例,JS的編程中這種編程模式貫通始終,如:
//1、定義一個對象 var sheep = { color: white, echo: function(){ console.log("mae~~~") } } sheep.echo() //這只羊發出mae的叫聲 //2.設置對象的樣式 $(".passage").css({ width: "100px", color: "pink" } ) //這個名為passge的jquery對象被設置寬和色 ......
總之,JavaScript的編程無法脫離對象而獨存
2.類與對象說了那么久,如果連對象是什么都沒一個清晰的界定,那么在編程過程中還是存在模糊地帶。
什么是對象
對象可以說是對現實事物的抽象,對象封裝了屬性和方法,屬性值指的是對象的狀態,方法指的是對象的行為。
比如,我們把NBA的巨星kobe抽象為javascript里的對象:
var kobe = { team: "Los Angeles Lakers", position: "shooting guard", ability : function(){ console.log("impress those who like basketball") } }
現實世界的科比抽象為js中kobe這一對象,效力于洛杉磯湖人和位置是得分后衛是他的屬性,能力是影響許多愛好籃球的人是他的方法。
什么是"類"(構造函數)
按照圣經的記載,在第一章的創世紀中寫道:“神按照著自己的形象造人?!?/p>
現實世界的萬物(對象)的演化不是憑空誕生的,它需要按照一個模板去構造出各種實例出來。
因此,類(構造函數)就是提供這么一種模板的‘對象’(函數本身在js中就是對象),它是對象的抽象。
但是,js中并沒有類的概念,而是通過構造函數替代了類的功能,為某一類的對象提供共同的屬性和方法。
通過構造函數能夠創造各種具有特定類的屬性和方法的實例對象。
比如,定義一個籃球運動員的類(構造函數):
//定義一個類,該類包含了一個籃球運動員應有的屬性和方法 var BasketballPlayer = function(){ this.height = "180+", this.muscle = true, this.ability = function(){ console.log("shooting and passing ") } } //由類(構造函數)創造出3個實例對象 var kobe = new BasketballPlayer(); var james =new BasketballPlayer(); var curry =new BasketballPlayer();
這里有個小問題,構造函數BasketballPlayer又是有誰構造出來呢?看了下面的代碼便知~~~
BasketballPlayer instanceof Object//true 構造函數或者是函數在js中天生就是構造函數Object的實例
所以說,所有的實例對象都有類(構造函數)創造出來,而所有的構造函數都是由最為一般的類,即Object構造出來,故一切皆對象。
【注】
類在js中表現為構造函數,為了準確起見,下面統一稱為構造函數,我們只需要知道二者起到的作用是一致就行。
前面我們了解到,世間萬物(實例對象)都是按照特定的模板(類或構造函數)構造的,而所有的構造函數都是由最一般的構造函數Object構造的。
但是,我們或許看到下面的代碼會產生這么一種疑惑:
1.構造函數中的Book的this是干嘛的,有什么門道?
2.利用構造函數Book構造實例javascript時new起到什么作用
3.為什么我構造出一個實例對象后,這個構造函數能夠返回一個對象給我
總結成一句就是:在整個造物的過程中,構造函數的運作機制是怎么樣的???
var Book = function(){ this.material = "paper"; this.color = "white"; this.utility = function(){ console.log("IQ+"); } this.whoAmI = function(){ console.log(this) } } var javascript = new Book()
this在構造函數的作用
關鍵字this在js中顯得十分重要,它在不同的運行環境(屬性和方法的調用者)指向的環境(對象)不同,也就是說this的指向是動態的,但是無論this的指向是誰,只要清楚屬性和方法的調用者是誰那么this就指向誰。
//在瀏覽器全局環境下,即window對象下 var print = function(){ console.log(this) } print()//this指向Window,因為這是Window對象調用了print方法 //在特定對象的環境下 var o = { print: function(){ console.log(this) } } o.print()//this指向o,因為這是o對象調用print方法
因此,回到構造函數中的this來,當執行 var javascript = new Book()時,此時是javascript這個實例對象調用了構造函數Book,函數內部的this指向javascript這一實例對象
javascript.whoAmI()//this此時指向javascript對象
【注】更多this的知識詳見what"s this???
new命令的原理
接下來談一談new命令的原理。
new命令的作用,就是執行構造函數,返回一個實例對象
與普通的正常調用函數不同,在函數執行前面附加new命令,函數執行以下步驟:
1.創建一個空對象,作為將要返回的實例對象;
2.將這個空對象的原型``__proto__``指向構造函數的prototype屬性以實現繼承機制 3.將這個空對象賦值給函數內部的this關鍵字 4.開始執行構造函數內部的代碼
原型對象
上面我們基本了解構造函數在創造實例對象時的部分運作機制,明白了this關鍵字和new命令在構造實例時所起的作用。
現在有一個最最重要的疑問是實例對象究竟是如何繼承構造函數中設定好的屬于該類的共有的屬性和方法呢?
prototype object
JavaScript中每個實例對象繼承自另一個對象,后者被稱為原型對象,原型對象上的屬性和方法都能被派生對象共享,這就是JavaScript著名的繼承機制的基本設計。
先上一段代碼用于講解:
function Dog(name,color){ this.name = name; this.color = color; } Dog.prototype.spark = function(){ console.log("Wow~~~") } var tony = new Dog("tony","white")
1.通過構造函數Dog生成的實例對象tony,會自動為實例對象tony分配原型對象;
2.每一個構造函數都有一個prototype屬性,該屬性就是實例對象的原型對象
3.實例對象內部有一個__proto__屬性,該屬性在被構造函數一創造出來就指向構造函數的protype屬性
這樣一來,我們通過構造函數Dog中的原型對象prototype實現了實例對象tony對Dog的共有屬性和方法的繼承。
因此,我們可以得出的思考是,原型對象定義所有實例對象的共有的屬性和方法,所有的實例對象無非是從原型對象衍生出的子對象,只不過在后來給它添加了特有的屬性和方法罷了。
prototype chain
實例對象tony的__proto__指向構造函數Dog的prototype對象,因此繼承了Dog中prototype的屬性和方法;
而構造函數本身也存在__proto__指向更一般的函數(本質上也是對象)的prototype對象;
更進一步,該函數也存在__proto__指向最一般的構造函數Object的prototype對象
這種層層嵌套的關系形成一條原型鏈(prototype chain)。
一只名叫tony的狗,首先繼承了構造函數Dog的原型對象,而Dog的原型對象中的__proto__有繼承了函數的原型對象,函數對象中的__proto__有繼承了Oject的原型對象。
這里再一次體現了構造函數Object的威力,所有的對象無非都是Object的衍生,均繼承Object.prototype的屬性和方法,更加深刻表達“一切皆對象”的思想。
4.一些相關的方法instanceof 運算符
instanceof運算符返回一個布爾值,表示指定對象是否為某個構造函數的實例
tony instanceof Dog//true or Dog.prototype.isPrototypeOf(tony)//true
Object.getPrototypeOf()
Object.getPrototypeOf()返回一個對象的原型,這是獲取原型對象的標準方法
Object.setPrototypeOf()
Object.setPrototypeOf
方法可以為現有對象設置原型,返回一個新對象,該方法接受兩個參數,第一個是現有對象,第二個是原型對象。
var foo = { x:1 }; var bar = Object.setPrototypeOf({},foo) bar.x === 1//true
我們之前以new命令去構建實例對象,本質上就是把一個空對象的proto指向構造函數的prototype,然后在實例對象上執行構造函數
var Person = function(){ this.race = "monkey" }; var Asian = new Person(); //等價于 var Asian = Object.setPrototypeOf({},Person.prototype); Person.call(Asian)
Object.create()
Object.create方法用于從原型對象生成新的實例對象,可以替代new命令
var Person = { race: "monkey" } var Asian = Object.create(Person) //等價于 var Person = function(){ this.race="monkey" } var Asian = new Person()
Object.isPrototypeOf()
對象實例的isPrototypeOf方法,用來判斷一個對象是否是另一個對象的原型。
var obj1 = {}; var obj2 = Object.create(obj1); obj1.isPrototypeOf(obj2)//true
Object.prototype.hasOwnProperty()
對象實例的hasOwnProperty方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。
var o = { name:"teren" } o.hasOwnProperty("name")//true o.hasOwnProperty("toString")//false Object.getPrototypeOf(o).hasOwnProperty("toString")//true
阮一峰-JavaScript標準參考教程
饑人谷學習筆記
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/91371.html
摘要:目錄導語對象對象小結導語本系列文章將重點講解提供的原生庫標準庫,只要在支持語言的平臺,標準庫中的提供的對象的屬性和方法都能使用對象對象的理解講的標準庫,首先要從對象談起,因為之后的所有對象都可以看做是對象構造出來的因此,對象可以看做是一個構 目錄 導語 1. Object對象 2. Array對象 3. 小結 導語 本系列文章將重點講解JavaScript提供的原生庫——標準庫,只要...
摘要:通過這個創世區塊,不停地通過變化隨機數來計算出符合條件的區塊。節點和端口號,在這個節點創建出來之后,種子節點就會發給它在這個區塊鏈中所有節點的和端口號同時記錄下這個新伙伴的和端口號。 區塊鏈概念 狹義:區塊鏈是一種按照時間順序將數據區塊以順序相連的方式組合成的一種鏈式數據結構,并以密碼方式保證的不可篡改和不可偽造的分布式賬本。 一、挖礦(產生新區塊) 首先,區塊鏈是由每一個區塊聯系而...
摘要:原文地址喵喵,讀者朋友們好,我是來自喵星的客人,地球登記名為貓。今天依然是些貓言貓語,請看官們不要嫌棄。這樣的破壞神,不是怪物是什么喵喵了個大乖乖這不是我認識的,也不是我以為自己知道的蟒蛇啊聽起來倒像是一個嚇唬小孩的神話故事。 導讀: Python貓是一只喵星來客,它愛地球的一切,特別愛優雅而無所不能的 Python。我是它的人類朋友豌豆花下貓,被授權潤色與發表它的文章。如果你是第一次...
摘要:本文首發于深入淺出區塊鏈社區原文鏈接如何搭建以太坊私有鏈原文已更新,請讀者前往原文閱讀在開發以太坊時,很多時候需要搭建一條以太坊私有鏈,通過本文一起看看如何在上進行搭建。 本文首發于深入淺出區塊鏈社區原文鏈接:如何搭建以太坊私有鏈原文已更新,請讀者前往原文閱讀 在開發以太坊時,很多時候需要搭建一條以太坊私有鏈,通過本文一起看看如何在Mac上進行搭建。 寫在前面 閱讀本文前,你應該對以太...
摘要:要點用法用法標簽屬性我們需要在中導入,因此我們必須使用導入語句其中有定義幾個屬性以配置其用法屬性可選描述可選表示要包含執行代碼的外部文件可選參數應當立即下載此腳本,但不應妨礙其他操作,只對外部腳本有用可選參數表示通過屬性指定的代碼字符集可選 要點: 用法 用法 標簽屬性 我們需要在HTML中導入javascript,因此我們必須使用導入語句:,其中script有定義幾個屬性以配置...
閱讀 1830·2023-04-26 02:32
閱讀 578·2021-11-18 13:12
閱讀 2460·2021-10-20 13:48
閱讀 2531·2021-10-14 09:43
閱讀 3841·2021-10-11 10:58
閱讀 3520·2021-09-30 10:00
閱讀 2944·2019-08-30 15:53
閱讀 3498·2019-08-30 15:53