一文詳解JavaScript中prototype的使用
prototype初步認(rèn)識(shí)
在學(xué)習(xí)JavaScript中,遇到了prototype,經(jīng)過(guò)一番了解,知道它是可以進(jìn)行動(dòng)態(tài)擴(kuò)展的
function Func(){}; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展
即最開(kāi)始創(chuàng)建的函數(shù)Func并沒(méi)有var1變量,但是我們可以進(jìn)行擴(kuò)展,并且讓根據(jù)其創(chuàng)建的對(duì)象也有var1變量
函數(shù)有prototype屬性,函數(shù)創(chuàng)建的對(duì)象沒(méi)有
這個(gè)時(shí)候,嘗試對(duì)var1變量進(jìn)行擴(kuò)展,但是居然報(bào)錯(cuò)了
function Func(){}; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log(Func.var1) func1.prototype.var1 = "func1進(jìn)行了擴(kuò)展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1')
獲得當(dāng)前對(duì)象的屬性
那我們現(xiàn)在有一個(gè)疑問(wèn):func1應(yīng)該是有var1變量的,那上面報(bào)錯(cuò)意思是func1沒(méi)有prototype屬性/方法咯?我如何查看一個(gè)對(duì)象到底有沒(méi)有這個(gè)屬性呢?
我們知道,可以用in來(lái)查看對(duì)象是否有屬性
function Func(){}; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log(Func.var1) // func1.prototype.var1 = "func1進(jìn)行了擴(kuò)展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1') console.log("var1" in func1) //true console.log("prototype" in func1) //false
現(xiàn)在我們知道了,func1確實(shí)沒(méi)有prototype屬性/方法,那func1也就是函數(shù)創(chuàng)建的對(duì)象都不能擴(kuò)展了嗎?回答這個(gè)問(wèn)題之前,我們還要明白一個(gè)問(wèn)題,func1中的var1變量是自己的嗎?怎么區(qū)分呢?
function Func(){}; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log(Func.var1) // func1.prototype.var1 = "func1進(jìn)行了擴(kuò)展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1') console.log("var1" in func1) //true console.log("prototype" in func1) //false console.log("-----接下來(lái)看hasOwnProperty函數(shù)-----") func1.var2 = "func1自己的變量" console.log(func1.hasOwnProperty("var2")) //true console.log(func1.hasOwnProperty("var1")) //false
我們可以用hasOwnProperty
函數(shù)來(lái)知道變量是不是擴(kuò)展的了
父和子的擴(kuò)展
這里我把Func當(dāng)成父,把func1當(dāng)成子來(lái)作為個(gè)人理解
function Func() { }; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log(Func.var1) // func1.prototype.var1 = "func1進(jìn)行了擴(kuò)展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1') console.log("var1" in func1) //true console.log("prototype" in func1) //false console.log("-----接下來(lái)看hasOwnProperty函數(shù)-----") func1.var2 = "func1自己的變量" console.log(func1.hasOwnProperty("var2")) //true console.log(func1.hasOwnProperty("var1")) //false console.log("-----接下來(lái)看proto-----") console.log(Func.hasOwnProperty("__proto__")) //false console.log(func1.hasOwnProperty("__proto__")) //false console.log(func1.__proto__ === Func.prototype) // true console.log(func1.__proto__ == Func.prototype) // true console.log(func1.prototype == Func.prototype) // false console.log(func1.__proto__.var1) //Func進(jìn)行了擴(kuò)展 console.log(func1.var1) //Func進(jìn)行了擴(kuò)展
這里可以看到func1本身沒(méi)有__proto__
屬性,但是和Func的protype屬性是一樣的
子的proto和prototype的區(qū)別
到這里你肯定想問(wèn),對(duì)于子func1的__proto__
和prototype有什么區(qū)別呢?
首先子func1并沒(méi)有prototype屬性
其實(shí)雙下劃線表示隱藏的,不太想讓外界訪問(wèn)到,這么思考,父Func不僅創(chuàng)建了子func1,而且創(chuàng)建了子func2,這時(shí)候如果子func1通過(guò)__proto__
修改了var1,那么父Func的var1跟著變化,并且func2的var1也會(huì)變化,但是如果func1直接修改var1,那么父Func和子func2的var1都不會(huì)變化
function Func() { }; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log(Func.var1) // func1.prototype.var1 = "func1進(jìn)行了擴(kuò)展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1') console.log("var1" in func1) //true console.log("prototype" in func1) //false console.log("-----接下來(lái)看hasOwnProperty函數(shù)-----") func1.var2 = "func1自己的變量" console.log(func1.hasOwnProperty("var2")) //true console.log(func1.hasOwnProperty("var1")) //false console.log("-----接下來(lái)看proto-----") console.log(Func.hasOwnProperty("__proto__")) //false console.log(func1.hasOwnProperty("__proto__")) //false console.log(func1.__proto__ === Func.prototype) // true console.log(func1.__proto__ == Func.prototype) // true console.log(func1.prototype == Func.prototype) // false console.log(func1.__proto__.var1) //Func進(jìn)行了擴(kuò)展 console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log("-----接下來(lái)看proto和prototype的區(qū)別-----") func1.var1 = "func1進(jìn)行了擴(kuò)展" console.log(func1.var1) //func1進(jìn)行了擴(kuò)展 console.log(Func.prototype.var1) //Func進(jìn)行了擴(kuò)展
擴(kuò)展得到的東西到底從哪來(lái)的
那么子func1我們前面使用了hasOwnProperty屬性,但是func1本身并沒(méi)有這個(gè)屬性,那么它從哪來(lái)的?
function Func() { }; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log(Func.var1) // func1.prototype.var1 = "func1進(jìn)行了擴(kuò)展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1') console.log("var1" in func1) //true console.log("prototype" in func1) //false console.log("-----接下來(lái)看hasOwnProperty函數(shù)-----") func1.var2 = "func1自己的變量" console.log(func1.hasOwnProperty("var2")) //true console.log(func1.hasOwnProperty("var1")) //false console.log("-----接下來(lái)看proto-----") console.log(Func.hasOwnProperty("__proto__")) //false console.log(func1.hasOwnProperty("__proto__")) //false console.log(func1.__proto__ === Func.prototype) // true console.log(func1.__proto__ == Func.prototype) // true console.log(func1.prototype == Func.prototype) // false console.log(func1.__proto__.var1) //Func進(jìn)行了擴(kuò)展 console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log("-----接下來(lái)看proto和prototype的區(qū)別-----") func1.var1 = "func1進(jìn)行了擴(kuò)展" console.log(func1.var1) //func1進(jìn)行了擴(kuò)展 console.log(Func.prototype.var1) //Func進(jìn)行了擴(kuò)展 console.log("-----接下來(lái)看hasOwnProperty從哪來(lái)的-----") console.log(Func.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true console.log(Func.__proto__.hasOwnProperty("hasOwnProperty")) // false console.log(func1.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true
從父和子那節(jié)的那張圖也可以看出,使用兩次__proto__
即可找到hasOwnProperty屬性
那么到此也就了解了prototype和__proto__
了
附上完整代碼兩段供測(cè)試:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function Fun(){ } var func1 = new Fun() console.log(typeof Fun) // function console.log(typeof func1) // object console.log(func1.prototype) // undefined console.log(typeof func1.__proto__) // object console.log(func1.__proto__) // 一個(gè)比較復(fù)雜的object console.log(func1.__proto__ == Fun.prototype) // true console.log(func1.prototype == Fun.prototype) // false Fun.prototype.var1 = "hello" console.log(func1.var1) // hello console.log(func1.__proto__.var1) // hello func1.var1 = "yes" console.log(Fun.var1) // undefined console.log(func1.var1) // yes console.log(Fun.prototype.var1) // hello console.log(func1.__proto__.var1) // hello console.log(func1.prototype) // undefined func1.__proto__.var1 = "hhh" console.log(func1.__proto__.var1) // hhh console.log(Fun.prototype.var1) // hhh console.log(Fun.__proto__.var1) // undefined console.log("------測(cè)試原型對(duì)象里面的proto-------") console.log(func1.hasOwnProperty("var1")) // true console.log(func1.hasOwnProperty("__proto__")) console.log(Fun.hasOwnProperty("hasOwnProperty")) // false console.log(Fun.hasOwnProperty("__proto__")) // false console.log(Fun.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true console.log(Fun.__proto__.hasOwnProperty("hasOwnProperty")) // false console.log(func1.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function Func() { }; var func1 = new Func; console.log(func1.var1) //undefined Func.prototype.var1 = "Func進(jìn)行了擴(kuò)展" console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log(Func.var1) // func1.prototype.var1 = "func1進(jìn)行了擴(kuò)展" //Uncaught TypeError: Cannot set properties of undefined (setting 'var1') console.log("var1" in func1) //true console.log("prototype" in func1) //false console.log("-----接下來(lái)看hasOwnProperty函數(shù)-----") func1.var2 = "func1自己的變量" console.log(func1.hasOwnProperty("var2")) //true console.log(func1.hasOwnProperty("var1")) //false console.log("-----接下來(lái)看proto-----") console.log(Func.hasOwnProperty("__proto__")) //false console.log(func1.hasOwnProperty("__proto__")) //false console.log(func1.__proto__ === Func.prototype) // true console.log(func1.__proto__ == Func.prototype) // true console.log(func1.prototype == Func.prototype) // false console.log(func1.__proto__.var1) //Func進(jìn)行了擴(kuò)展 console.log(func1.var1) //Func進(jìn)行了擴(kuò)展 console.log("-----接下來(lái)看proto和prototype的區(qū)別-----") func1.var1 = "func1進(jìn)行了擴(kuò)展" console.log(func1.var1) //func1進(jìn)行了擴(kuò)展 console.log(Func.prototype.var1) //Func進(jìn)行了擴(kuò)展 console.log("-----接下來(lái)看hasOwnProperty從哪來(lái)的-----") console.log(Func.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true console.log(Func.__proto__.hasOwnProperty("hasOwnProperty")) // false console.log(func1.__proto__.__proto__.hasOwnProperty("hasOwnProperty")) // true </script> </body> </html>
以上就是一文詳解JavaScript中prototype的使用的詳細(xì)內(nèi)容,更多關(guān)于JavaScript prototype的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
10種JavaScript最常見(jiàn)的錯(cuò)誤(小結(jié))
這篇文章主要介紹了10種JavaScript最常見(jiàn)的錯(cuò)誤(小結(jié)),查看了數(shù)千個(gè)項(xiàng)目后,發(fā)現(xiàn)了 10 個(gè)最常見(jiàn)的 JavaScript 錯(cuò)誤。我們會(huì)告訴你什么原因?qū)е铝诉@些錯(cuò)誤,以及如何防止這些錯(cuò)誤發(fā)生2019-06-06js實(shí)現(xiàn)文章目錄索引導(dǎo)航(table of content)
這篇文章主要介紹了js實(shí)現(xiàn)文章目錄索引導(dǎo)航(table of content),需要的朋友可以參考下2020-05-05Webpack 之 babel-loader文件預(yù)處理器詳解
這篇文章主要介紹了Webpack 之 babel-loader文件預(yù)處理器詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03js onmousewheel事件多次觸發(fā)問(wèn)題解決方法
做一個(gè)首屏和第二屏之間滾動(dòng)鼠標(biāo)滾輪就可以整平切換的效果,遇到了很多問(wèn)題,下面是問(wèn)題解決方法2014-10-10JS實(shí)現(xiàn)加載時(shí)鎖定HTML頁(yè)面元素的方法
這篇文章主要介紹了JS實(shí)現(xiàn)加載時(shí)鎖定HTML頁(yè)面元素的方法,涉及javascript針對(duì)頁(yè)面元素的遍歷與屬性操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06js經(jīng)驗(yàn)分享 JavaScript反調(diào)試技巧
在這篇文章中,我打算跟大家總結(jié)一下關(guān)于JavaScript反調(diào)試技巧方面的內(nèi)容。值得一提的是,其中有些方法已經(jīng)被網(wǎng)絡(luò)犯罪分子廣泛應(yīng)用到惡意軟件之中了,需要的朋友可以參考下2018-03-03JavaScript獲取當(dāng)前時(shí)間戳5種方法匯總
很多時(shí)候我們都把時(shí)間戳作為id值,下面這篇文章主要給大家介紹了關(guān)于JavaScript獲取當(dāng)前時(shí)間戳的5種方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10