简体   繁体   English

对象构造函数内部的作用域

[英]Scope Inside The Object Constructor Function

I am defining the consctructor function Foo as: 我将构造函数Foo定义为:

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

and I am creating the object as: 我将对象创建为:

var bar= new Foo();

return b does not work, I have to use return this.b instead. return b不起作用,我必须使用return this.b代替。 But it work fine with the a variable. 但是,使用a变量可以正常工作。 Why? 为什么?

Your function declares two types of constructs. 您的函数声明了两种类型的构造。 var a is a normal variable that is scoped to the function and it is private within the function. var a是作用域范围内的普通变量,在函数内是私有的。 It can be used any way the function needs to, so returning it is no problem at all. 可以以函数需要的任何方式使用它,因此返回它根本没有问题。 Most importantly, its value will not change from one instance of Foo to the next. 最重要的是,它的值不会从一个Foo实例更改为另一个实例。

b , f1 and f2 aren't being declared as variables. bf1f2没有被声明为变量。 They are being declared as "instance properties", meaning that their data will change from one instance of the object to another. 它们被声明为“实例属性”,这意味着它们的数据将从对象的一个​​实例更改为另一个。 If you want to return an instance property value, you must use this to return the value associated with that particular instance. 如果要返回实例属性值,则必须使用this来返回与该特定实例关联的值。

After all, if you wrote: 毕竟,如果您写了:

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

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

How would you be able to keep the two b values separate from each other? 您如何能够将两个b值彼此分开? The answer is that you have two instances of a Foo object and the obj1 and obj2 variables each store a reference to their own instance. 答案是,您有两个Foo对象的实例,而obj1obj2变量各自存储对自己实例的引用。

When you write obj1.b , you need access to the b property that belongs to the obj1 object instance. 编写obj1.b ,需要访问属于obj1对象实例的b属性。 The this keyword does this for you. this关键字为您完成此操作。

Read on for more details: 请阅读以获得更多详情:

The this object binding is volatile in JavaScript...that is, it doesn't always point to the same object and its binding can change from one line of code to the very next. this对象绑定在JavaScript中是易变的……也就是说,它并不总是指向同一对象,并且其绑定可以从一行代码更改为另一行代码。 How you invoke the code that contains the word this determines what object it will bind to. 如何调用包含单词this的代码将确定它将绑定到的对象。

Here's a checklist that you can follow to know what this will bind to... 下面是您可以遵循知道清单this将绑定到...

If the code that contains this is invoked: 如果包含this代码的代码被调用:

  1. As a method or property of an object instance (through an instance variable): 作为对象实例的方法或属性(通过实例变量):

     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. Via a .call() , .apply() , .bind() or Array.prototype.fn invocation: 通过.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); 

    Additionally, several Array.prototype methods allow for a thisObject to be passed which will alter the binding for the duration of the method call: 另外,一些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. If none of the other scenarios apply, Default binding occurs. 如果没有其他情况适用,则发生默认绑定。

    3a. 3a。 With "use strict" in effect: this is undefined 生效"use strict"thisundefined

    3b. 3b。 Without "use strict" in effect: this binds to the Global object 没有有效的"use strict"this绑定到全局对象

** NOTE: this binding can also be affected by using eval() , but as a general best practice, the use of eval() should be avoided. **注意: this绑定也可以通过使用eval()来影响,但作为一般的最佳实践,应避免使用eval()

When your function 当你的功能

f1

is invoked, it asks it's environment/context "Excuse me, do you have any idea what [a] is please?". 被调用时,它询问其环境/上下文“对不起,您知道[a]是什么吗?”。 It responds with "Not here, but let me ask my own environment/context whether or not it knows what [a] is... ah hah, it says it knows what [a] is, and it's value is 0.". 它的回答是“不在这里,但让我问自己的环境/上下文是否知道[a]是什么...啊哈,它说它知道[a]是什么,并且它的值为0。”。

When your function 当你的功能

f2 

is invoked, it asks it asks the same question of [b] as f1 did for [z]... the difference is, the environment/context it is looking in for [b] does not include the instance of Foo to which [b] has been attached. 被调用时,它询问它是否与f1对[z]询问相同的[b]问题...区别是,它正在寻找[b]的环境/上下文不包含[ b]已附加。

'this' in JavaScript is a tricky subject, and is covered in great detail in this free online book which is part of the series "You don't know JS", by Kyle Simpson. JavaScript中的“ this”是一个棘手的主题,这本免费的在线书对此进行了详细介绍, 该书是Kyle Simpson 撰写的“ You't know JS”系列的一部分。 A very good series. 一个很好的系列。

It doesn't return because b is not declared. 它不会返回,因为未声明b。

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

should work fine. 应该工作正常。

Or you can bind f2 method to "this" and return it: 或者,您可以将f2方法绑定到“ this”并返回:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM