我正在使用 Lightbox2
https://github.com/lokesh/lightbox2/blob/master/js/lightbox.js
而且我不明白为什么Lightbox的所有内部成员都是原型(Lightbox.prototype.init
)而不是简单的成员(Lightbox.init
)?
如果它们特定于灯箱的每个实例,使用起来会不会更容易this.init
?
我正在使用 Lightbox2
https://github.com/lokesh/lightbox2/blob/master/js/lightbox.js
而且我不明白为什么Lightbox的所有内部成员都是原型(Lightbox.prototype.init
)而不是简单的成员(Lightbox.init
)?
如果它们特定于灯箱的每个实例,使用起来会不会更容易this.init
?
这样想:
Lightbox 是您的类定义,但它还不是一个实例。
你直接放在类上的任何东西都像一个静态成员:
Lightbox.staticFunc = function() {
// "this" will not point to instance object
};
无论您在其原型上放置什么都是共享实例成员:
Lightbox.prototype.instanceFunc = function() {
// "this" will point to object instance so members can be accessed
};
当你创建一个类的实例时,所有的实例成员都可以通过 tthis
关键字访问,但静态成员可以通过类定义来访问:
var someData = Lightbox.staticFunc();
var l = new Lightbox();
l.instanceFunc();
这是否清楚你对原型成员的理解?
您一直在查看的代码意味着:
// this is a constructor that accesses instance properties (using "this")
// ------
// since properties are accessed via "this.something" means that they are
// not shared between instances but are part of one particular instance
// ------
function Lightbox(options) {
this.options = options;
this.album = [];
this.currentImageIndex = void 0;
this.init();
}
// adding an instance method that will be accessible to lightbox object instance
// that's why it can also access instance members (using "this")
// ------
// all functions that are defined on the prototype are shared between
// all instances so they consume less resources because not every
// object instance created them separately.
// ------
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";
};
当然可以在构造函数中定义这些函数 usingthis
但是它们不会在实例之间共享,因此每个对象实例都将定义相同的函数,从而消耗更多资源。所以这是不一样的,尽管从执行点来看它看起来是一样的:
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();
你认为输出会是什么?你至少应该有点困惑之后会发生什么delete
?哪个方法会被删除?每个实例?共享?两个都?好吧,应该在对象实例上删除每个实例方法a
,这就是为什么之后它报告共享方法已被调用的原因。但仅在a
. b
仍然有自己的每个实例方法。
因此,事不宜迟,输出如下所示:
Per instance method // a.method
Per instance method // b.method
Shared instance method // a.method
Per instance method // b.method
prototype
属性呢这些是不同的。当您创建一个对象实例时,所有这些属性都会被复制到每个对象并且不会共享。因此,无论您在特定对象的范围内对它们做什么,都不会反映给其他人。
如果您随后删除特定对象上的此类属性,它的初始值仍然可用,就像对象被实例化时一样。
var C = new function() {};
C.prototype.prop = 1;
var a = new C();
var b = new C();
a.prop = 10; // does not change the value of "b.prop"
delete a.prop; // "a.prop" is now back to 1
如果它们特定于灯箱的每个实例,使用 this.init 会不会更容易?
他们不应该这就是为什么他们将一切都放在prototype
对象中。当您使用 时prototype
,所有方法仍然对您可用,只是它们不会成为实例成员。
JavaScript 使用原型链,当它看到一个方法时,它会在原型链中搜索,直到找到指定的方法。Object
如果在中间没有找到,这个过程会一直持续到最终的对象。
您应该只创建您认为合理或需要的实例成员(通过),因为如果您使用关键字(例如实例成员this
)放置不必要的方法,它会增加开销(计算浪费) 。this