Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:覆盖函数';s原型-坏习惯?_Javascript_Constructor_Prototype - Fatal编程技术网

Javascript:覆盖函数';s原型-坏习惯?

Javascript:覆盖函数';s原型-坏习惯?,javascript,constructor,prototype,Javascript,Constructor,Prototype,因为当我们声明一个函数时,它的原型的构造函数属性指向函数本身,这样覆盖函数的原型是一种不好的做法吗: function LolCat() { } // at this point LolCat.prototype.constructor === LolCat LolCat.prototype = { hello: function () { alert('meow!'); } // other method declarations go here a

因为当我们声明一个函数时,它的原型的构造函数属性指向函数本身,这样覆盖函数的原型是一种不好的做法吗:

function LolCat() {
}

// at this point LolCat.prototype.constructor === LolCat

LolCat.prototype = {
    hello: function () {
        alert('meow!');
    }
    // other method declarations go here as well
};

// But now LolCat.prototype.constructor no longer points to LolCat function itself

var cat = new LolCat();

cat.hello(); // alerts 'meow!', as expected

cat instanceof LolCat // returns true, as expected
我不是这样做的,我还是喜欢下面的方法

LolCat.prototype.hello = function () { ... }
但我经常看到其他人这样做

因此,为了方便起见,如第一个示例所示,通过覆盖函数的原型对象,从原型中删除构造函数引用,是否有任何含义或缺点?

此表单:

LolCat.prototype = {
  hello: function () {
      alert('meow!');
  }
};
LolCat.prototype.hello = function () { ... }
销毁任何现有的方法和公共属性。在本例中,如前所述,这并不重要,因为新创建的LolCat没有任何属性或方法。然而,在更复杂的代码中应该注意这一点

此表格:

LolCat.prototype = {
  hello: function () {
      alert('meow!');
  }
};
LolCat.prototype.hello = function () { ... }

将新方法添加到现有对象并保持现有对象的完整性。

在使用原型继承时覆盖
构造函数
是一种不错的做法。事实上,很多人都是这样做的:

LolCat.prototype = {
    constructor: LolCat,
    hello: function () {
        alert('meow!');
    }
};

这是一个不错的练习,但是你必须知道你在做什么以及为什么。它对于原型遗传非常有用。覆盖原型的对象将获得指定给其原型的对象的所有属性:

您可以使用

ChildClassName.prototype = new ParentClass();.
现在,ChildClassName拥有ParentClass的所有功能,但丢失了以前分配给它的原型的所有功能。您需要记住使用重置对象的构造函数属性

ChildClassName.prototype.constructor=ChildClassName. 
否则(在测试对象类型时)该对象将报告为ParentClass类型而不是ChildClassName类型

现在,您可以按照自己描述的方式向ChildClassName对象添加更多方法

ChildClassName.prototype.myMethod = function(){
    //do stuff
}
结果是一个父对象/“类”(当然javascript中没有真正的类)和一个从中继承并扩展其功能的子对象/“类”


您只需要知道,如果覆盖原型,则分配给原型的任何属性都将消失。在构造继承对象时,这可能正是您想要的。

这是一种不错的做法。但是有一种简单而标准的方法可以重写下面的函数。当我们全局定义一个“函数LolCat()”时,它是在窗口下创建的,所以您可以像下面这样编写代码

window.LolCat = function() {...};
LolCat.prototype.hello = function () { ... }

就这一点而言,我看不到任何人提到最佳实践,因此我认为这归根结底是看
构造函数
属性是否有用

值得注意的一点是
构造函数
属性,如果不销毁它,也可以在创建的对象上使用。在我看来,这可能很有用:

var ClassOne = function() {alert("created one");}
var ClassTwo = function() {alert("created two");}

ClassOne.prototype.aProperty = "hello world"; // preserve constructor
ClassTwo.prototype = {aProperty: "hello world"}; // destroy constructor

var objectOne = new ClassOne(); // alerts "created one"
var objectTwo = new ClassTwo(); // alerts "created two"

objectOne.constructor(); // alerts "created one" again
objectTwo.constructor(); // creates and returns an empty object instance
因此,在我看来,这是一个建筑决策。是否允许创建的对象在实例化后重新调用其构造函数?如果是这样,就保存它。如果没有,销毁它

请注意,objectTwo的构造函数现在与标准对象构造函数函数完全相同-无用

objectTwo.constructor === Object; // true

因此,调用
new objectTwo.constructor()
相当于
new Object()

在多年的javascript之后,我偶然发现了一个奇怪的错误,其中一个对象的新实例,然后传入了一个mixin,当它的
原型
类声明为:

MyClass.prototype = {
   constructor: MyClass,
   myMethod(){ ...}
};
使用时不再存在任何问题:

Object.assign( MyClass.prototype, {
   myMethod(){ ...}
});
奖励:你不必再重新设计这个结构了


我想这是因为当我们完全覆盖prototype属性时,我们也会擦除它的specials属性,并将其转换为普通属性…也许这个属性在默认情况下不应该是可写的…

True,但在像OP的示例这样的新定义类的上下文中,这并不是一个真正的问题,因为还没有任何公共“存在”。哦,我同意在给出的例子中,这是正确的。我修改了我的答案以澄清问题。谢谢。那你觉得这完全是可选的吗?我的意思是,如果它没有破坏
操作符的
实例,那么完全忽略它就没有什么坏处了?@Chris:@FelixKling谢谢,这是一个很好的链接!我认为Jacob的回答对我来说是最有意义的——基本上,显式重新分配
构造函数
属性是一种试图通过经典继承的圆孔来适应Javascript的方桩的方法!)一个有趣的问题。我将在Google上转一转,看看能找到什么。Related:LolCat.prototype={constructor:LolCat,…}使用它将保留构造函数。当你说“reported to the ParentClass type”,你的意思是当使用
instanceof
测试时,它将针对子类返回
false
?我认为这并不能真正回答问题,在全局命名空间中放置构造函数也不是一个好主意。