JavaScript私有變量實(shí)例詳解
本文實(shí)例講述了JavaScript私有變量。分享給大家供大家參考,具體如下:
任何在函數(shù)中定義的變量,就是私有變量,因?yàn)檫@些變量在函數(shù)外部是無(wú)法訪問(wèn)到的??偟膩?lái)說(shuō),私有變量包括函數(shù)的參數(shù)、局部變量和在函數(shù)內(nèi)部定義的其他函數(shù)。
function add(num1, num2){
var sum = num1 + num2;
return sum;
}
上面的例子中的 num1, num2, sum 就是函數(shù)的私有變量。
如果在這個(gè)函數(shù)內(nèi)部創(chuàng)建一個(gè)閉包,那么閉包通過(guò)自己的作用域鏈也可以訪問(wèn)這些變量,利用這一點(diǎn),就可以創(chuàng)建用于訪問(wèn)私有變量的公有方法。
有權(quán)訪問(wèn)私有變量和私有函數(shù)的公有方法叫做特權(quán)方法。
1. 構(gòu)造函數(shù)模式
創(chuàng)建特權(quán)方法的方式有兩種,第一種是在構(gòu)造函數(shù)中定義:
function MyObject(){
//私有變量
var privateVariable = 10;
//私有函數(shù)
function privateFunction(){
return false;
}
//特權(quán)方法
this.publicMethod = function(){
privateVariable++;
return privateFunction();
};
}
這里定義的的特權(quán)方法是一個(gè)閉包,所以能夠訪問(wèn)在構(gòu)造函數(shù)中定義的私有變量和私有函數(shù)。在創(chuàng)建 MyObject 實(shí)例后,只能通過(guò)特權(quán)方法來(lái)訪問(wèn)定義的私有變量和函數(shù)。
利用這種技術(shù),可以隱藏那些不能被外部直接修改的數(shù)據(jù):
function Person(name){
this.getName= function () {
return name;
};
this.setName= function (value) {
name=value;
}
}
var person=new Person("deniro");
console.log(person.getName());//deniro
person.setName("lily");
console.log(person.getName());//lily
上面的代碼定義了兩個(gè)特權(quán)方法,它們都可以在函數(shù)外部被調(diào)用,因?yàn)樗鼈兪情]包,所以可以通過(guò)作用域訪問(wèn) name。name 在 Person 的每一個(gè)實(shí)例中都不同,因?yàn)槊看握{(diào)用構(gòu)造函數(shù)都會(huì)重新創(chuàng)建這兩個(gè)方法。
在構(gòu)造函數(shù)中創(chuàng)建特權(quán)方法的缺點(diǎn)是,必須使用構(gòu)造函數(shù)模式來(lái)實(shí)現(xiàn),而這樣做會(huì)在每個(gè)實(shí)例上創(chuàng)建同樣的一組新方法!
2. 靜態(tài)私有變量模式
通過(guò)在私有作用域中定義私有變量和函數(shù),也可以創(chuàng)建特權(quán)方法,基本模式是:
(function(){
//私有變量
var privateVariable = 10;
//私有函數(shù)
function privateFunction(){
return false;
}
//構(gòu)造函數(shù)
MyObject = function(){
};
//公有/特權(quán)方法
MyObject.prototype.publicMethod = function(){
privateVariable++;
return privateFunction();
};
})();
公有方法在原型上定義,使用的原型模式。另外,我們使用的是函數(shù)表達(dá)式來(lái)定義構(gòu)造函數(shù),而且沒(méi)有用 var,這種在初始化時(shí)未經(jīng)聲明的變量,就會(huì)創(chuàng)建一個(gè)全局變量。因此,MyObject 就成了一個(gè)全局變量,能夠在私有作用域之外被訪問(wèn)到。但在嚴(yán)格模式下給未經(jīng)聲明的變量賦值會(huì)導(dǎo)致錯(cuò)誤。
這種方式定義的私有變量和函數(shù)是實(shí)例之間共享的。因?yàn)樘貦?quán)方法是在原型上定義的,因此所有實(shí)例都使用同一個(gè)函數(shù)。又因?yàn)檫@個(gè)特權(quán)方式是一個(gè)閉包,所以它保存著對(duì)包含它的作用域的引用:
(function () {
var name = "";
Person = function (value) {
name = value;
}
Person.prototype.getName = function () {
return name;
};
Person.prototype.setName = function (value) {
name = value;
}
})();
var person1 = new Person("deniro");
console.log(person1.getName());//deniro
person1.setName("lily");
console.log(person1.getName());//lily
var person2 = new Person("Jack");
console.log(person2.getName());//Jack
console.log(person1.getName());//Jack
因此每個(gè)實(shí)例都沒(méi)有自己的私有變量。
注意: 如果作用域鏈較長(zhǎng),可能會(huì)在一定程度上影響查找速度。這正是使用閉包和私有變量的一個(gè)明顯不足。
3. 模塊模式
模塊模式是為單例創(chuàng)建私有變量和特權(quán)方法。單例指的是只有一個(gè)實(shí)例的對(duì)象,按照慣例,JavaScript 是按照對(duì)象字面量的方式來(lái)創(chuàng)建單例對(duì)象的:
var singleton = {
name : value,
method: function(){
//方法代碼
}
}
模塊模式為單例新增了私有變量和特權(quán)方法:
var singleton = function(){
//私有變量
var privateVariable = 10;
//私有函數(shù)
function privateFunction(){
return false;
}
//特權(quán)/公有方法和屬性
return {
publicProperty: true,
publicMethod: function(){
privateVariable++;
return privateFunction();
}
};
}();
模塊模式使用了一個(gè)返回對(duì)象的匿名函數(shù)。在這個(gè)匿名函數(shù)內(nèi)部,首先定義了私有變量和函數(shù),然后將一個(gè)對(duì)象字面量作為函數(shù)的值返回。返回的對(duì)象字面量只包含可以公開(kāi)的屬性和方法。這個(gè)對(duì)象是在匿名函數(shù)內(nèi)部定義的,所以它的公有方法有權(quán)訪問(wèn)私有變量和函數(shù)。這種模式在需要對(duì)單例進(jìn)行某些初始化,同時(shí)又需要維護(hù)其私有變量時(shí)很有用:
var BaseComponent = {};
var application = function () {
//私有變量和函數(shù)
var components = new Array();
//初始化
components.push(new BaseComponent());
//公共
return {
getComponentCount: function () {//返回已注冊(cè)的組件數(shù)
return components.length;
},
registerComponent: function (component) {//注冊(cè)新組件
if (typeof component == "object") {
components.push(component);
}
}
};
}();
在 web 程序中,經(jīng)常需要使用一個(gè)單例來(lái)管理應(yīng)用程序級(jí)的信息。這個(gè)例子創(chuàng)建了一個(gè)用于管理組件的 application 對(duì)象。首先聲明一個(gè)私有 components 數(shù)組,然后為它添加了一個(gè) BaseComponent 實(shí)例(BaseComponent 實(shí)際代碼不重要,這里主要是為了演示初始化),返回的對(duì)象包含有權(quán)訪問(wèn)數(shù)組的特權(quán)方法。
如果創(chuàng)建一個(gè)對(duì)象時(shí),需要對(duì)其進(jìn)行初始化,同時(shí)還要公開(kāi)一些能夠訪問(wèn)這些私有數(shù)據(jù)的方法,那么就可以使用模塊模式。
4. 增強(qiáng)的模塊模式
這種模式適合那些單例必須是某種類型的實(shí)例,同時(shí)還必須添加某些屬性或方法對(duì)其增強(qiáng)的情況:
var singleton = function(){
//私有變量
var privateVariable = 10;
//私有函數(shù)
function privateFunction(){
return false;
}
//創(chuàng)建對(duì)象
var object = new CustomType();
//添加特權(quán)/公有方法和屬性
object.publicProperty = true;
object.publicMethod = function(){
privateVariable++;
return privateFunction();
};
//返回這個(gè)對(duì)象
return object;
}();
我們把之前的例子改成增強(qiáng)的模塊模式:
var BaseComponent = {};
var application = function () {
//私有變量和函數(shù)
var components = new Array();
//初始化
components.push(new BaseComponent());
//創(chuàng)建 application 的一個(gè)局部副本
var app = new BaseComponent();
//公共接口
app.getComponentCount = function () {
return components.length;
};
app.registerComponent = function (component) {
if (typeof component == "object") {
components.push(component);
}
};
//返回這個(gè)副本
return app;
}();
更多關(guān)于JavaScript相關(guān)內(nèi)容還可查看本站專題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
相關(guān)文章
JS獲取scrollHeight問(wèn)題想到的標(biāo)準(zhǔn)問(wèn)題
如果沒(méi)有文檔聲明可以用 document.body.scrollHeight,如果有文檔聲明必須用 document.documentElement.scrollHeight關(guān)于這方面的東西2007-05-05
Ionic2系列之使用DeepLinker實(shí)現(xiàn)指定頁(yè)面URL
這篇文章主要介紹了Ionic2系列之使用DeepLinker實(shí)現(xiàn)指定頁(yè)面URL的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
JavaScript進(jìn)階練習(xí)及簡(jiǎn)單實(shí)例分析
下面小編就為大家?guī)?lái)一篇JavaScript進(jìn)階練習(xí)及簡(jiǎn)單實(shí)例分析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06
鼠標(biāo)滑過(guò)出現(xiàn)預(yù)覽的大圖提示效果
這篇文章主要介紹了如何實(shí)現(xiàn)鼠標(biāo)滑過(guò)出現(xiàn)預(yù)覽的大圖提示效果,需要的朋友可以參考下2014-02-02
JavaScript forEach的幾種用法小結(jié)
forEach()是JavaScript中一個(gè)常用的方法,用于遍歷數(shù)組或類數(shù)組對(duì)象中的每個(gè)元素,本文就來(lái)介紹一下JavaScript forEach的幾種用法小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
微信小程序?qū)崿F(xiàn)一個(gè)自定義遮罩層效果
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)一個(gè)自定義遮罩層,大概效果是點(diǎn)擊按鈕Show顯示遮罩層,再次點(diǎn)擊屏幕任何地方隱藏遮罩層,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09

