Javascript 为什么实例不';在没有prototype关键字的情况下将t inherit属性添加到构造函数中
在本例中,一个名为“t”的属性被添加到speak函数中。Javascript 为什么实例不';在没有prototype关键字的情况下将t inherit属性添加到构造函数中,javascript,Javascript,在本例中,一个名为“t”的属性被添加到speak函数中。speak.t=5当我调用speak()时,它会通过另一个名为show的函数打印值5。但是当我创建speak的新实例时,它不会继承属性t。为什么会这样?我的意思是,如果它是speak构造函数的属性,它的所有实例都应该继承它 <html> <body> <script> function Speak(){ show(Speak.t); } Speak.t=5; function show(v){
speak.t=5代码>当我调用speak()时,它会通过另一个名为show的函数打印值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>
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
函数Speak(){
show(Speak.t);
}
t=5;
功能表演(五){
console.log('值为:'+v);
}
说();
var s1=新的Speak();
控制台日志(s1.t);
“我的意思是,如果它是Speak构造函数的属性,那么它的所有实例都应该继承它?”
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
不。它的实例继承自构造函数的原型,而不是构造函数本身。JavaScript基于原型,而不是“基于构造函数”。如果您熟悉,Speak.t
将类似于公用电话
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
将其更改为Speak.prototype.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
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
由于实例继承自其构造函数的原型,因此实际上可以通过执行以下操作来实现类继承:
function SpecialSpeak(){}
SpecialSpeak.prototype = new Speak();
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
这将创建一个Speak
实例,并将其指定为SpecialSpeak
的原型
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
由于所有的Speak
实例都将在其原型发生更改时更新,因此它还将更新SpecialSpeak
的原型,并更新所有SpecialSpeak
的实例
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
var s = new SpecialSpeak();
s.v; //undefined
Speak.prototype.v = "text";
s.v; //text
function Speak(){}
var obj = new Speak();
console.log("length" in Speak); // true
console.log("length" in obj); // false
这演示了继承如何在JavaScript中工作。原型的链接有时称为链接
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
您可能还想查看有关继承的信息
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
旁注:由于所有原型链都必须有一个起点
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
Object.prototype instanceof Object; //false
虽然Object.prototype
是一个对象,但它是所有*继承自的顶级原型(对象),因此它不是Object
的实例。这就是目标
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
*从ES5开始,引入了Object.create
,它允许您创建不从对象继承的对象。prototype
当对构造函数调用new
操作符时,JavaScript引擎会在幕后执行一些步骤:
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
它分配从构造函数原型继承的新对象
它执行构造函数,将新创建的对象作为this
如果构造函数返回一个对象,那么它将使用它。否则,它将使用此
对象
它在任何时候都不会考虑附加到构造函数的类属性。这就是为什么Speak.t=5
不创建继承属性的原因
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
但是,这些代码将执行以下操作:
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
// 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
};
}
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
您可以阅读了解更多信息。发生这种情况是因为您没有在内部设置t
的值。您应该在的构造函数中实例化t
的值,如下所示:
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
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
方法来访问它的原型
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
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);
因为函数只是对象,所以t
成为函数Speak的一个属性,而不是与实例共享
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
var s = new SpecialSpeak();
s.v; //undefined
Speak.prototype.v = "text";
s.v; //text
function Speak(){}
var obj = new Speak();
console.log("length" in Speak); // true
console.log("length" in obj); // false
对于例如函数,默认情况下获取一个名为length的属性(给出函数的arity)
不会与实例共享
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
var s = new SpecialSpeak();
s.v; //undefined
Speak.prototype.v = "text";
s.v; //text
function Speak(){}
var obj = new Speak();
console.log("length" in Speak); // true
console.log("length" in obj); // false
您可以非常清楚地看到,实例不共享长度。
在javascript中,共享属性或方法的唯一方法是通过原型模式
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true
以这种方式创建属性,使其行为类似于Speak上的静态
变量我敢肯定,这必须是重复的,但是我找不到它。Speak。有些东西可能是静态的:原型由实例共享:我不理解您的第二个示例。您在另一个Speak函数中声明了另一个Speak函数。这很混乱。稍作解释会更好。无论如何,谢谢:)var Speak
将包含自动执行功能。在这个自动执行的函数中,我创建了函数Speak并将t
属性和show
函数附加到他的原型中。现在清楚了吗?函数参数有长度属性。但是函数本身如何有长度属性。我的意思是Speak.length可能返回什么??例如,如果你说函数test(a,b){}。测试长度为2。length为您提供函数可以接受的参数数量。这只是断言了一个事实,即函数只是javascript@BOSS-.length
不提供函数可以接受的参数数量。相反,它返回函数期望的参数数。父实例是否设置子对象的原型部分,子对象是否不重新使用父构造函数?参考一篇展示如何使用prototype的文章不是更好吗?@HMR-我已经添加了一个指向MDN继承文章的链接。
new SpecialSpeak() instanceof SpecialSpeak; //true
new SpecialSpeak() instanceof Speak; //true