Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.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工厂函数没有这个,新的或原型_Javascript_Class_Inheritance_Prototype_Instantiation - Fatal编程技术网

Javascript工厂函数没有这个,新的或原型

Javascript工厂函数没有这个,新的或原型,javascript,class,inheritance,prototype,instantiation,Javascript,Class,Inheritance,Prototype,Instantiation,我越来越多地使用这种奇怪(至少对我来说)的方法,我开始喜欢它,但与此同时,我不确定在更大的背景下是否有什么可怕的错误 简化示例: function createCat(initName) { let name = initName; const getName = () => name; function setName(newName) { name = newName; } function meow() { console.log("ME

我越来越多地使用这种奇怪(至少对我来说)的方法,我开始喜欢它,但与此同时,我不确定在更大的背景下是否有什么可怕的错误

简化示例:

function createCat(initName) {
  let name = initName;
  const getName = () => name;
  function setName(newName) {
    name = newName;
  }
  function meow() {
    console.log("MEOW");
  }
  return {
    meow,
    setName,
    getName
  };
}

function createSuperCat(name) {
  const proto = createCat(name);
  const getName = () =>
    `Super secret! But hey - they used to call himself ${name}`;
  const getSecretName = () => proto.getName();
  function bark() {
    console.log("WHOOF");
  }
  return { ...proto, bark, getName, getSecretName };
}

const someCat = createCat("Hugo");
const someSuperCat = createSuperCat("Fluffy");

// someCat
console.log(someCat.getName()); // Hugo
someCat.setName("Tom");
console.log(someCat.getName()); // Tom
someCat.meow(); // MEOW

// someSuperCat
console.log(someSuperCat.getName()); // Super secret! But hey - they used to call him Fluffy
console.log(someSuperCat.getSecretName()); // Fluffy
someSuperCat.setName("Mittens");
console.log(someSuperCat.getSecretName()); // Mittens
console.log(someSuperCat.getName()); // Super secret! But hey - they used to call him Fluffy
someSuperCat.meow(); // MEOW
someSuperCat.bark(); // WHOOF
我知道没有唯一正确的方法,如果某个方法有效,它就是一个有效的解决方案

但是,我还是想知道……你认为这种方法有什么需要注意的地方吗

到目前为止,它似乎可以做所有像继承、扩展或重写继承方法这样的奇特的事情,你可以省略旧的y OOP,你不必用新的关键字实例化一个标准的工厂函数,没有原型模式(实际上有点-而且因为它是Javascript,所以总是会有),没有任何类或其他语法糖


我可能错了。我不是一个真正的程序员或什么的,所以我希望有经验的人能给我一些建议,因为我可能错过了一些以后可能会引起不适的东西。

所以这种方法最大的一个警告是,首先,给代码增加不必要的复杂性,由于JS已经为您所做的事情提供了解决方案,所以这样做并不能真正实现任何目标。但是,随着对象数量的增加,这种方法的效率会大大提高,并且会浪费内存。原型继承和
this
关键字的一个好处是,所有函数都可以存储在单个对象引用中

您的方法重新定义每个对象的所有函数。因此,每次创建一个新的
cat
对象时,您都在重新定义所有通用函数。存储在每个对象的内存中

即使您希望避免使用类和使用
new
,也最好利用原型继承和
this
关键字

我将您的代码改写为:

const-catProto={
getName:函数(){
返回此.name;
},
setName:函数(newName){
this.name=newName;
},
喵喵:函数(){
控制台日志(“喵喵”);
},
};
函数createCat(名称){
const cat=Object.create(catProto);
cat.name=名称;
返回猫;
}
函数createSuperCat(名称){
const cat=createCat(名称);
cat.getName=()=>`超级秘密…`;
cat.getSecretName=catProto.getName;
cat.bark=()=>console.log(“WHOOF”);
返回猫;
}
const someCat=createCat(“雨果”);
const someSuperCat=createSuperCat(“Fluffy”);
//某只猫
console.log(someCat.getName());//雨果
someCat.setName(“汤姆”);
console.log(someCat.getName());//汤姆
someCat.meow();//喵
//超级猫
console.log(someSuperCat.getName());//超级秘密!但是,嘿,他们以前叫他毛茸茸的
console.log(someSuperCat.getSecretName());//毛茸茸的
someSuperCat.setName(“手套”);
console.log(someSuperCat.getSecretName());//连指手套
console.log(someSuperCat.getName());//超级秘密!但是,嘿,他们以前叫他毛茸茸的
someSuperCat.meow();//喵

someSuperCat.bark();//WHOOF
所以这种方法最大的一个警告是,首先,给代码增加了不必要的复杂性,因为JS已经为您正在做的事情提供了解决方案,所以这样做并不能真正实现任何目标。但是,随着对象数量的增加,这种方法的效率会大大提高,并且会浪费内存。原型继承和
this
关键字的一个好处是,所有函数都可以存储在单个对象引用中

您的方法重新定义每个对象的所有函数。因此,每次创建一个新的
cat
对象时,您都在重新定义所有通用函数。存储在每个对象的内存中

即使您希望避免使用类和使用
new
,也最好利用原型继承和
this
关键字

我将您的代码改写为:

const-catProto={
getName:函数(){
返回此.name;
},
setName:函数(newName){
this.name=newName;
},
喵喵:函数(){
控制台日志(“喵喵”);
},
};
函数createCat(名称){
const cat=Object.create(catProto);
cat.name=名称;
返回猫;
}
函数createSuperCat(名称){
const cat=createCat(名称);
cat.getName=()=>`超级秘密…`;
cat.getSecretName=catProto.getName;
cat.bark=()=>console.log(“WHOOF”);
返回猫;
}
const someCat=createCat(“雨果”);
const someSuperCat=createSuperCat(“Fluffy”);
//某只猫
console.log(someCat.getName());//雨果
someCat.setName(“汤姆”);
console.log(someCat.getName());//汤姆
someCat.meow();//喵
//超级猫
console.log(someSuperCat.getName());//超级秘密!但是,嘿,他们以前叫他毛茸茸的
console.log(someSuperCat.getSecretName());//毛茸茸的
someSuperCat.setName(“手套”);
console.log(someSuperCat.getSecretName());//连指手套
console.log(someSuperCat.getName());//超级秘密!但是,嘿,他们以前叫他毛茸茸的
someSuperCat.meow();//喵

someSuperCat.bark();//WHOOF
只要您意识到以下功能的缺失,这种模式就可以了:

  • 运算符的实例
  • Object.getPrototypeOf
  • 原型
    构造函数
    属性
  • 没有功能的副本,因为原型上会有它们
这似乎也会对性能产生影响

下面是与现代语法中的OOP实现的比较。请注意,它使用私有字段,在撰写本文时,并非所有引擎都支持私有字段,尤其是FireFox。但例如在Chrome中,它运行良好:

//寄生实现
函数createCat(initName){
让name=initName;
const getName=()=>name;
函数集合名(newName){
name=newName;
}
函数meow(){
返回“喵喵”;
}
返回{
喵,
集合名,