Javascript berorientasikan objek Setiap objek terbina dalam js diperoleh daripada objek, jadi terdapat tiga ciri berorientasikan objek warisan, polimorfisme dan pembinaan semula, walaupun js kini berdasarkan prototaip Pseudo-inheritance. , tetapi idea umum ialah bahasa berorientasikan objek.
Persekitaran pengendalian tutorial ini: sistem Windows 7, versi JavaScript 1.8.5, komputer Dell G3.
Berbanding dengan bahasa lain, "objek" dalam JavaScript sentiasa kelihatan tidak begitu mesra. Sesetengah pendatang baru sering mempunyai keraguan apabila mempelajari JavaScript berorientasikan objek: Mengapa JavaScript (sehingga ES6) mempunyai konsep objek, tetapi bukan konsep kelas seperti bahasa lain? Mengapakah kita boleh menambah sifat secara bebas pada objek JavaScript, tetapi bukan bahasa lain?
Malah dalam beberapa perbahasan, sesetengah orang menekankan bahawa JavaScript bukanlah "bahasa berorientasikan objek", tetapi "bahasa berasaskan objek". Kenyataan ini pernah diedarkan secara meluas, tetapi sebenarnya, pemegang yang saya miliki ditemui setakat ini Tiada sesiapa yang membuat kenyataan ini boleh menjawab soalan "Bagaimana untuk menentukan berorientasikan objek dan berasaskan objek".
Malah, dua kata sifat berasaskan objek dan berorientasikan objek telah muncul dalam pelbagai versi piawaian JavaScript. Mula-mula kita boleh melihat definisi berasaskan objek bagi standard JavaScript Kandungan khusus definisi ini ialah: "Infrastruktur bahasa dan hos disediakan oleh objek, dan program ECMAScript ialah koleksi objek yang berkomunikasi antara satu sama lain. ." Maksud di sini bukanlah untuk menyatakan sama sekali makna berorientasikan objek yang lemah, tetapi untuk menyatakan kepentingan objek kepada bahasa.
Jadi, dalam artikel ini, saya akan cuba memberitahu anda apa itu berorientasikan objek dan berorientasikan objek dalam JavaScript.
Mari kita bincangkan dahulu tentang apa itu objek Disebabkan oleh sebab terjemahan, sukar untuk kita memahami maksud sebenar "objek" dalam konteks bahasa Cina. Sebenarnya, Objek (objek) ialah istilah umum untuk segala-galanya dalam bahasa Inggeris, yang mempunyai persamaan dengan pemikiran abstrak pengaturcaraan berorientasikan objek. "Objek" Cina tidak mempunyai kesejagatan sedemikian Dalam proses pembelajaran pengaturcaraan, kami lebih memahaminya sebagai istilah profesional.
Tetapi apa pun, kita harus sedar bahawa objek bukanlah konsep yang dicipta daripada udara nipis dalam medan komputer Ia adalah abstraksi yang mengikuti corak pemikiran manusia (jadi pengaturcaraan berorientasikan objek juga dipertimbangkan: lebih dekat A paradigma pengaturcaraan minda manusia).
Jadi, mari kita lihat dahulu apakah sebenarnya objek dalam model pemikiran manusia.
Konsep objek dibentuk pada zaman kanak-kanak awal manusia, yang jauh lebih awal daripada konsep seperti nilai dan prosedur yang biasa digunakan dalam logik pengaturcaraan kami. Pada zaman kanak-kanak, kita sentiasa mula-mula menyedari bahawa epal tertentu boleh dimakan (epal tertentu di sini adalah objek), kemudian menyedari bahawa semua epal boleh dimakan (semua epal di sini adalah kelas), dan kemudian kita menyedari bahawa Hanya kemudian boleh kami menyedari hubungan antara tiga epal dan tiga pear, dan kemudian menjana konsep nombor "3" (nilai).
Dalam buku "Analisis dan Reka Bentuk Berorientasikan Objek", Grady Booch meringkaskannya untuk kita, dia percaya bahawa dari perspektif kognitif manusia, objek harus menjadi salah satu daripada perkara berikut:
Sesuatu yang boleh disentuh atau dilihat;
Sesuatu yang boleh difahami oleh kecerdasan manusia; atau tindakan (membayangkan atau melakukan tindakan).
Dengan definisi semula jadi objek, kita boleh menerangkan objek dalam bahasa pengaturcaraan. Dalam bahasa pengaturcaraan yang berbeza, pereka bentuk juga menggunakan pelbagai ciri bahasa untuk menggambarkan objek secara abstrak Sekolah yang paling berjaya adalah menggunakan "kelas" untuk menerangkan objek, yang melahirkan bahasa pengaturcaraan yang popular seperti C dan Java. Pada tahun-tahun awal, JavaScript memilih kaedah yang lebih tidak popular: prototaip (saya akan memberi tumpuan kepada prototaip dalam artikel seterusnya, anda boleh meninggalkan kesan di sini). Ini adalah salah satu sebab mengapa saya katakan sebelum ini bahawa ia tidak bergaul.
Sebelum kemunculan ES6, sebilangan besar pengaturcara JavaScript cuba menjadikan JavaScript lebih seperti pengaturcaraan berasaskan kelas berdasarkan sistem prototaip, yang menghasilkan banyak apa yang dipanggil "rangka kerja", seperti PrototypeJS dan Dojo . Malah, mereka menjadi sejenis dialek JavaScript yang pelik, dan malah melahirkan satu siri komuniti yang tidak serasi. Jelas sekali, keuntungan melakukan setakat ini melebihi kerugian.
Jika kita bercakap tentang objek dari perspektif masa jalan, kita membincangkan model berjalan sebenar JavaScript Ini kerana sebarang pelaksanaan kod tidak boleh memintas model objek masa jalan Walau bagaimanapun, mujurlah, dari perspektif masa jalan. anda tidak perlu risau dengan "kemudahan berasaskan kelas" ini kerana konsep kelas runtime dalam mana-mana bahasa adalah lemah.
Pertama, mari kita fahami cara JavaScript mereka bentuk model objek.
Pada pendapat saya, tidak kira apa bahasa pengaturcaraan yang kita gunakan, kita harus terlebih dahulu memahami ciri-ciri penting objek (rujuk "Analisis dan Reka Bentuk Berorientasikan Objek" Grandy Booch). Untuk meringkaskan, objek mempunyai ciri-ciri berikut.
Objek boleh dikenal pasti secara unik: walaupun dua objek yang betul-betul sama bukan objek yang sama.
Objek adalah stateful: Objek mempunyai keadaan, dan objek yang sama mungkin berada dalam keadaan yang berbeza.
Objek mempunyai tingkah laku: iaitu, keadaan objek mungkin berubah disebabkan kelakuannya.
Mari kita lihat ciri pertama dahulu, objek itu boleh dikenal pasti secara unik. Secara umumnya, pengenalan unik objek dalam pelbagai bahasa dicerminkan oleh alamat memori Oleh itu, pengaturcara JavaScript tahu bahawa mana-mana objek JavaScript yang berbeza tidak sama antara satu sama lain Kita boleh melihat kod berikut, o1 dan o2 Pada pandangan pertama , ia adalah dua objek yang sama, tetapi hasil cetakan adalah palsu.
var o1 = { a: 1 }; var o2 = { a: 1 }; console.log(o1 == o2); // false
Mengenai ciri kedua dan ketiga objek, "keadaan dan tingkah laku", bahasa yang berbeza menggunakan istilah yang berbeza untuk menerangkannya secara abstrak Contohnya, C memanggilnya "pembolehubah ahli" dan " Fungsi ahli ", Java memanggilnya "sifat" dan "kaedah".
Dalam JavaScript, keadaan dan tingkah laku disatukan dan diabstraksikan sebagai "sifat". Memandangkan fungsi direka bentuk sebagai objek khas dalam JavaScript (saya akan menerangkannya secara terperinci kemudian, jadi tidak perlu pergi ke butiran. di sini) ), jadi tingkah laku dan keadaan dalam JavaScript boleh diabstrak menggunakan atribut.
Kod berikut sebenarnya menunjukkan contoh atribut dan fungsi biasa sebagai atribut, dengan o ialah objek, d ialah atribut, dan fungsi f juga merupakan atribut Walaupun kaedah penulisannya tidak sama, ia sesuai untuk JavaScript Contohnya, d dan f ialah dua atribut biasa.
var o = { d: 1, f() { console.log(this.d); } };
Jadi, secara ringkasnya, dalam JavaScript, keadaan dan gelagat objek sebenarnya disarikan kepada sifat. Jika anda telah menggunakan Java, jangan terkejut Walaupun terdapat perbezaan tertentu dalam idea reka bentuk, kedua-duanya menyatakan ciri asas objek: identiti, status dan tingkah laku.
Berdasarkan merealisasikan ciri asas objek, saya percaya bahawa ciri unik objek dalam JavaScript ialah: objek sangat dinamik Ini kerana JavaScript membenarkan pengguna menambah perubahan pada objek pada masa jalan dan keupayaan tingkah laku .
Biar saya berikan contoh kepada anda, sebagai contoh, JavaScript membenarkan menambahkan sifat pada objek pada masa jalan, yang sama sekali berbeza daripada kebanyakan reka bentuk objek statik berasaskan kelas. Jika anda telah menggunakan Java atau bahasa lain, anda pasti akan mempunyai perasaan yang sama seperti saya.
Kod berikut menunjukkan cara menambah atribut pada masa jalan Pada mulanya, saya mentakrifkan objek o Selepas definisi selesai, saya menambahkan atributnya b. Anda perlu memahami perkara ini.
var o = { a: 1 }; o.b = 2; console.log(o.a, o.b); //1 2
Untuk meningkatkan keupayaan pengabstrakan, sifat JavaScript direka bentuk untuk menjadi lebih kompleks daripada bahasa lain Ia menyediakan dua jenis sifat data dan sifat pengakses (getter/setter).
Untuk JavaScript, atribut bukan sekadar nama dan nilai mudah JavaScript menggunakan set ciri untuk menerangkan sifat.
Mari kita bincangkan tentang jenis atribut pertama, atribut data. Ia lebih dekat dengan konsep atribut bahasa lain. Atribut data mempunyai empat ciri.
nilai: Ia ialah nilai atribut.
boleh ditulis: Menentukan sama ada atribut boleh diberikan nilai.
boleh dikira: Menentukan sama ada for in boleh menghitung atribut ini.
boleh dikonfigurasikan: Menentukan sama ada atribut boleh dipadamkan atau nilai ciri boleh ditukar.
Dalam kebanyakan kes, kami hanya mengambil berat tentang nilai atribut data.
Atribut jenis kedua ialah atribut pengakses (getter/setter), yang juga mempunyai empat ciri.
getter: fungsi atau tidak ditentukan, dipanggil apabila mendapat nilai atribut.
setter: fungsi atau tidak ditentukan, dipanggil semasa menetapkan nilai sifat.
boleh dikira: Menentukan sama ada for in boleh menghitung atribut ini.
boleh dikonfigurasikan: Menentukan sama ada atribut boleh dipadamkan atau nilai ciri boleh ditukar.
Atribut pengakses membenarkan harta untuk melaksanakan kod semasa membaca dan menulis Ia membolehkan pengguna mendapat nilai yang sama sekali berbeza semasa menulis dan membaca harta itu sintaks.
Kod yang biasa kami gunakan untuk mentakrifkan atribut akan menghasilkan atribut data, antaranya boleh ditulis, boleh dikira dan boleh dikonfigurasikan semuanya lalai kepada benar. Kami boleh menggunakan fungsi terbina dalam Object.getOwnPropertyDescripter untuk melihat, seperti yang ditunjukkan dalam kod berikut:
var o = { a: 1 }; o.b = 2;//a和b皆为数据属性 Object.getOwnPropertyDescriptor(o,\u0026quot;a\u0026quot;) // {value: 1, writable: true, enumerable: true, configurable: true} Object.getOwnPropertyDescriptor(o,\u0026quot;b\u0026quot;) // {value: 2, writable: true, enumerable: true, configurable: true}
Kami menggunakan dua sintaks di sini untuk menentukan sifat Selepas mentakrifkan sifat, kami menggunakan API JavaScript untuk view Untuk atribut ini, kita boleh mendapati bahawa atribut yang ditakrifkan dengan cara ini ialah semua atribut data, dan nilai lalai boleh tulis, boleh dikira dan boleh dikonfigurasikan adalah benar.
Jika kita ingin menukar ciri-ciri harta atau mentakrifkan sifat pengakses, kita boleh menggunakan Object.defineProperty Contohnya adalah seperti berikut:
var o = { a: 1 }; Object.defineProperty(o, \u0026quot;b\u0026quot;, {value: 2, writable: false, enumerable: false, configurable: true});//a和b都是数据属性,但特征值变化了 Object.getOwnPropertyDescriptor(o,\u0026quot;a\u0026quot;); // {value: 1, writable: true, enumerable: true, configurable: true} Object.getOwnPropertyDescriptor(o,\u0026quot;b\u0026quot;); // {value: 2, writable: false, enumerable: false, configurable: true}o.b = 3;console.log(o.b); // 2
这里我们使用了Object.defineProperty来定义属性,这样定义属性可以改变属性的writable和enumerable,我们同样用Object.getOwnPropertyDescriptor来查看,发现确实改变了writable和enumerable特征。因为writable特征为false,所以我们重新对b赋值,b的值不会发生变化。
在创建对象时,也可以使用 get 和 set 关键字来创建访问器属性,代码如下所示:
var o = { get a() { return 1 } }; console.log(o.a); // 1
访问器属性跟数据属性不同,每次访问属性都会执行getter或者setter函数。这里我们的getter函数返回了1,所以o.a每次都得到1。
这样,我们就理解了,实际上JavaScript 对象的运行时是一个“属性的集合”,属性以字符串或者Symbol为key,以数据属性特征值或者访问器属性特征值为value。对象是一个属性的索引结构(索引结构是一类常见的数据结构,我们可以把它理解为一个能够以比较快的速度用key来查找value的字典)。我们以上面的对象o为例,你可以想象一下“a”是key。
这里{writable:true,value:1,configurable:true,enumerable:true}是value。我们在前面的类型课程中,已经介绍了Symbol类型,能够以Symbol为属性名,这是JavaScript对象的一个特色。
讲到了这里,如果你理解了对象的特征,也就不难理解我开篇提出来的问题。
你甚至可以理解为什么会有“JavaScript不是面向对象”这样的说法:JavaScript的对象设计跟目前主流基于类的面向对象差异非常大。而事实上,这样的对象系统设计虽然特别,但是JavaScript提供了完全运行时的对象系统,这使得它可以模仿多数面向对象编程范式(下一节课我们会给你介绍JavaScript中两种面向对象编程的范式:基于类和基于原型),所以它也是正统的面向对象语言。
JavaScript语言标准也已经明确说明,JavaScript是一门面向对象的语言,我想标准中能这样说正因为JavaScript的高度动态性的对象系统。
所以,我们应该在理解其设计思想的基础上充分挖掘它的能力,而不是机械地模仿其它语言。
要想理解JavaScript对象,必须清空我们脑子里“基于类的面向对象”相关的知识,回到人类对对象的朴素认知和面向对象的语言无关基础理论,我们就能够理解JavaScript面向对象设计的思路。
在这篇文章中,我从对象的基本理论出发,和你理清了关于对象的一些基本概念,分析了JavaScript对象的设计思路。接下来又从运行时的角度,介绍了JavaScript对象的具体设计:具有高度动态性的属性集合。
很多人在思考JavaScript对象时,会带着已有的“对象”观来看问题,最后的结果当然就是“剪不断理还乱”了。
【推荐学习:javascript高级教程】
Atas ialah kandungan terperinci Adakah javascript berdasarkan objek?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!