gpt4 book ai didi

javascript - 使用 `prototype` 而不是 `this` 的原因

转载 作者:数据小太阳 更新时间:2023-10-29 05:04:31 26 4
gpt4 key购买 nike

我正在使用 Lightbox2

https://github.com/lokesh/lightbox2/blob/master/js/lightbox.js

而且我不明白为什么 Lightbox 的所有内部成员都是原型(prototype) (Lightbox.prototype.init) 而不是简单的成员 (Lightbox.init)?

如果它们特定于 lightbox 的每个实例,使用 this.init 不是更容易吗?

最佳答案

困惑?不要...

这样想:

  1. Lightbox 是您的类定义,但它还不是一个实例。

  2. 任何你直接放在类上的东西都像一个静态成员:

    Lightbox.staticFunc = function() {
    // "this" will not point to instance object
    };
  3. 无论你在其原型(prototype)上放置什么,都是共享实例成员:

    Lightbox.prototype.instanceFunc = function() {
    // "this" will point to object instance so members can be accessed
    };
  4. 当您创建一个类的实例时,所有实例成员都可以通过 this 关键字访问,但静态成员可以通过类定义访问:

    var someData = Lightbox.staticFunc();
    var l = new Lightbox();
    l.instanceFunc();

这是否清楚您对原型(prototype)成员的理解?

然后是灯箱代码

您一直在查看的代码意味着:

// 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 类包含在一个函数闭包中,即使它没有定义任何私有(private)数据,因此在此示例中可以省略外部立即执行函数,同时具有相同的结果:

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();

你认为输出会是什么?您至少应该对 delete 之后发生的事情感到困惑?哪种方法会被删除?每个实例?共享?两个都?好吧,每个实例方法都应该在对象实例 a 上被删除,这就是为什么之后它报告已调用共享方法的原因。但仅限于 ab 仍然有自己的 per instance 方法。

所以事不宜迟,输出如下所示:

Per instance method      // a.method
Per instance method // b.method
Shared instance method // a.method
Per instance method // b.method

prototype 属性呢

这些是不同的。当您创建一个对象实例时,所有这些属性都会被复制到每个对象并且不会共享。因此,无论您在特定对象的范围内对它们做什么,都不会反射(reflect)到其他人身上。

如果您随后删除特定对象上的此类属性,它仍然可以使用其初始值,就像对象被实例化时一样。

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

关于javascript - 使用 `prototype` 而不是 `this` 的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10960205/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com