前端 ---JS中的面向对象
JS中的面向?qū)ο?/h1> 創(chuàng)建對象的幾種常用方式
1.使用Object或?qū)ο笞置媪縿?chuàng)建對象
2.工廠模式創(chuàng)建對象
3.構(gòu)造函數(shù)模式創(chuàng)建對象
4.原型模式創(chuàng)建對象
1.使用Object或?qū)ο笞置媪縿?chuàng)建對象
JS中最基本創(chuàng)建對象的方式:
var student = new Object(); student.name = "easy"; student.age = "20";這樣,一個student對象就創(chuàng)建完畢,擁有2個屬性name以及age,分別賦值為"easy"和20。
?如果你嫌這種方法有一種封裝性不良的感覺。來一個對象字面量方式創(chuàng)建對象。
var sutdent = {name : "easy",age : 20 };這樣看起來似乎就完美了。但是馬上我們就會發(fā)現(xiàn)一個十分尖銳的問題:當(dāng)我們要創(chuàng)建同類的student1,student2,…,studentn時,我們不得不將以上的代碼重復(fù)n次....
var sutdent1 = {name : "easy1",age : 20 };var sutdent2 = {name : "easy2",age : 20 };...var sutdentn = {name : "easyn",age : 20 };有個提問?能不能像工廠車間那樣,有一個車床就不斷生產(chǎn)出對象呢?我們看”工廠模式”。
?
2.工廠模式創(chuàng)建對象
JS中沒有類的概念,那么我們不妨就使用一種函數(shù)將以上對象創(chuàng)建過程封裝起來以便于重復(fù)調(diào)用,同時可以給出特定接口來初始化對象
function createStudent(name, age) {var obj = new Object();obj.name = name;obj.age = age;return obj; }var student1 = createStudent("easy1", 20); var student2 = createStudent("easy2", 20); ... var studentn = createStudent("easyn", 20);這樣一來我們就可以通過createStudent函數(shù)源源不斷地”生產(chǎn)”對象了。看起來已經(jīng)高枕無憂了,但貪婪的人類總有不滿足于現(xiàn)狀的天性:我們不僅希望”產(chǎn)品”的生產(chǎn)可以像工廠車間一般源源不斷,我們還想知道生產(chǎn)的產(chǎn)品究竟是哪一種類型的。
比如說,我們同時又定義了”生產(chǎn)”水果對象的createFruit()函數(shù):
function createFruit(name, color) {var obj = new Object();obj.name = name;obj.color = color;return obj; }var v1 = createStudent("easy1", 20); var v2 = createFruit("apple", "green");對于以上代碼創(chuàng)建的對象v1、v2,我們用instanceof操作符去檢測,他們統(tǒng)統(tǒng)都是Object類型。我們的當(dāng)然不滿足于此,我們希望v1是Student類型的,而v2是Fruit類型的。為了實(shí)現(xiàn)這個目標(biāo),我們可以用自定義構(gòu)造函數(shù)的方法來創(chuàng)建對象
3.構(gòu)造函數(shù)模式創(chuàng)建對象
在上面創(chuàng)建Object這樣的原生對象的時候,我們就使用過其構(gòu)造函數(shù):
var obj = new Object();在創(chuàng)建原生數(shù)組Array類型對象時也使用過其構(gòu)造函數(shù):
?
var arr = new Array(10); //構(gòu)造一個初始長度為10的數(shù)組對象在進(jìn)行自定義構(gòu)造函數(shù)創(chuàng)建對象之前,我們首先了解一下構(gòu)造函數(shù)和普通函數(shù)有什么區(qū)別。
1、實(shí)際上并不存在創(chuàng)建構(gòu)造函數(shù)的特殊語法,其與普通函數(shù)唯一的區(qū)別在于調(diào)用方法。對于任意函數(shù),使用new操作符調(diào)用,那么它就是構(gòu)造函數(shù);不使用new操作符調(diào)用,那么它就是普通函數(shù)。
2、按照慣例,我們約定構(gòu)造函數(shù)名以大寫字母開頭,普通函數(shù)以小寫字母開頭,這樣有利于顯性區(qū)分二者。例如上面的new Array(),new Object()。
3、使用new操作符調(diào)用構(gòu)造函數(shù)時,會經(jīng)歷(1)創(chuàng)建一個新對象;(2)將構(gòu)造函數(shù)作用域賦給新對象(使this指向該新對象);(3)執(zhí)行構(gòu)造函數(shù)代碼;(4)返回新對象;4個階段。
ok,了解了構(gòu)造函數(shù)和普通函數(shù)的區(qū)別之后,我們使用構(gòu)造函數(shù)將工廠模式的函數(shù)重寫,并添加一個方法屬性:?
?
function Student(name, age) {this.name = name;this.age = age;this.alertName = function(){alert(this.name)}; }function Fruit(name, color) {this.name = name;this.color = color;this.alertName = function(){alert(this.name)}; }這樣我們再分別創(chuàng)建Student和Fruit的對象:
var v1 = new Student("easy", 20); var v2 = new Fruit("apple", "green");這時我們再來用instanceof操作符來檢測以上對象類型就可以區(qū)分出Student以及Fruit了:
alert(v1 instanceof Student); //true alert(v2 instanceof Student); //false alert(v1 instanceof Fruit); //false alert(v2 instanceof Fruit); //truealert(v1 instanceof Object); //true 任何對象均繼承自O(shè)bject alert(v2 instanceof Object); //true 任何對象均繼承自O(shè)bject這樣我們就解決了工廠模式無法區(qū)分對象類型的尷尬。那么使用構(gòu)造方法來創(chuàng)建對象是否已經(jīng)完美了呢?使用構(gòu)造器函數(shù)通常在js中我們來創(chuàng)建對象。
我們會發(fā)現(xiàn)Student和Fruit對象中共有同樣的方法,當(dāng)我們進(jìn)行調(diào)用的時候這無疑是內(nèi)存的消耗。
我們完全可以在執(zhí)行該函數(shù)的時候再這樣做,辦法是將對象方法移到構(gòu)造函數(shù)外部:
function Student(name, age) {this.name = name;this.age = age;this.alertName = alertName; }function alertName() {alert(this.name); }var stu1 = new Student("easy1", 20); var stu2 = new Student("easy2", 20);在調(diào)用stu1.alertName()時,this對象才被綁定到stu1上。
我們通過將alertName()函數(shù)定義為全局函數(shù),這樣對象中的alertName屬性則被設(shè)置為指向該全局函數(shù)的指針。由此stu1和stu2共享了該全局函數(shù),解決了內(nèi)存浪費(fèi)的問題
但是,通過全局函數(shù)的方式解決對象內(nèi)部共享的問題,終究不像一個好的解決方法。如果這樣定義的全局函數(shù)多了,我們想要將自定義對象封裝的初衷便幾乎無法實(shí)現(xiàn)了。更好的方案是通過原型對象模式來解決。
4.原型的模式創(chuàng)建對象
原型鏈甚至原型繼承,是整個JS中最難的一部分也是最不好理解的一部分,在這里由于我們課程定位的原因,如果對js有興趣的同學(xué),可以去查閱一下相關(guān)JS原型的一些知識點(diǎn)。更加有助于你以后前端JS的面試。
function Student() {this.name = 'easy';this.age = 20; }Student.prototype.alertName = function(){alert(this.name); };var stu1 = new Student(); var stu2 = new Student();stu1.alertName(); //easy stu2.alertName(); //easyalert(stu1.alertName == stu2.alertName); //true 二者共享同一函數(shù)轉(zhuǎn)載于:https://www.cnblogs.com/liuafan/p/9523906.html
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的前端 ---JS中的面向对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记一次vue+vuex+vue-rout
- 下一篇: 8.23学习笔记