JavaScript原型与这个

javascript prototypes vs this

本文关键字:原型 JavaScript      更新时间:2023-09-26

我试图更好地掌握javascript类的内容和原因。 具体来说,我试图了解将方法分配给原型与使用 this.methodName = 函数之间的区别......构造函数中的语句。 所以,我做了一个实验:

function CThis(){
  this.method= function() {
    console.log("method of ",this);
  };
}
function CProto(){
}
CProto.prototype.method = function() {
  console.log("method of ",this);
};
window.onload = function(){
  ct = new CThis(); 
  ct.method();
  cp = new CProto();
  cp.method();
};

我的假设是两者的行为方式相同,但我学到了一些东西。 这是输出:

"method of " Object { method: CThis/this.method() } oop.js:3:4
"method of " Object {  } oop.js:11:2

在构造函数中使用this.method实际上给了我想要从典型oop程序中的类实例中的行为:即,"this"指的是类实例。 使用原型方法,这似乎指的是一个空对象。

我想我在这里的问题有三个方面:

  1. CProto.prototype.method中的"这个"指的是什么?
  2. 关于分配函数的其余故事是什么在构造函数中对此与使用对象的原型?
  3. 看起来,使用它的版本。 在构造函数中是一个做我想做的事情(即能够访问变量在类的实例中)。 既然如此,为什么 JavaScript哎呀教程这么谈原型?

提前感谢!

---编辑---

我对此进行了更多的思考,并意识到也许值得将示例扩展到单个方法之外,并尝试查看哪些变量可访问。

function CThis(){
  this.localthis = "I'm this.localthis";
  var localvar = "I'm localvar";
  this.method= function() {
    console.log("method of ",this);
    console.log("value of this.localthis:", this.localthis);
    console.log("value of localvar with this.:", this.localvar); 
    console.log("value of localvar without this.:", localvar); 
  };
}
function CProto(){
  this.localthis = "I'm this.localthis";
  var localvar = "I'm localvar";
}
CProto.prototype.method = function() {
  console.log("method of ",this);
  console.log("value of this.localthis:", this.localthis); 
  console.log("value of localvar with this.:", this.localvar);  
  console.log("value of localvar without this.:", localvar);  
};
window.onload = function(){
  ct = new CThis(); 
  ct.method();
  cp = new CProto();
  cp.method();
};

和新的输出:

method of " Object { localthis: "I'm this.localthis", method: CThis/this.method() } oop.js:5:4
"value of this.localthis:" "I'm this.localthis" oop.js:6:4
"value of localvar with this.:" undefined oop.js:7:4
"value of localvar without this.:" "I'm localvar" oop.js:8:4
"method of " Object { localthis: "I'm this.localthis" } oop.js:18:2
"value of this.localthis:" "I'm this.localthis" oop.js:19:2
"value of localvar with this.:" undefined oop.js:20:2
ReferenceError: localvar is not defined
因此,在

变量作用域方面肯定存在差异(在this.method中,我可以从构造函数内部访问var变量)。

在第一种情况下,您创建的每个实例都有自己的方法副本,因此当您打印出对象时,它是可见的。每次调用构造函数时,JS 引擎可能还必须对此函数执行编译步骤。

在第二种情况下,您创建的任何实例都没有任何属性。相反,当你调用该方法时,js 引擎会在原型链中向上移动,寻找正确名称的属性。它查看cp.__proto__并找到指向您称为CProto.prototype的对象的指针,该对象确实具有可以调用的称为"method"的属性。

作为附加测试,向类中添加一个实际实例变量。将this.foo = 42;添加到两个构造函数,然后查看您得到的内容。

首先,javascript OO是原型的,所以它不完全像基于类的OO。你似乎已经掌握了基本部分。

原型

继承的工作方式有点像向后的数据树:如果在对象本身上找不到属性,请查看它的原型,如果它不在原型上,请查看它的原型原型,依此类推,直到没有原型。

1. CProto.prototype.method内部的"这个"指的是什么?

调用 METHOD 时,这始终是指上下文对象(即用于调用方法的对象)。

obj1.hello() // this === obj1
obj2.hello() // this === obj2
Object.getPrototypeOf(obj1).hello() // this is now global since you didn't use a contextual object.
obj1.hello.call(obj2) // this === obj2, because we forced a context change

2. 关于在构造函数中为其分配函数与使用对象的原型相比,故事的其余部分是什么?

分配给原型会使原型的所有实例继承该方法。在构造函数中赋值意味着只有实例具有该方法。否则,它本质上是一样的。实例方法的唯一优势是访问实例的私有上下文(闭包)。

在构造函数中赋值时,对象本身是方法的"所有者"。这改变了Object.key()for in的工作方式。当它位于原型上时,原型对象是"所有者",因此您的实例对象没有将该方法作为自己的属性。这可能看起来微不足道,但这是一个重要的区别,尤其是在循环/循环对象属性时。

通过原型进行分配时,方法只有一个实例(它在原型上)。通过构造函数赋值时,将为每个实例创建一个新上下文和一个新函数。虽然微不足道,但存在性能差异。

3.

上面两个答案已经解释得差不多了。