在这个例子中,一个名为“' t'添加说话功能。Speak.t=5;
当我调用speak()时,它通过另一个名为show.But的函数输出值5当我创建Speak的新实例时,它不会继承属性t。为什么所以我的意思是,如果它是Speak构造函数的一个属性,它的所有实例都应该继承它吗?
<html>
<body>
<script>
function Speak(){
show(Speak.t);
}
Speak.t=5;
function show(v){
console.log('value is : '+v);
}
Speak();
var s1=new Speak();
console.log(s1.t);
</script>
</body>
</html>
答案 0 :(得分:4)
&#34;我的意思是如果它是Speak构造函数的属性,它的所有实例都应该继承它吗?&#34;
没有。它的实例继承自构造函数的原型,而不是构造函数本身。 JavaScript是基于原型的,而不是#34;基于构造函数的#34;。如果您熟悉other OOP languages,则Speak.t
类似与公众static property。
将其更改为Speak.protoype.t = 5
会将属性t: 5
添加到原型中,该原型将继承到其所有实例:
function Speak(){
show(this.t);
}
Speak.prototype.t = 5;
function show(v){
console.log('value is : '+v);
}
var s1 = new Speak(); //"value is : 5"
console.log(s1.t); //5
由于实例继承自其构造函数的原型,您实际上可以通过执行以下操作来实现类继承:
function SpecialSpeak(){}
SpecialSpeak.prototype = new Speak();
这会创建一个Speak
实例并将其指定为SpecialSpeak
的原型。
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
由于所有Speak
个实例的原型发生变化后都会更新,因此它还会更新SpecialSpeak
的原型并更新所有SpecialSpeak
个实例
var s = new SpecialSpeak();
s.v; //undefined
Speak.prototype.v = "text";
s.v; //text
这演示了继承在JavaScript中的工作原理。原型的链接有时称为"prototype chain"。
您可能还想查看有关继承的this great article。
旁注:由于所有原型链都必须有一个起点,
Object.prototype instanceof Object; //false
虽然Object.prototype
是一个对象,但它是 * 所有内容的最顶层原型(对象),因此它不是Object
的实例。它是 对象!
* 从ES5开始,引入了Object.create
,允许您创建不会从Object.prototype
继承的对象。
答案 1 :(得分:1)
当在构造函数上调用new
运算符时,JavaScript引擎会在场景后面执行几步:
this
this
对象。在任何时候它都不会考虑附加到构造函数的类属性。这就是Speak.t = 5
不创建继承属性的原因。
然而,这些代码将会:
// By attaching `t` to the prototype
function Speak1() {}
Speak1.prototype.t = 5;
// By attaching `t` to the newly created object
function Speak2() {
this.t = 5;
}
// By returning an object containing `t` (thus overriding the formerly allocated this)
function Speak3() {
return {
t: 5
};
}
您可以阅读here了解详情。
答案 2 :(得分:1)
这是因为您没有在内部设置t
的值。你应该在Speak的构造函数中实例化t
的值,如下所示:
function Speak(){
this.t = 5;
show(this.t);
}
function show(v){
console.log('value is : '+v);
}
Speak();
var s1=new Speak();
console.log(s1.t);
您还可以在构造函数中附加show
方法来访问它的原型。
var Speak = (function() {
function Speak() {
this.t = 5;
this.show();
}
Speak.prototype.show = function() {
return console.log('value is : ' + this.t);
};
return Speak;
})();
var s1=new Speak();
console.log(s1.t);
答案 3 :(得分:1)
因为函数只是对象t
成为Speak函数的属性,而不是与实例共享。
对于例如默认情况下的函数获取一个名为length的属性(给出函数的arity) 不会与实例共享。
function Speak(){}
var obj = new Speak();
console.log("length" in Speak); // true
console.log("length" in obj); // false
您可以清楚地看到长度未与实例共享。 在javascript中,共享属性或方法的唯一方法是通过原型模式。
以这种方式创建属性,使其在Speak
上的行为类似于static
变量