对象构造函数内的范围

时间:2016-12-05 17:36:35

标签: javascript

我将构造函数Foo定义为:

function Foo () {
    var a= 0;
    this.b = 1;
    this.f1= function () { return a; };
    this.f2= function () { return b; };
}

我正在创建对象:

var bar= new Foo();

return b不起作用,我必须使用return this.b。但它适用于a变量。为什么呢?

3 个答案:

答案 0 :(得分:0)

您的函数声明了两种类型的构造。 var a是一个范围变量的普通变量,它在函数中是私有的。它可以以函数需要的任何方式使用,因此返回它完全没有问题。最重要的是,它的值不会从Foo的一个实例更改为下一个实例。

bf1f2未被声明为变量。它们被声明为“实例属性”,这意味着它们的数据将从对象的一个​​实例更改为另一个实例。如果要返回实例属性值,则必须使用this返回与该特定实例关联的值。

毕竟,如果你写了:

var obj1 = new Foo();
obj1.b = 10;

var obj2 = new Foo();
obj1.b = 20;

您如何才能将两个b值彼此分开?答案是您有两个Foo对象实例,obj1obj2变量各自存储对自己实例的引用。

编写obj1.b时,需要访问属于b对象实例的obj1属性。 this关键字为您执行此操作。

继续阅读以获取更多详情:

this对象绑定在JavaScript中是易失性的...也就是说,它并不总是指向同一个对象,并且它的绑定可以从一行代码更改为下一行代码。如何调用包含单词this的代码确定它将绑定到哪个对象。

以下是一份清单,您可以通过该清单了解this将绑定到哪个...

如果调用包含this的代码:

  1. 作为对象实例的方法或属性(通过实例变量):

    var o = new Object(); 
    
    // "this" will be bound to the "o" object instance
    // while "someProperty" and "someMethod" code executes
    o.someProperty = someValue;
    o.someMethod();
    
  2. 通过.call().apply().bind()Array.prototype.fn调用:

    // "this" will be bound to the object suppled as the "thisObjectBinding"
    someFunction.call(thisObjectBinding, arg, arg);
    someFunction.apply(thisObjectBinding, [arg, arg]);
    var newFunc = someFunction.bind(thisObjectBinding, arg, arg);
    

    此外,一些Array.prototype方法允许传递thisObject,这将在方法调用的持续时间内改变绑定:

    Array.prototype.every( callbackfn [ , thisArg ] )
    Array.prototype.some( callbackfn [ , thisArg ] )
    Array.prototype.forEach( callbackfn [ , thisArg ] )
    Array.prototype.map( callbackfn [ , thisArg ] )
    Array.prototype.filter( callbackfn [ , thisArg ] )
    
  3. 如果没有其他方案适用,则会发生默认绑定。

    3A。 "use strict"生效后thisundefined

    3B。没有"use strict"生效:this绑定到全局对象

  4. **注意:使用this也可能会影响eval()绑定,但作为一般的最佳做法,应避免使用eval()

答案 1 :(得分:0)

当你的功能

f1

被调用,它询问它的环境/背景"对不起,你知道什么是[a]是好的吗?"。它回应了#34;不是在这里,但是让我问一下我自己的环境/背景是否它知道[a]是什么......啊哈,它说它知道什么是[a],它是' s值为0."。

当你的功能

f2 

被调用,它要求它询问[b]与f1对[z]所做的相同的问题...不同的是,它为[b]查找的环境/上下文不包括Foo的实例已附加[b]。

'这'在JavaScript中是一个棘手的主题,在free online book中有很详细的介绍,这是该系列的一部分"你不知道JS",由Kyle Simpson。一个非常好的系列。

答案 2 :(得分:0)

它没有返回,因为没有声明b。

function Foo () {
    var a = 0;
    this.b = 1;
    var b = this.b;
    this.f1= function () { return a; };
    this.f2= function () { return b; };
}

应该可以正常工作。

或者你可以将f2方法绑定到"这个"并将其归还:

function Foo () {
    var a= 0;
    this.b = 1;
    this.f1= function () { return a; };
    this.f2= (function () { return this.b; }).bind(this);
}