JavaScript继承问题

发布于 2024-10-15 06:11:24 字数 931 浏览 7 评论 0原文

这是《Pro JavaScript Design Patterns》一书中的扩展函数,

function extend(subClass, superClass) {
    var F = function() {};
    F.prototype = superClass.prototype;
    subClass.prototype = new F();
    subClass.prototype.constructor = subClass;
    subClass.superclass = superClass.prototype;
    if(superClass.prototype.constructor == Object.prototype.constructor) {
       superClass.prototype.constructor = superClass;
    }
}

我对前 3 行有问题...它创建一个空函数,然后将 F.prototype 设置为 superClass.prototype,这意味着(对于 2 个新的构造函数例如 foo、bar 和 foo 扩展 bar),F.prototype 将有一个构造函数属性: bar 和 proto :Object,或者不是? 第 3 行: subClass.prototype = new F();发生了一些我无法理解的事情。为什么当 F 的 [[Prototype]] 是 Object 时继承发生在这里?


有什么区别

subClass.prototype = new superClass();

前3行和代码执行时 ?我的意思是第一个与第二个的作用相同。


只是添加一个对子类中超类构造函数的调用。 调用的是“className”.superclass.constructor.call(this);

This is the extend function from the book "Pro JavaScript Design Patterns"

function extend(subClass, superClass) {
    var F = function() {};
    F.prototype = superClass.prototype;
    subClass.prototype = new F();
    subClass.prototype.constructor = subClass;
    subClass.superclass = superClass.prototype;
    if(superClass.prototype.constructor == Object.prototype.constructor) {
       superClass.prototype.constructor = superClass;
    }
}

I have problems with the first 3 lines... It creates an empty function and then it sets the F.prototype to superClass.prototype which means (for 2 new constructor functions e.g. foo, bar and foo extends bar) that F.prototype will have a constructor property: bar and proto :Object, or not?
And on line 3: subClass.prototype = new F(); happens something that I cannot understand.. Why the inheritance happens here when F's [[Prototype]] is Object?


What are the differences between the first 3 lines and

subClass.prototype = new superClass();

when the code executes? I mean how The first does the same as the second one.


Just to add there is a call to the superClass constructor in the subClass.
The call is "className".superclass.constructor.call(this);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

当爱已成负担 2024-10-22 06:11:24
function extend(subClass, superClass) {

    // create a new empty function
    var F = function() {}; 

    // set the prototype of that function to prototype object of the superclass
    F.prototype = superClass.prototype;

    // now set the prototype of the subClass to a new instance of F
    // this is done so that subClass.prototype.foo = does not affect
    // superClass.prototype.foo
    // if you don't do this, changes to one subClass will affect superClass and all
    // other subClasses of superClass
    subClass.prototype = new F();

注意:subClass.prototype = new superClass() 将调用构造函数并使用返回的新对象作为原型。这将导致 superClass 本身的属性出现在原型链上(因为该实例是原型对象)。

    // set the constructor, this indicates that 'subClass' is a function
    subClass.prototype.constructor = subClass;

    // add a property to indicate what the superClass is
    // this way one can call super methods via this.superclass.something
    subClass.superclass = superClass.prototype;

    // in case the superClass was an object...
    if(superClass.prototype.constructor == Object.prototype.constructor) {

       // change the constructor?
       // no idea why they do this here
       // this introduces a side effect to the function
       superClass.prototype.constructor = superClass;
    }
}
function extend(subClass, superClass) {

    // create a new empty function
    var F = function() {}; 

    // set the prototype of that function to prototype object of the superclass
    F.prototype = superClass.prototype;

    // now set the prototype of the subClass to a new instance of F
    // this is done so that subClass.prototype.foo = does not affect
    // superClass.prototype.foo
    // if you don't do this, changes to one subClass will affect superClass and all
    // other subClasses of superClass
    subClass.prototype = new F();

Note: subClass.prototype = new superClass() would call the constructor and use the returned new object as the prototype. Which would result in properties on superClass itself would turn up on the prototype chain (since that instance is the prototype object).

    // set the constructor, this indicates that 'subClass' is a function
    subClass.prototype.constructor = subClass;

    // add a property to indicate what the superClass is
    // this way one can call super methods via this.superclass.something
    subClass.superclass = superClass.prototype;

    // in case the superClass was an object...
    if(superClass.prototype.constructor == Object.prototype.constructor) {

       // change the constructor?
       // no idea why they do this here
       // this introduces a side effect to the function
       superClass.prototype.constructor = superClass;
    }
}
我爱人 2024-10-22 06:11:24

我们有构造函数:

FSuper &

我们有对象 fsuper 和 &使用上述构造函数创建的 sub

f = new Fsuper = new Supersub = new Sub

我们知道 f.__proto__ === super.__proto__ === Super.prototype 来自第 2 行

从第 3 行我们可以看到 sub.__proto__ === f & sub.__proto__.__proto__ === Super.prototype

另外,我们在第 5 行

和第 4 行和第 5 行中都有 Sub.superClass === Super.prototype 。 6 我们可以说 sub.constructor === Sub & super.constructor === Super

我们可以在第 3 行第 7 行之前调用 new F 的原因是因为第 7 行设置了

f.__proto__.constructor == = Super 其中 f.constructor 已经是 Sub。基本上,第 7 行正在清理 Super ,并且根本不会影响 Sub ,因为您永远不应该在实际代码中调用 .__proto__.constructor

这个特定的函数不会显式地调用 Super 作为函数,而只是确保通过 Sub 构造的对象在其链中具有 Super.prototype

We've got constructors:

F , Super & Sub.

We've got objects f , super, & sub that are made using said constructors.

i.e. f = new F , super = new Super , sub = new Sub

We know f.__proto__ === super.__proto__ === Super.prototype from line 2

From line 3 we can see that sub.__proto__ === f & sub.__proto__.__proto__ === Super.prototype

Also we have Sub.superClass === Super.prototype from line 5.

and from line 4 & 6 we can say that sub.constructor === Sub & super.constructor === Super

The reason we can call new F before on line 3 before line 7 is because line 7 set's

f.__proto__.constructor === Super where as f.constructor is already Sub. basically line 7 is cleaning Super up and shouldn't effect Sub at all because you should never call .__proto__.constructor in real code.

This particular function explicity does not call Super as function but only make's sure that objects constructed through Sub have Super.prototype in their chain.

岁月打碎记忆 2024-10-22 06:11:24

作为替代方案,您可以考虑原型 javascript 库。其中包括继承。

原型 Javascript 库

以下是原型文档中的示例。

var Animal = Class.create({
  initialize: function(name, sound) {
    this.name  = name;
    this.sound = sound;
  },

  speak: function() {
    alert(this.name + " says: " + this.sound + "!");
  }
});

// subclassing Animal
var Snake = Class.create(Animal, {
  initialize: function($super, name) {
    $super(name, 'hissssssssss');
  }
});

var ringneck = new Snake("Ringneck");
ringneck.speak();
//-> alerts "Ringneck says: hissssssssss!"

var rattlesnake = new Snake("Rattler");
rattlesnake.speak();
//-> alerts "Rattler says: hissssssssss!"

这是文档页面

As an alternative, you might consider the prototype javascript library. It includes inheritance.

Prototype Javascript Library

Here is an example from the prototype documentation.

var Animal = Class.create({
  initialize: function(name, sound) {
    this.name  = name;
    this.sound = sound;
  },

  speak: function() {
    alert(this.name + " says: " + this.sound + "!");
  }
});

// subclassing Animal
var Snake = Class.create(Animal, {
  initialize: function($super, name) {
    $super(name, 'hissssssssss');
  }
});

var ringneck = new Snake("Ringneck");
ringneck.speak();
//-> alerts "Ringneck says: hissssssssss!"

var rattlesnake = new Snake("Rattler");
rattlesnake.speak();
//-> alerts "Rattler says: hissssssssss!"

Here is the documentation page

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文