Javascript”;私人的“;与实例属性相比
Javascript "private" vs. instance properties
我正在做一些Javascript R&D,虽然我已经阅读了Javascript:TheDefinitiveGuide和Java脚本面向对象编程,但我仍然有一些小问题,让我的头脑从基于类的OOP转向词汇的、基于对象的OOP。
我喜欢模块。命名空间、子类和接口。w00t。以下是我正在玩的游戏:
var Classes = {
_proto : {
whatAreYou : function(){
return this.name;
}
},
Globe : function(){
this.name = "Globe"
},
Umbrella : new function(){
this.name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
this.name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
this.name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
我试图找到最好的方法来模块化我的代码(并理解原型),并将所有东西分离出来。注意,Globe
是一个需要用new
实例化的函数,Umbrella
是一个单例函数,并且已经声明,Igloo
使用了我今天在工作中想到的东西,并且似乎像我希望的那样工作,而House
是另一个用于测试的Igloosque函数。
其输出为:
Globe
unavailable
Igloo
My House
到目前为止还不错。由于语法原因,Globe原型必须在Classes对象之外声明,Umbrella不能接受,因为它已经存在(或者实例化了,或者……不知道这个"正确"的术语),Igloo有一些闭包可以为您声明它。
然而。。。
如果我把它改成:
var Classes = {
_proto : {
whatAreYou : function(){
return _name;
}
},
Globe : function(){
_name = "Globe"
},
Umbrella : new function(){
_name = "Umbrella"
}(),
Igloo : function(){
function Igloo(madeOf){
_name = "Igloo"
_material = madeOf;
}
// Igloo specific
Igloo.prototype = {
getMaterial : function(){
return _material;
}
}
// the rest
for(var p in Classes._proto){
Igloo.prototype[p] = Classes._proto[p]
}
return new Igloo(arguments[0]);
},
House : function(){
function House(){
_name = "My House"
}
House.prototype = Classes._proto
return new House()
}
}
Classes.Globe.prototype = Classes._proto
Classes.Umbrella.prototype = Classes._proto
$(document).ready(function(){
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
var objects = [globe, umb, igloo, house]
for(var i = 0, len = objects.length; i < len; i++){
var me = objects[i];
if("whatAreYou" in me){
console.log(me.whatAreYou())
}else{
console.warn("unavailable")
}
}
})
并将this.name
转换为_name
("私有"属性),它不起作用,而是输出:
My House
unavailable
My House
My House
有人能解释一下吗?显然,_name
在每次迭代时都被覆盖,并且没有读取它所附加的对象的属性。
这一切似乎有点过于冗长,需要this
和有点奇怪的IMO.
感谢:)
您声明了一个全局变量。声明后,它可以从代码中的任何位置获得。无论您在哪里向_name
(更接近window._name
)提出请求,您每次都会收到一个全局消息。在您的案例中,每个函数中都替换了_name。最后一个功能是House,已经设置为"My House"
"私有"(局部)变量的声明必须使用var
语句。
看看这个:
var foo = function( a ) {
_bar = a;
this.showBar = function() {
console.log( _bar );
}
};
var a = new foo(4); // _bar ( ie window._bar) is set to 4
a.showBar(); //4
var b = new foo(1); // _bar is set to 1
a.showBar(); //1
b.showBar(); //1
_bar = 5; // window._bar = 5;
a.showBar();// 5
应为:
var foo = function( a ) {
var _bar = a;
// _bar is now visibled only from both that function
// and functions that will create or delegate from this function,
this.showBar = function() {
console.log( _bar );
};
this.setBar = function( val ) {
_bar = val;
};
this.delegateShowBar = function() {
return function( ) {
console.log( _bar );
}
}
};
foo.prototype.whatever = function( ){
//Remember - here don't have access to _bar
};
var a = new foo(4);
a.showBar(); //4
_bar // ReferenceError: _bar is not defined :)
var b = new foo(1);
a.showBar(); //4
b.showBar(); //1
delegatedShowBar = a.delegateShowBar();
a.setBar(6);
a.showBar();//6
delegatedShowBar(); // 6
如果删除关键字"this",则_name在"Globe"范围内。
查看您的代码。
var globe, umb, igloo, house;
globe = new Classes.Globe();
umb = Classes.Umbrella;
igloo = new Classes.Igloo("Ice");
house = new Classes.House();
最后,房子将以"我的房子"的名称覆盖全球范围内的"_name"值。
- Backbone.Model.extend不创建实例属性
- 在定义了构造函数之后,是否可以将实例属性添加到JavaScript原型中
- 从原型方法更改实例属性
- 在 IIFE 中使用实例属性
- 在 ES6 中,允许解构类实例属性
- 在 ES6 中自动将参数设置为实例属性
- 将实例属性放置在原型构造函数中,无论好坏
- JS:原型-访问正确的实例属性
- 我可以在Silverlight中的Scriptable Member属性上设置Javascript中的实例属性吗
- 实例属性会模糊原型链吗
- mixin中的prototype.js实例属性
- 为什么不应该't我直接访问实例属性进行写操作
- Javascript”;私人的“;与实例属性相比
- 为什么在原型中声明实例属性而不是在构造函数中声明
- 如何用原型函数更新实例属性,并从另一个函数访问它
- 新的骨干实例属性指向旧的实例属性
- 在实例方法中获取对实例属性的访问权
- ES6类/实例属性
- 为什么赋值影响实例属性而不是原型属性?
- 在Coffee Script中理解类扩展和实例属性