javascript原型vs这个

时间:2016-01-27 17:22:37

标签: javascript oop prototype this

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

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里面的“this”是什么?
  2. 关于分配功能的其余部分是什么 在构造函数内使用对象的原型?
  3. 貌似,使用此版本的版本。在构造函数中是一个 做我想做的事情(即能够访问变量 在一个类的实例中)。鉴于此,为什么要javascript oop教程如此讨论原型?
  4. 提前致谢!

    --- --- EDIT

    我对此有了更多的想法,并意识到将示例扩展到单一方法之后可能是值得的,并尝试查看哪些变量可以访问。

    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变量)。

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

首先,javascript OO是原型,因此它与基于类的OO不完全相同。你好像已经抓住了必要的部分。

Prototypical继承的工作方式有点像向后数据树:如果你没有在对象本身找到属性,看看它的原型,如果它不在它的原型上,看看它的原型是什么原型等等,直到没有原型。

<强> 1。什么是“this”指的是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的工作方式。当它在Prototype上时,原型对象是“所有者”,因此您的实例对象没有将该方法作为自己的属性。这看似微不足道,但这是一个重要的区别,特别是在循环/循环对象属性时。

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

第3

上面两个答案几乎解释了。