Javascript应用—;继承类

Javascript应用—;继承类,javascript,Javascript,下面的代码改编自 原始帖子没有MessageClass.apply(这是参数)因为它的目的是显示Javascript中继承是如何出错的 我的问题是:ErrorMessageClass.prototype=newMessageClass()之前ErrorMessageClass构造函数甚至被宣布为坏习惯?我的理解是,这样调用未声明的标识符会导致出现静默声明,结果被放置在全局窗口对象上,我理解这是不好的 这张表格是: function ErrorMessageClass() {

下面的代码改编自

原始帖子没有
MessageClass.apply(这是参数)因为它的目的是显示Javascript中继承是如何出错的

我的问题是:
ErrorMessageClass.prototype=newMessageClass()之前ErrorMessageClass构造函数甚至被宣布为坏习惯?我的理解是,这样调用未声明的标识符会导致出现静默声明,结果被放置在全局窗口对象上,我理解这是不好的

这张表格是:

    function ErrorMessageClass() {
        MessageClass.apply(this, arguments);
    }
    ErrorMessageClass.prototype = new MessageClass();
被认为是更好的做法?显示了按照上面的原样编写的代码,这就是为什么我尝试了它。这个博主知道一些我不知道的事情吗

编辑


下面的答案中有很多很好的信息,但我确实想强调一下真正完美地解释事情的是什么

它是有效的,因为函数声明是先求值的。如果试图将这些类移动到对象文字“名称空间”下,则第一个版本将失败


我个人觉得第二种方法更容易阅读——另外,别忘了将子类的prototype.constructor属性设置回自身。就我个人而言,我在函数原型上使用了inherits()方法,它基本上封装了您在这里使用的代码类型。

这是有效的,因为首先计算函数声明。如果试图将这些类移动到对象文字“名称空间”下,则第一个版本将失败


我个人觉得第二种方法更容易阅读——另外,别忘了将子类的prototype.constructor属性设置回自身。就我个人而言,我在函数原型上使用了inherits()方法,它基本上封装了您在这里使用的代码类型。

通常,为了避免这种混淆,您只需在之后附加原型,但正如Adam Rack所指出的,函数声明会被挂起,就像var语句一样

但是,不应将基本对象实例化为原型。如果您的基本对象接受参数,您应该使用什么?使用空的“代理”构造函数

// Used to setup inheritance
function surrogate () {};


function MessageClass() {
    var self = this;
    this.clickHander = function(e) { self.someoneClickedMe = true; };

    var _private = 0;
    this.getPrivate = function() { return _private; };
    this.setPrivate = function(val) { _private = val; };
}

// The key steps to creating clean inheritance
surrogate.prototype = MessageClass;
// Sets up inheritance without instantiating a base class object
ErrorMessageClass.prototype = new surrogate();
// Fix the constructor property
ErrorMessageClass.prototype.constructor = ErrorMessageClass

function ErrorMessageClass() {
    MessageClass.apply(this, arguments);
}

还有很多话要说

通常,为了避免这种混淆,您只需在之后附加原型,但正如Adam Racks所指出的,函数声明就像var语句一样被挂起

但是,不应将基本对象实例化为原型。如果您的基本对象接受参数,您应该使用什么?使用空的“代理”构造函数

// Used to setup inheritance
function surrogate () {};


function MessageClass() {
    var self = this;
    this.clickHander = function(e) { self.someoneClickedMe = true; };

    var _private = 0;
    this.getPrivate = function() { return _private; };
    this.setPrivate = function(val) { _private = val; };
}

// The key steps to creating clean inheritance
surrogate.prototype = MessageClass;
// Sets up inheritance without instantiating a base class object
ErrorMessageClass.prototype = new surrogate();
// Fix the constructor property
ErrorMessageClass.prototype.constructor = ErrorMessageClass

function ErrorMessageClass() {
    MessageClass.apply(this, arguments);
}

还有很多话要说

“首先计算函数声明”是什么意思?你是说函数ErrorMessageClass()。。。将在ErrorMessageClass.Prototype=。。。甚至被宣布为第二?我认为口译语言无法做到这一点,这可能会有所帮助-@Adam:是的。JavaScript充满了惊喜!如果不希望“函数提升”,可以将函数编写为FunctionExpression而不是magic FunctionDeclaration语句:
var ErrorMessageClass=function(){…}那个链接很好地解释了事情。谢谢。你所说的“先计算函数声明”是什么意思?你是说函数ErrorMessageClass()。。。将在ErrorMessageClass.Prototype=。。。甚至被宣布为第二?我认为口译语言无法做到这一点,这可能会有所帮助-@Adam:是的。JavaScript充满了惊喜!如果不希望“函数提升”,可以将函数编写为FunctionExpression而不是magic FunctionDeclaration语句:
var ErrorMessageClass=function(){…}那个链接很好地解释了事情。谢谢。+1绝对不要构造和初始化一个真实的对象作为原型使用。请参阅背景和一些例子,在一个方法中封装“代理”,提供一个单独的初始化器等。我大部分同意,但你认真考虑使用它的地方和它不在哪里。并不是说它改变了什么,模拟基本上使用了与代码相同的方法。那么我为什么要使用它呢?因为道格拉斯·克罗克福德(Douglas Crockford)说新的
操作符是危险的?+1绝对不要构造和初始化一个真实的对象作为原型使用。请参阅背景和一些例子,在一个方法中封装“代理”,提供一个单独的初始化器等。我大部分同意,但你认真考虑使用它的地方和它不在哪里。并不是说它改变了什么,模拟基本上使用了与代码相同的方法。那么我为什么要使用它呢?因为Douglas Crockford说新的操作员很危险?