困惑?不要紧...
可以这样理解:
Lightbox is your class definition, but it's not yet an instance.
Whatever you put directly on the class is like a static member:
Lightbox.staticFunc = function() {
};
Whatever you put on its prototype is a shared instance member:
Lightbox.prototype.instanceFunc = function() {
};
When you create an instance of a class, all instance members are accessible throught this
keyword, but static ones through class definition:
var someData = Lightbox.staticFunc();
var l = new Lightbox();
l.instanceFunc();
这是否使您对原型成员有了更清晰的理解?
然后是Lightbox代码
您一直在查看的代码意味着:
function Lightbox(options) {
this.options = options;
this.album = [];
this.currentImageIndex = void 0;
this.init();
}
Lightbox.prototype.init = function() {
this.enable();
return this.build();
};
但是这段代码的某些部分有点令人困惑,例如:
LightboxOptions = (function() {
function LightboxOptions() {
this.fileLoadingImage = 'images/loading.gif';
this.fileCloseImage = 'images/close.png';
this.resizeDuration = 700;
this.fadeDuration = 500;
this.labelImage = "Image";
this.labelOf = "of";
}
return LightboxOptions;
})();
LightboxOptions
类虽然没有定义任何私有数据,但它仍包含在函数闭包中。所以,在这个例子中,外部立即执行的函数可以省略而产生相同的结果:
LightboxOptions = function() {
this.fileLoadingImage = 'images/loading.gif';
this.fileCloseImage = 'images/close.png';
this.resizeDuration = 700;
this.fadeDuration = 500;
this.labelImage = "Image";
this.labelOf = "of";
};
当然可以在构造函数中使用this
来定义这些函数,但是这样它们就不会在实例之间共享,因此每个对象实例都会定义相同的函数,从而消耗更多的资源。因此,尽管从执行点看起来相同,但这并不相同:
CustomClass = function() {
this.prop = true;
};
CustomClass.prototype.method = function() { alert("I'm shared."); };
与“稍有不同”:
CustomClass = function() {
this.prop = true;
this.method = function() { alert("I'm duplicated in every instance."); };
};
后一种方法会消耗更多的资源,因为每个对象实例都要定义一个函数。
...还有一些内容需要完全理解这件事
假设我们有以下类定义:
var C = function() {
this.prop = true;
this.method = function() { console.log("Per instance method"); };
}
C.prototype.method = function() { console.log("Shared instance method"); };
如果我们调用这些代码行,会发生什么?
var a = new C();
var b = new C();
a.method();
b.method();
delete a.method;
a.method();
b.method();
你认为输出结果会是什么?在删除之后会发生什么,你应该有点困惑。哪个方法将被删除?每个实例吗?共享的吗?嗯,按照应该是每个实例的方法将在对象实例a上被删除,这就是为什么之后它报告共享方法已被调用但只在a上。b仍然有自己的每个实例方法。
因此,不再拖延,输出结果如下:
Per instance method // a.method
Per instance method // b.method
Shared instance method // a.method
Per instance method // b.method
原型属性怎么办
原型属性与众不同。当您创建一个对象实例时,所有这些属性都会被复制到每个对象中,并且不共享。因此,在特定对象的范围内对它们进行的任何操作都不会反映到其他对象上。
如果您在特定对象上删除这样的属性,它仍将以初始值的形式可用,就像在对象实例化时一样。
var C = new function() {};
C.prototype.prop = 1;
var a = new C();
var b = new C();
a.prop = 10;
delete a.prop;
this
不同,并且明显不同于将方法分配给构造函数。仅在构造函数内部将实例特定数据分配给this
。应共享的数据分配给原型。 - Felix Klingthis
和prototype
之间的一般区别。但我不明白在这种情况下使用prototype
有什么作用。 - ilyo.init()
应该在所有实例之间共享,因此它被分配给prototype
。将其分配给Lightbox
是没有意义的,因为实例不会继承这些方法。在构造函数内部将其分配给this
是可能的,但是每个实例都有自己的方法副本,这会增加内存使用量。当然,每个通用的理由都更适用于特定情况下的prototype
而不是this
。在某些情况下选择它并不需要额外的理由。 - Felix Kling