摘要:使用閉包遇到的陷阱一陷阱在類的原型對象中添加特權(quán)方法首先定義一個類,該類中有一個私有變量定義個特權(quán)方法來訪問修改私有變量然后我們對類進(jìn)行測試到目前為止,類正常工作。
使用JavaScript閉包遇到的陷阱(一) 陷阱:在類的原型對象中添加特權(quán)方法
首先定義一個Page類,該類中有一個私有變量dom:
function Page(){ var dom; }
定義2個特權(quán)方法來訪問、修改私有變量dom:
function Page(){ var dom; this.setDom=function(newDom){ dom=newDom; }; this.getDom=function(){ return dom; } }
然后我們對Page類進(jìn)行測試:
var page1=new Page(); page1.setDom("page1"); console.log(page1.getDom());//page1var page2=new Page(); page2.setDom("page2"); console.log(page2.getDom());//page2console.log(page1.getDom());//page1到目前為止,Page類正常工作。
這時問題來了:我想每個Page類的對象都有相同的特權(quán)方法,那就將這兩個特權(quán)方法添加到Page的原型對象中好了。function Page(){ var dom; if(this.__proto__.setDom !== "function"){ this.__proto__.setDom=function(newDom){ dom=newDom; }; this.__proto__.getDom=function(){ return dom; }; } }對修改后的Page類進(jìn)行測試:
var page1=new Page(); page1.setDom("page1"); console.log(page1.getDom());//page1var page2=new Page(); page2.setDom("page2"); console.log(page2.getDom());//page2/* 注意!問題出現(xiàn)了! */ console.log(page1.getDom());//page2這時最后一行的console.log(page1.getDom())打印的結(jié)果變成了
page2探究 前提在使用new操作符調(diào)用Page構(gòu)造函數(shù)創(chuàng)建對象的過程:先創(chuàng)建一個Page類的空對象,并將構(gòu)造函數(shù)中的this指向該對象,再執(zhí)行構(gòu)造函數(shù)。
在函數(shù)中定義的變量都保存在該函數(shù)執(zhí)行環(huán)境的變量對象中。
每個函數(shù)都有一個作用域鏈。函數(shù)在定義時,就會生成不完整的作用域鏈,該作用域的前端是函數(shù)定義時所在環(huán)境的變量對象。函數(shù)在執(zhí)行時,會創(chuàng)建該函數(shù)的執(zhí)行環(huán)境,并將該執(zhí)行環(huán)境的活動對象(這里可理解為變量對象)添加到之前創(chuàng)建的作用域鏈的前端,此時的作用域鏈?zhǔn)峭暾淖饔糜蜴湣?/p>
變量訪問的過程就是從作用域鏈家前端沿著作用域鏈查找變量的過程。
分析Page類的構(gòu)造函數(shù)使用動態(tài)原型的方式來給原型對象添加方法。因此在創(chuàng)建第一個Page實例時,調(diào)用Page函數(shù)創(chuàng)建執(zhí)行環(huán)境a,這時,會在a中定義setDom和getDom方法并添加到Page類的原型對象中。原型對象中的setDom和getDom方法的作用域鏈前端都是執(zhí)行環(huán)境a(準(zhǔn)確的說是a對應(yīng)的變量對象)。
創(chuàng)建第一個Page實例時,給Page類的原型對象添加了setDom和getDom方法。之后再創(chuàng)建其他的Page實例時,都不會再修改原型對象中的setDom和getDom方法了。
在創(chuàng)建第二個Page實例時,再次調(diào)用Page函數(shù),創(chuàng)建了執(zhí)行環(huán)境b。
在調(diào)用Page實例的setDom或getDom方法時,由于都是調(diào)用原型對象中的方法。而根據(jù)之前說的,原型對象中的setDom方法和getDom方法在訪問dom變量的時候,都要沿著作用域鏈查找,最后找到的是環(huán)境a中的變量dom,也就是第一個Page實例的私有變量dom。
所以在測試的時候,無論是page1還是page2調(diào)用setDom和getDom方法,都是修改或訪問page1中的私有變量dom。
小結(jié)在類的原型對象中添加的特權(quán)方法,不能用來訪問或操作類的私有變量,只能用來訪問或操作this修飾的特權(quán)變量。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79462.html
相關(guān)文章
JavaScript深入淺出
摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統(tǒng)的類繼承還要強大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...
新鮮出爐的8月前端面試題
摘要:前言最近參加了幾場面試,積累了一些高頻面試題,我把面試題分為兩類,一種是基礎(chǔ)試題主要考察前端技基礎(chǔ)是否扎實,是否能夠?qū)⑶岸酥R體系串聯(lián)。 前言 最近參加了幾場面試,積累了一些高頻面試題,我把面試題分為兩類,一種是基礎(chǔ)試題: 主要考察前端技基礎(chǔ)是否扎實,是否能夠?qū)⑶岸酥R體系串聯(lián)。一種是開放式問題: 考察業(yè)務(wù)積累,是否有自己的思考,思考問題的方式,這類問題沒有標(biāo)準(zhǔn)答案。 基礎(chǔ)題 題目的答...
前端面試題收集,持續(xù)更新中
摘要:對于所訪問的每個元素,函數(shù)應(yīng)該將該元素傳遞給所提供的回調(diào)函數(shù)。 HTML 在線閱讀Github地址 題目列表 HTML HTML和XHTML的區(qū)別 Html的語義化 Doctype的文檔類型 cookie、sessionSttorage、localStory區(qū)別 HTML全局屬性(global attribute)有哪些? 常見的瀏覽器內(nèi)核有哪些? 介紹一下你對瀏覽器內(nèi)核的理解?...
前端面試題收集,持續(xù)更新中
摘要:對于所訪問的每個元素,函數(shù)應(yīng)該將該元素傳遞給所提供的回調(diào)函數(shù)。 HTML 在線閱讀Github地址 題目列表 HTML HTML和XHTML的區(qū)別 Html的語義化 Doctype的文檔類型 cookie、sessionSttorage、localStory區(qū)別 HTML全局屬性(global attribute)有哪些? 常見的瀏覽器內(nèi)核有哪些? 介紹一下你對瀏覽器內(nèi)核的理解?...
前端面試題收集,持續(xù)更新中
摘要:對于所訪問的每個元素,函數(shù)應(yīng)該將該元素傳遞給所提供的回調(diào)函數(shù)。 HTML 在線閱讀Github地址 題目列表 HTML HTML和XHTML的區(qū)別 Html的語義化 Doctype的文檔類型 cookie、sessionSttorage、localStory區(qū)別 HTML全局屬性(global attribute)有哪些? 常見的瀏覽器內(nèi)核有哪些? 介紹一下你對瀏覽器內(nèi)核的理解?...
發(fā)表評論
0條評論
caohaoyu
男|高級講師
TA的文章
閱讀更多
CloudCone:便宜VPS年付$17.99起,洛杉磯MC機房,優(yōu)化線路
閱讀 3027·2021-10-08 10:18
前端每日實戰(zhàn):143# 視頻演示如何用 CSS 的 Grid 布局創(chuàng)作一枚小松鼠郵票
閱讀 743·2019-08-30 15:54
CSS垂直居中,你會多少種寫法?
閱讀 1073·2019-08-29 18:43
Codepen 每周精選:本周最值得推薦的 23 個頁面特效(2018-5-28)
閱讀 2452·2019-08-29 15:33
前端基礎(chǔ)之CSS(1)
閱讀 1312·2019-08-29 15:29
javascript 理解和使用回調(diào)函數(shù)
閱讀 1613·2019-08-29 13:29
一個奇葩問題引發(fā)的"吐血"
閱讀 1033·2019-08-26 13:46
高級 Angular 組件模式 (6)
閱讀 1709·2019-08-26 11:55
閱讀需要支付1元查看