"codetitle">复制代码 代码如下:
(function () {
for (var i = 0; i < 10; i++) {
//Do Nothing
}
alert(i); //输出10
})();
第6行可以访问到for循环块中的变量i,如果我们稍微修改以上代码,把for循环块放置在闭包中,情况就不一样了:
复制代码 代码如下:
(function () {
(function () {
for (var i = 0; i < 10; i++) {
//Do Nothing
}
})();
alert(i); //Error: 'i' is undefined
})();
在第8行访问变了i时,出现错误,实现了我们想要的块级作用域。
"codetitle">复制代码 代码如下:
//实例私有变量
function MyObject(name) {
//定义私有变量
//注意:此处没有用this.name,如果使用this.name变成公共属性了
var privateName = name;
//定义私有熟悉
var privateFunction = function () {
return "Private Function";
}
//公共方法访问私有熟悉
MyObject.prototype.getName = function () {
return privateName;
}
MyObject.prototype.getFunction = function () {
return privateFunction();
}
}
var moGyy = new MyObject("gyy");
alert(moGyy.getName()); //输出gyy
alert(moGyy.getFunction()); //输出Private Function
var moCyy = new MyObject("cyy");
alert(moCyy.getName()); //输出cyy
alert(moCyy.getFunction()); //输出Private Function
在上面的示例中创建的两个对象moGyy和moCyy的getName返回不同的值,同时如果想调用私有方法同样也需要公共接口。上面的示例中两个公共函数之所以能访问私有变量,是因为两个公共函数都是闭包,而闭包的作用域链中包含了包含函数的变量对象,因此在进行变量查找时,顺着作用域链可以访问包含函数中的私有变量。在上面的示例中把公共方法添加到MyObject的原型中,目的是防止每次创建对象都创建功能一样的两个函数实例。
<2>.静态私有属性
在有些情况下我们可能希望数据全局共享,那么可能就会用到静态属性,我们还是希望这个属性为私有的,那么怎样实现静态私有属性呢?首先这个私有应该在构造函数的外部,为了把构造函数外部的变量和构造函数结合为一体,可以使用闭包把私有变量和构造函数都包含在其作用域中,为了在闭包外面访问内部的构造函数,可以使用一个全局的变量来引用构造函数,如下代码示例:
复制代码 代码如下:
//静态私有变量和实例私有变量
(function () {
//定义私有变量
var staticPrivateValue = "";
//构造函数,把构织函数赋值给一个全局的变量
MyObject = function (name) {
//定义实例变量
this.name = name;
};
//定义两个公共方法用于访问私有变量,再一次把公共方法添加到原型中
MyObject.prototype.getPrivateValue = function () {
return staticPrivateValue;
}
MyObject.prototype.setPrivateValue = function (value) {
staticPrivateValue = value;
}
})();
var mo = new MyObject("jeff-gyy");
mo.setPrivateValue("gyycyy"); //设置私有属性的值
alert(mo.getPrivateValue()); //输出gyycyy
alert(mo.name); //输出jeff-gyy
var mo1 = new MyObject("jeff-cyy");
alert(mo1.getPrivateValue()); //输出gyycyy
alert(mo1.name); //输出jeff-cyy
从上面的代码来看mo1调用getPrivateValue函数返回的值就是mo设置的值"gyycyy",为什么会这样呢?首先我们定义了一个匿名函数并立即调用函数,函数包含了私有变量staticPrivateValue,那么为MyObject定义的两个原型方法其实通过闭包的作用域链可以访问在包含函数的私有变量,也就是getPrivateValue和setPrivateValue两个函数的作用域链中都包含了匿名函数的变量对象,我们知道作用域链中包含的变量对象其实就是一个指针,所以创建的两个对象通过公共方法房屋私有变量时,其实访问的都是匿名函数的变量对象中的staticPrivateValue,因此实现变量实例间共享的目的。从传统OO语言的角度来看我们实现的静态属性其实并不是真正意义上的静态,只是实现了静态属性实例共享的特点。
<3>.模块模式和增强模块模式
还有一种全局共享数据的方式就是singleton, 可以使用模块模式来实现Object类型的单例模式,也可以使用增强模块模式实现自定义类型的单例模式,如下示例:
复制代码 代码如下:
//自定义构造函数
var mo = new function () {
//私有变量
var privateValue = "";
//普通模块模式
return {
publicValue: "public",
//访问私有变量
getPrivateValue: function () {
return privateValue;
},
setPrivateValue: function (value) {
privateValue = value;
}
}
}();
mo.setPrivateValue("private value");
alert(mo.getPrivateValue());
alert(mo.publicFunction());
模块模式使用匿名函数来封装内部实现,就上面的示例匿名函数中包含了私有变量privateValue,返回的对象中的公共函数通过闭包的作用域链访问包含函数中的私有变量,由于定义的匿名函数被立即调用,因此变量mo引用的是返回的对象。上面的单例模式返回的是一个Object对象,可以使用增强模块模式实现自定义类型的单例模式:
复制代码 代码如下:
//增强模块模式
//自定义构造函数
function MyObject(name) {
this.name = name;
};
//自定义构造函数
var mo = new function () {
//私有变量
var privateValue = "";
//增强模块模式
var o = new MyObject("gyycyy");
o.publicValue = "public";
//访问私有变量
o.getPrivateValue = function () {
return privateValue;
}
o.setPrivateValue = function (value) {
privateValue = value;
}
return o;
}();
mo.setPrivateValue("private value");
alert(mo.getPrivateValue());
alert(mo.publicFunction());
以上代码示例实现了MyObject的单例模式。
最后需要提一点的是使用闭包有利也有弊,由于闭包作用域链引用包含函数的变量对象,因此会占用额外的内存,而且进行变量查找是也需要通过作用域链,因此会消耗查找时间,闭包越深情况更严重。另外在IE(早些版本)中由于垃圾回收机制使用引用计数,因此可能会出现循环引用的情况,导致内存泄露,如下示例:
复制代码 代码如下:
function assignHandler(){
var element = document.getElementById("someElement");
element.onclick = function(){
alert(element.id);
};
}
在上面的代码中创建了一个闭包作为element的事件,该闭包引用了包含函数assingHandler的变量对象,而恰恰是对变量对象的引用使得element引用计数至少为1,因此element不会被回收,导致内存泄露。修改的方法大家可以想想。
(function () {
for (var i = 0; i < 10; i++) {
//Do Nothing
}
alert(i); //输出10
})();
第6行可以访问到for循环块中的变量i,如果我们稍微修改以上代码,把for循环块放置在闭包中,情况就不一样了:
复制代码 代码如下:
(function () {
(function () {
for (var i = 0; i < 10; i++) {
//Do Nothing
}
})();
alert(i); //Error: 'i' is undefined
})();
在第8行访问变了i时,出现错误,实现了我们想要的块级作用域。
"codetitle">复制代码 代码如下:
//实例私有变量
function MyObject(name) {
//定义私有变量
//注意:此处没有用this.name,如果使用this.name变成公共属性了
var privateName = name;
//定义私有熟悉
var privateFunction = function () {
return "Private Function";
}
//公共方法访问私有熟悉
MyObject.prototype.getName = function () {
return privateName;
}
MyObject.prototype.getFunction = function () {
return privateFunction();
}
}
var moGyy = new MyObject("gyy");
alert(moGyy.getName()); //输出gyy
alert(moGyy.getFunction()); //输出Private Function
var moCyy = new MyObject("cyy");
alert(moCyy.getName()); //输出cyy
alert(moCyy.getFunction()); //输出Private Function
在上面的示例中创建的两个对象moGyy和moCyy的getName返回不同的值,同时如果想调用私有方法同样也需要公共接口。上面的示例中两个公共函数之所以能访问私有变量,是因为两个公共函数都是闭包,而闭包的作用域链中包含了包含函数的变量对象,因此在进行变量查找时,顺着作用域链可以访问包含函数中的私有变量。在上面的示例中把公共方法添加到MyObject的原型中,目的是防止每次创建对象都创建功能一样的两个函数实例。
<2>.静态私有属性
在有些情况下我们可能希望数据全局共享,那么可能就会用到静态属性,我们还是希望这个属性为私有的,那么怎样实现静态私有属性呢?首先这个私有应该在构造函数的外部,为了把构造函数外部的变量和构造函数结合为一体,可以使用闭包把私有变量和构造函数都包含在其作用域中,为了在闭包外面访问内部的构造函数,可以使用一个全局的变量来引用构造函数,如下代码示例:
复制代码 代码如下:
//静态私有变量和实例私有变量
(function () {
//定义私有变量
var staticPrivateValue = "";
//构造函数,把构织函数赋值给一个全局的变量
MyObject = function (name) {
//定义实例变量
this.name = name;
};
//定义两个公共方法用于访问私有变量,再一次把公共方法添加到原型中
MyObject.prototype.getPrivateValue = function () {
return staticPrivateValue;
}
MyObject.prototype.setPrivateValue = function (value) {
staticPrivateValue = value;
}
})();
var mo = new MyObject("jeff-gyy");
mo.setPrivateValue("gyycyy"); //设置私有属性的值
alert(mo.getPrivateValue()); //输出gyycyy
alert(mo.name); //输出jeff-gyy
var mo1 = new MyObject("jeff-cyy");
alert(mo1.getPrivateValue()); //输出gyycyy
alert(mo1.name); //输出jeff-cyy
从上面的代码来看mo1调用getPrivateValue函数返回的值就是mo设置的值"gyycyy",为什么会这样呢?首先我们定义了一个匿名函数并立即调用函数,函数包含了私有变量staticPrivateValue,那么为MyObject定义的两个原型方法其实通过闭包的作用域链可以访问在包含函数的私有变量,也就是getPrivateValue和setPrivateValue两个函数的作用域链中都包含了匿名函数的变量对象,我们知道作用域链中包含的变量对象其实就是一个指针,所以创建的两个对象通过公共方法房屋私有变量时,其实访问的都是匿名函数的变量对象中的staticPrivateValue,因此实现变量实例间共享的目的。从传统OO语言的角度来看我们实现的静态属性其实并不是真正意义上的静态,只是实现了静态属性实例共享的特点。
<3>.模块模式和增强模块模式
还有一种全局共享数据的方式就是singleton, 可以使用模块模式来实现Object类型的单例模式,也可以使用增强模块模式实现自定义类型的单例模式,如下示例:
复制代码 代码如下:
//自定义构造函数
var mo = new function () {
//私有变量
var privateValue = "";
//普通模块模式
return {
publicValue: "public",
//访问私有变量
getPrivateValue: function () {
return privateValue;
},
setPrivateValue: function (value) {
privateValue = value;
}
}
}();
mo.setPrivateValue("private value");
alert(mo.getPrivateValue());
alert(mo.publicFunction());
模块模式使用匿名函数来封装内部实现,就上面的示例匿名函数中包含了私有变量privateValue,返回的对象中的公共函数通过闭包的作用域链访问包含函数中的私有变量,由于定义的匿名函数被立即调用,因此变量mo引用的是返回的对象。上面的单例模式返回的是一个Object对象,可以使用增强模块模式实现自定义类型的单例模式:
复制代码 代码如下:
//增强模块模式
//自定义构造函数
function MyObject(name) {
this.name = name;
};
//自定义构造函数
var mo = new function () {
//私有变量
var privateValue = "";
//增强模块模式
var o = new MyObject("gyycyy");
o.publicValue = "public";
//访问私有变量
o.getPrivateValue = function () {
return privateValue;
}
o.setPrivateValue = function (value) {
privateValue = value;
}
return o;
}();
mo.setPrivateValue("private value");
alert(mo.getPrivateValue());
alert(mo.publicFunction());
以上代码示例实现了MyObject的单例模式。
最后需要提一点的是使用闭包有利也有弊,由于闭包作用域链引用包含函数的变量对象,因此会占用额外的内存,而且进行变量查找是也需要通过作用域链,因此会消耗查找时间,闭包越深情况更严重。另外在IE(早些版本)中由于垃圾回收机制使用引用计数,因此可能会出现循环引用的情况,导致内存泄露,如下示例:
复制代码 代码如下:
function assignHandler(){
var element = document.getElementById("someElement");
element.onclick = function(){
alert(element.id);
};
}
在上面的代码中创建了一个闭包作为element的事件,该闭包引用了包含函数assingHandler的变量对象,而恰恰是对变量对象的引用使得element引用计数至少为1,因此element不会被回收,导致内存泄露。修改的方法大家可以想想。
标签:
私有属性,静态属性
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
桃源资源网 Design By www.nqtax.com
暂无“JavaScript中的私有/静态属性介绍”评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。