Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.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_Inheritance_Ecmascript 5 - Fatal编程技术网

JavaScript-出于什么原因…;遗产

JavaScript-出于什么原因…;遗产,javascript,inheritance,ecmascript-5,Javascript,Inheritance,Ecmascript 5,有人能告诉我,为什么允许这样做(?): 即使在使用中,允许改变遗产结构的原因是什么?继承结构的这种变化不应该反映出来吗 以下是3种类型中可能/声称的继承。当然,正确的做法是更改语句“B.prototype=newa();”的位置,但我故意这样做。这是因为您不能声明继承结构。所有的继承都是在运行时动态完成的,因此在任何时间点都不可能再对其进行更改 当您将一个类的实例用作另一个类的prottype时,它将继承该实例,而不仅仅是复制结构。例如: function A() {} A.prototype

有人能告诉我,为什么允许这样做(?):

即使在使用中,允许改变遗产结构的原因是什么?继承结构的这种变化不应该反映出来吗


以下是3种类型中可能/声称的继承。当然,正确的做法是更改语句“B.prototype=newa();”的位置,但我故意这样做。

这是因为您不能声明继承结构。所有的继承都是在运行时动态完成的,因此在任何时间点都不可能再对其进行更改

当您将一个类的实例用作另一个类的prottype时,它将继承该实例,而不仅仅是复制结构。例如:

function A() {}
A.prototype = {
  hello: function() {}
};

var a = new A();

function B() {}
B.prototype = a;

var b = new B();

// all instances of B has the hello method
b.hello();

// add a method to the A instance
a.goodbye = function() {};

// now all instances of B have that method
b.goodbye();
这一行:

 B.prototype = new A();
表示将原型分配给A的实例。 如果省略构造函数调用,则相当于:

B.prototype = Object.create(A.prototype);
这意味着
B.prototype
指向从
A.prototype
克隆的对象:

Object.getPrototypeOf(B.prototype) === A.prototype // true
但在这一行:

A.prototype = new SuperA();
您正在替换
A.prototype
中的引用,但
B.prototype
仍指向旧引用:

var oldProto = A.prototype;
A.prototype = new SuperA();
Object.getPrototypeOf(B.prototype) === A.prototype // false
Object.getPrototypeOf(B.prototype) === oldProto    // true
这条线路的工作原理是:

alert(objectB.getA());
因为
getA
是在
newa()
调用中添加的,所以它向现有原型添加了一个新插槽,而不是替换整个实例

这是:

alert(objectB.getSuperA()); 
不起作用,因为SuperA不在B的原型链中

这个问题很棘手。但实际上JavaScript有一个非常简单的模型,但由于一些语言关键字(new/instanceof)和函数的奇怪使用(类似于Java构造函数),它令人困惑:

  • 属性/方法查找始终在原型链中上升。这就是你所有的遗产
  • “Clonning”(就Object.create而言)意味着创建一个新的空对象,并从给定对象设置原型
  • 原型只是对对象的引用,所以您可以随时添加/更改插槽
只有这两样东西你就不需要剩下的了。构造函数(内部有一些小的差异)可以看作是实现以下目标的捷径:

var newInstance = Object.create(SomeFunction.prototype);
SomeFunction.constructor.apply(newInstance, arguments);

对我来说,使用函数来创建对象是一个坏主意,如果JavaScript只有
对象。从版本1创建
,而没有构造函数,那么所有的模型都更容易理解。

这是有意义的,毕竟解释器读取了代码,只有函数首先被读取和分离。但当我想到物体时,我开始感到困惑。JavaScript使用对象。如果我说B从A继承,然后我说A从某物继承,这不应该通过对象引用反映出来吗?B是否更新了“a”的结构?B不知道A的结构,即使A发生了变化(在继承方面,在这种情况下)?@Loa:当你使用A的一个实例作为B的原型时,那么B不是继承A的结构,而是继承A的那个实例。如果你改变A的结构,或者A的那个实例的内容,它将影响B的所有实例。。。非常感谢。这让我明白了一些事情。如果我让你给我看一个你现在所说的例子,我会感到恼火吗?请编辑您的答案或给我一个链接好吗?@Loa:我在上面添加了一个示例,希望能有所帮助。请注意,在这里创建的a、B或SuperA的每个新实例都会在您更改构造函数中的原型时修改其所有实例的继承。
var newInstance = Object.create(SomeFunction.prototype);
SomeFunction.constructor.apply(newInstance, arguments);