在“这个”关键字返回在Javascript对象的原型中的窗口对象?(The 'this

2019-08-02 07:13发布

我有一个类中的下列功能:

MyClass.prototype.myFunction = function(item, args) 
{       
    console.log(this);
}

这个功能是从我没有权限更改外部库调用。 当它被称为,控制台登录“本”作为窗口对象,而不是实际的实例化对象。 在搜索计算器,我发现这句话:

这是根据该方法如何根据该方法是怎么写的叫,而不是设置。 所以对于obj.method(),这将被设置为方法的内部OBJ()。 对于obj.method.call(x)时,该方法的()内将被设置为x。 它是由它怎么叫确定。 什么也意味着是,如果你把它作为一个回调的onclick例如,这将被设置为全局窗口对象,而不是你所期望的。

我假设这是怎么回事,我不能改变它的调用方式。 我的问题是,反正是有那么得到的对象实例及其不管它怎么叫?

Answer 1:

这与JavaScript的共同困惑。 人们很容易把它们当作表现得像扩展方法使用其他语言,但在Javascript中它是那么容易改变的背景下this ,它往往是由意外完成。

所以:

MyClass.prototype.myFunction = function(args) 
{
    // You expect [this] to refer to an instance of MyClass
    this.somePropertyOfMyClass;
};

然后,你可以调用这个:

var x = new MyClass();
x.myFunction(args)

然而,一个函数被调用JavaScript的方式可以改变什么this是指:

var y = somethingElse();
x.myFunction.call(y, args); // now in myFunction [this] refers to y

更有可能的是,很多图书馆都使用this上下文链接和事件-犯错容易。 例如jQuery中:

var $thing = $('.selector');
$thing.click(x.myFunction); // now in myFunction [this] refers to $thing

这可能是不明显写了jQuery,调用者x.myFunction这样会打破它。 他们可以变通方法(假设他们了解的实现)有:

$thing.click(function() { x.myFunction(); }); 

如果你希望你的MyClass是有弹性的,以被称为像这样的话就不要用prototype -而不是使用对象的属性:

function MyClass() {
    var self = this;
    // ...
    this.myFunction = function(args) 
    {
        // [self] will always refer to the current instance of MyClass
        self.somePropertyOfMyClass;
    };
}

需要注意的是更现代的浏览器的Javascript引擎是为优化这些类型的呼叫不错,所以我不会用的prototype一样,除非你已经确定你需要额外的性能优化。



Answer 2:

大概一个函数引用传递到其他函数来调用,而另一个功能是一样的东西:

function otherFunction(args, fn) {
    ...
    fn();
    ...
}

为了确保该方法获取this需要,你可以这样做:

// Create a local variable referencing the `this` you want
var instance = this;

// Pass a function that has a closure to the variable
// and sets the appropriate this in the call
otherFunction(args, function(){myMethod.call(instance)})

现在, thismyMethod将是什么instance的引用。 请注意,如果你改变的值instance调用后otherFunction ,被称为方法之前, myMethod将获得新的价值。

你可以处理,太多,如果这是一个问题。

哦,你也可以通过给每个实例它自己的方法,有一个封闭的情况下处理这个构造函数:

function MyObj(name) {
  var instance = this;
  instance.name = name;
  instance.getName = function() {
    return instance.name;
  }
}

var anObj = new MyObj('fred');

// Call as a method of anObj
alert(anObj.getName());  // fred 

// Pass method as a reference
var x = anObj.getName;

// Unqualified call
alert(x());  // fred    


Answer 3:

规则是:

this是从一个函数调用,它指的是全球客体(通常Window )。
this是由方法来调用,它指的是所有者对象(即当前对象在其中所使用的方法)。

例:

function Tryme() {

    var that = this

    function func2() {
        console.log("'this' from 'func2':", this)
    }

    function func3() {
        console.log("'that' from 'func3':", that)
    }

    this.method1 = function () {
        console.log("'this' from 'method1':", this)
    }

    this.method2 = function () {
        func2()
    }

    this.method3 = function () {
        func3()
    }
}

myinstance = new Tryme()

myinstance.method1() // displays the object 'myinstance'
myinstance.method2() // displays the object 'Window'
myinstance.method3() // displays the object 'myinstance'

在本例中,会发生什么?

当你调用.method1()和你显示this ,你是目前在对象的方法myinstance 。 因此, this将参照对象本身(即myinstance )。

当你调用.method2()这个方法会调用该对象中的局部功能myinstance称为func2() 该函数func2()是一个函数,而不是一个方法,所以this是指全局对象Window

当你调用.method3()这个方法会调用该对象中的局部功能myinstance称为func3() 该函数func3()是一个函数,而不是一个方法,所以this是指全局对象Window (如在func2() 但在func3()我们正在显示的内容that ,这是内的局部变量myinstance对象。 that是已经初始化的值的对象thisthis指的是所有者对象(即myinstance )。 在JavaScript中,如果初始化object2与价值object1object2 = object1 ),那么当你改变一个对象的值,其他对象的值也可能发生变化。 所以that总是引用的值this是的一个myinstance ,即使当值this变化。 请记住this是指对象关联的关键字,它不是一个变量。

什么你的情况发生?

你叫this从一个函数,所以this指的是全局对象( Window )。

@Keith建议可以做些什么,即。 创建一个对象,其中您将创建一个self (或者that )对象,等于this你感兴趣的,然后使用该实例的self对象的功能(这将引用this对象,你有兴趣) 。

更多信息

这里: https://www.w3schools.com/js/js_this.asp
这里: https://crockford.com/javascript/private.html



Answer 4:

一个解决将是有副本myFunction()为每个实例,即在构造函数而不是它的原型创建它,因为这样你可以有一个参考this存储在构造函数中的局部变量:

function MyClass() {
    var self = this;
    this.myFunction = function(item, args) {
        // use self instead of this
        console.log(self);
    };
    // other constructor code here
}

但当然,创造了每一个实例功能使用更多的内存 - 取决于你的函数的大小可能会或可能不会是一个问题。 一种折衷的可能是把一个包装为你的函数在构造函数中,并定义对样机的实际功能:

function MyClass() {
    var self = this;
    this.myFunction = function(item, args) {
        return self.wrappedMyFunction(item, args);
    };

    // your other constructor code here
}    
MyClass.prototype.wrappedMyFunction = function(item, args) 
{       
    console.log(this);
}


文章来源: The 'this' keyword returns the window object within an object's prototype in Javascript?