为什么这是javascript的输出?

时间:2016-05-23 05:39:39

标签: javascript this

var name = 'bob';
var someObject = {
    name: 'james',
    someProperty: {
         name: 'sam',
         getName: function(){
             return this.name;
         }
    }
}

var testing = someObject.someProperty.getName;

testing();

这个代码块返回'bob'的原因是因为我们最终只是在全局对象的名称上调用this.name,这是'bob'还是有更好的方法来考虑这个问题?谢谢!

6 个答案:

答案 0 :(得分:4)

  

this的值取决于函数的调用方式。

testing()被调用为window.testing(),因此this引用windowvar name引用global(scope of window)"bob"归还。

您可以使用.call的{​​ES5'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call}来指定this上下文来获取"sam"

call()方法调用具有给定this值的函数

使用.bind()this-reference中拥有指定的function-body上下文, bind()方法创建一个新函数,在调用时,其{{1} }}关键字设置为提供的值,在调用新函数时提供的任何参数序列前面提供。

this

答案 1 :(得分:1)

在Chrome开发者控制台中运行上述代码我得到了以下输出:

输入:

var testing = someObject.someProperty.getName;
testing();

输出:

"bob"

但后来我改为:

输入:

var testing = someObject.someProperty.getName();
testing;

输出:

"sam"

那么,在第一个场景中,"测试"成为一个函数对象,它将返回全局" name"的值。变量。 "测试"与#34; someObject"无关。在这种情况下。这类似于:

// global scope
var testing = function() {
    return this.name;
}

在第二种情况下,"测试"只是" someObject.someProperty.getName()"的返回值。

答案 2 :(得分:0)

当您调用测试时,将在没有对象上下文的情况下调用该函数,并且全局上下文用于此指针。全局上下文中的this.name是'bob',因此是结果。调用someObject.someProperty.name()将返回'sam'。如果你想让它返回'james',你需要这样称呼它:

someObject.someProperty.getName.call(someObject);

或:

var testing = someObject.someProperty.getName.bind(someObject);
testing();

答案 3 :(得分:0)

var name = 'bob';
var someObject = {
   name: 'james',
   someProperty: {
      name: 'sam',
      getName: function() {
         console.log(this);
         return this.name;
      }
   }
}
var testing = someObject.someProperty.getName;
testing()

Window {external: Object, chrome: Object, customElements: undefined, originalOutline: undefined, someObject: Object…}

当我尝试这个时,注意到我(这个)的结果是如何打印的,它指的是全局"这个"。这不是我们想要的。 如果我想打印"sam",我会这样做,以重新定义"这个"装置

 testing.bind(someObject.someProperty)(). // returns "sam"

此外,您还可以这样做:

var name = 'bob';
var someObject = {
   name: 'james',
   someProperty: {
       name: 'sam',
       getName: function() {
          return this.name;
       }.bind(someObject.someProperty)
    }
 }
 var testing = someObject.someProperty.getName;

当你打电话给它时,这将返回"sam",无论"这是什么"上下文。

另一种方法是保留原始代码,而不是设置

var testing = someObject.someProperty.getName;

而是将其更改为:

var testing = someObject.someProperty.getName();

现在,这个对象使用someProperty的上下文引用getName()函数。

答案 4 :(得分:0)

我相信你将这个简单的对象文字对象构造器混合在一起。对象文字someObject不会自动使用this - 它与一堆变量几乎相同。

var name = 'bob';
var someObject = {}
someObject.name = 'james'
someObject.someProperty = {};
someObject.someProperty.name = 'sam';
someObject.someProperty.getName = function(){
    return this.name; // global context
}

您可以通过以下几种方式近似实例化,_然后在{javascript'中使用this

使用Object.create

将对象文字someObject传递给Object.create()将为this创建一个新的上下文,如您所料:

var name = 'bob';
var someObject = {
    name: 'james',
    someProperty: {
         name: 'sam',
         getName: function(){
             return this.name;
         }
    }
}

var aNewContext = Object.create(someObject);

aNewContext.someProperty.getName();
// "sam"

使用函数构造函数

当您将关键字new与函数一起使用时,它还会创建一个新对象并将其分配给this。添加到原型的函数可以作为方法调用,也可以引用this

function SomePropertyConstructor() {
    this.name = 'sam';
}
SomePropertyConstructor.prototype.getName = function(){
    return this.name;
}


var name = 'bob';
var someObject = {
    name: 'james',
    someProperty: new SomePropertyConstructor()
}


someObject.someProperty.getName();
// "sam"

注意 - 如果您自己调用该函数,则需要使用bind来控制上下文:

var unbound = someObject.someProperty.getName;
[ unbound(), unbound.bind(someObject.someProperty)()]
//["bob", "sam"]

答案 5 :(得分:0)

要添加,如果要使用函数获取switch(toss){ case 0 : out.println("tails"); break; // Here case 1 : out.println("heads"); break; // And here } ,可以将函数调用包装在另一个函数中:

sam