在 js 中实例化对象之前,'this' 是什么? [英] What is 'this' before an object is instantiated in js?

查看:63
本文介绍了在 js 中实例化对象之前,'this' 是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白以下内容:

var x = function() {
    this.foo="foo";
    return function() {
        this.bar = "bar";
        return foo+bar;
    };
}(); // returns inner

alert(x()); // 'foobar', so both 'this' variables are set
alert(x.bar); // undefined - but wasn't it used correctly?
alert(new x().bar); // ok, works

我的假设是第一次生成并使用默认的this"范围/变量映射,然后当new"被调用时,一个带有新this"的新对象(函数?)通过并返回.或者,也许 x 不是一个合适的对象?但是,this"如何最终被设置并用于制作foobar"?

My assumption was that a default 'this' scope/variable-map is generated and used the first time, and then when 'new' is called, a new object (function?) with a new 'this' is sent through and returned. Or, perhaps x isn't a proper object? But then, how does 'this' end up being set and used to make 'foobar'?

我需要知道什么才能理解这一点?

What do I need to know to understand this?

推荐答案

首先让我们回顾一下 JavaScript 的一些细节,然后我们可以处理你的例子.

First let's go over some fine points of JavaScript, then we can deal with your example.

一个误解是上下文.每个函数都在上下文中调用,可以使用关键字 this 访问.让我们编写一个可以用来检查上下文的函数:

One point of misunderstanding is a context. Every function is called in a context, which is available using a keyword this. Let's write a function we can use to inspect contexts:

var probe = function(){
  // if the context doesn't have a name, let's name it
  if(!this.name){
    this.name = "lumberjack";
  }
  // print the name of my context
  console.log(this.name);
};

我们开始:

name = "global!";

// when we call a function normally it still have a context:
// the global context
probe(); // prints: global!

var ctx = {name: "ctx"};

// we can set a context explicitly using call()
probe.call(ctx); // prints: ctx

// we can set a context explicitly using apply()
probe.apply(ctx); // prints: ctx

// it is set implicitly, if we call a function as a member
ctx.fun = probe;
ctx.fun(); // prints: ctx

// or we can create a brand new object and set it as a context:
// that's what "new" does
var t = new probe(); // prints: lumberjack

// let's sum it up:
console.log(name);     // prints: global!
console.log(ctx.name); // prints: ctx
console.log(t.name);   // prints: lumberjack

这就是为什么很容易搞砸并在不经意间跌落到全局环境中的原因.

That's why it is so easy to mess up and fall down inadvertently to the global context.

当看到构造函数返回值时,许多人会感到困惑.这是合法的.构造函数可以返回一个对象、一个函数或一个数组.此值将用作实例.旧实例将被丢弃.

Many people are confused when they see a constructor returning a value. It is legal. Constructor can return an object, a function, or an array. This value is going to be used as an instance. The old instance is going to be discarded.

var myClass = function(){
  // if it is called as a constructor, "this" will be a new instance
  // let's fill it up:
  this.a = 42;
  this.b = "Ford";
  this.c = function(){ return "Perfect"; };
  // done? let's discard it completely!
  // and now for something completely different...
  return {
    owner: "Monty Python",
    establishment: "Flying Circus"
  };
};
var t = new myClass();
alert(t.owner + "'s " + t.establishment);

正如预期的那样,它显示了巨蟒的飞行马戏团".

As expected it shows "Monty Python's Flying Circus".

如果构造函数返回其他内容(例如,数字、字符串、空值、未定义),则将丢弃返回的结果并使用旧实例.

If a constructor returns something else (e.g., a number, a string, the null, the undefined) the returned result is going to be discarded and the old instance will be used.

您的示例很难理解,主要是因为它的编写方式.让我们通过重写来简化它.

Your example is hard to understand mostly because of the way it was written. Let's simplify it by rewriting.

首先让我们处理x:

var x = function() {
  this.foo = "foo";
  return function() {
    this.bar = "bar";
    return foo + bar;
  };
}(); // returns inner

我们可以看到匿名函数(1st function)立即执行,所以我们可以内联它:

As we can see the anonymous function (the 1st function) is executed immediately, so we can inline it:

// next assignment can be simplified because
// top "this" is window or the global scope
//this.foo = "foo"; =>
foo = "foo";
x = function() {
  this.bar = "bar"; // this line depends on its context, or "this"
  return foo + bar; // this line uses global "foo" and "bar"
};

所以最后我们有两个全局变量:foo(一个字符串)和 x(一个函数).

So at the end we have two global variables: foo (a string) and x (a function).

现在让我们回顾一下第一个st警报:

Now let's go over the 1st alert:

alert(x()); // 'foobar', so both 'this' variables are set

再次,让我们内联x():

// next assignment can be simplified because
// top "this" is window or the global scope
//this.bar = "bar"; =>
bar = "bar";
// at this moment both global "foo" and "bar" are set
alert(foo + bar); // => "foo" + "bar" => "foobar"

第二个nd警报同样简单:

alert(x.bar); // undefined - but wasn't it used correctly?

它不需要太多重写.x 是一个函数,我们没有给它添加任何属性,所以 x.bar 是未定义的.如果你添加它,你可以看到结果:

It doesn't need much rewriting. x is a function, we didn't add any properties to it, so x.bar is undefined. If you add it, you can see results:

x.bar = "bar2";
alert(x.bar); // bar2

第三个rd警报演示了 JavaScript 的 OOP:

The 3rd alert demonstrates JavaScript's OOP in action:

alert(new x().bar); // ok, works

(旁注:它仅在您首先运行 x() 时才起作用,否则它会因为 bar 未定义而爆炸.

(A side note: it works only because you ran x() first, otherwise it blows up because bar is undefined).

让我们像这样重写它:

var t = new x();
alert(t.bar); // bar

现在让我们分析构造函数.它有两个语句:赋值和返回.后者被忽略,因为它返回一个字符串.所以我们可以这样重写:

Now let's analyze the constructor. It has two statements: an assignment, and a return. The latter is ignored because it returns a string. So we can rewrite it like that:

x = function(){
  this.bar = "bar";
};
var t = new x();
alert(t.bar); // bar

我希望现在一切看起来都很简单.

I hope it all looks easy now.

这篇关于在 js 中实例化对象之前,'this' 是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆