在构造函数调用模式中理解`this`

时间:2016-11-11 20:37:49

标签: javascript

尝试理解this,在javascript the good parts书中找到了一个例子:

var first;
var second;

var Quo = function(string) {
    first = this;
    this.status = string;// first this
};

Quo.prototype.get_status = function() {
    second = this;
    return this.status;//second this
};

var myQuo = new Quo( "confused" );
console.log( myQuo.get_status() );

console.log( (first===second) + ',' + (second===myQuo) + ',' + (first===myQuo) );

输出:

$ node test.js 
confused
true,true,true

第一个this和第二个this是否都指向myQuo?如何打印出每个this指向的对象名称或函数名称或类名? (目前真的被this搞糊涂了。)

更新

另一个问题:两个this都引用Quo的实例而不是Quo的原型?

另外,尝试:

console.log( myQuo.get_status() );
console.log(first.constructor.name);
console.log( first );
console.log( second );

输出:

confused

{ status: 'confused' }
{ status: 'confused' }

为什么first.constructor.name什么都没有?为什么first{ status: 'confused' }

4 个答案:

答案 0 :(得分:2)

在javascript中,当在实例上调用在原型上定义的函数时; "这"在函数内部(想想它被替换为 - )该实例(或者在其原型链中具有原型的拥有对象)。

在你的情况下,构造函数(也是原型上的函数)被一个新创建的对象调用为"这个"使用" new"关键字。

Quo.prototype.get_status = function() {
    second = this; //this is myQuo
    return this.status;//second this
};

然后,第一个也被分配了完全相同的实例。

在同一个实例上调用get_status时,会再次使用实例替换它;

Quo.prototype.get_status.call(myQuo)

并且第二次被分配了相同的实例。

执行myQuo.get_status()与;

相同
echo

因此这两个"这个"关键字指的是同一个对象。

做" ==="如果两个变量指向同一个实例,则检查是完全正确的。获取构造函数名称只是告诉您它们是使用特定的构造函数名称构造的,否则。可以使用相同的构造函数名称创建两个不同的对象。

答案 1 :(得分:2)

此问题仅以JavaScript中的thiscontext为中心。

每当你提问什么是this你应该总是问自己这4个问题(按顺序),你总会得到答案。

  1. 是否使用new关键字调用了该函数?

    示例:var myObj = new Obj();

    这:新创建的对象

  2. 使用callapplybindthis调用此功能 上下文明确传递?

    示例:myFunction.call(self)

    这个:myFunction中的this将等于self

  3. 是通过包含/拥有对象调用函数吗?

    示例:myObj.myFunction()

    这个:myFunction中的this将等于myObj

  4. 什么是默认this上下文?

    这:如果在严格模式,则默认为未定义。如果不在严格模式,则默认为全局对象

  5. 所以,在你的情况下:

    first = this位于Quo函数内部,使用“new”关键字调用,因此first将等于新创建的对象。

    myQuo只是使用“new”关键字执行Quo函数的返回值,默认情况下返回新创建的对象,这就是为什么first === myQuo

    second = this位于get_status()函数内部,在调用函数之前没有任何意义。调用函数后,您可以看到上面的问题3 ,以查看this上下文是否绑定到拥有对象。由于它是使用myQuo.get_status()调用的,因此myQuo是拥有对象,这就是second === myQuo的原因。

    希望这可以解决所有问题!如果您需要其他解释,请告诉我们!

答案 2 :(得分:1)

  

第一个和第二个都指向myQuo吗?

更正它们都指向Quo的相同实例。

  

如何打印出每个指向的对象名称或函数名称或类名?

console.log(first.constructor.name);
console.log(second.constructor.name);

答案 3 :(得分:0)

以下是this在您提到的两种情况下如何运作的解释。首先,您需要了解根据函数的调用方式设置this(除非我们正在处理fat arrow functions

致电new

var myQuo = new Quo( "confused" );

它与做

基本相同
var myQuo = Object.create(Quo.prototype);
// Explicitly setting `this`
Quo.call(myQuo, "confused")

调用对象上的函数时

myQuo.get_status()

意味着get_status函数将使用.左侧的内容调用,即myQuo

  • 您现在永远不能拥有对象的名称(如果您的意思是将其命名为myQuo
  • 要获得对构造函数的引用,您可以执行myQuo.constructor(或this.constructor)。如果您的功能已命名(与您的相同),则可以使用this.constructor.name获取Quo