可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a jquery class within a normal class in javascript. Is it possible to access variables in the scope of the parent class from a callback function in the jquery class?
A simple example of what I mean is shown below
var simpleClass = function () {
this.status = "pending";
this.target = jqueryObject;
this.updateStatus = function() {
this.target.fadeOut("fast",function () {
this.status = "complete"; //this needs to update the parent class
});
};
};
Now in the above example, the callback function tries to access the scope of the jquery object. is there any way to access the status variable in the parent class?
回答1:
You set "this" to a variable in the parent function and then use it in the inner function.
var simpleClass = function () {
this.status = "pending";
this.target = jqueryObject;
var parent = this;
this.updateStatus = function() {
this.jqueryObject.fadeOut("fast",function () {
parent.status = "complete"; //this needs to update the parent class
});
};
};
回答2:
I will post this answer to this old question anyway as no one yet posted this before.
You can use the bind
method on your function calls to define the scope which this
belongs to.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Normaly everytime you create a method - this
belongs to the current scope of the function. Variables from scope2 can't see variables from scope1.
e.g.
function(){
// scope 1
this.baz = 'foo';
function(){
// scope 2
this.baz // not defined
};
};
with the bind
method you can define the scope from this
inside the function. So using .bind(this)
you're telling the called function that their own scope from this
is referred to the scope of the parent function, like:
function(){
// scope 1
this.baz = 'foo';
function(){
// scope 1
this.baz // foo
}.bind(this);
};
so in your case, this would be an example using the bind
method
var simpleClass = function () {
this.status = "pending";
this.target = jqueryObject;
this.updateStatus = function() {
this.target.fadeOut("fast",function () {
this.status = "complete"; //this needs to update the parent class
}.bind(this));
}.bind(this);
};
回答3:
Use an Arrow Function
An arrow function does not have it's own this
. The this
value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this
which is not present in current scope they end up finding this
from its enclosing scope.
Normal function syntax
function(param1, param2) {}
Arrow function syntax
(param1, param2) => {}
Usage
const simpleClass = function () {
this.status = "pending";
this.target = jqueryObject;
this.updateStatus = function() {
this.target.fadeOut("fast", () => { // notice the syntax here
this.status = "complete"; // no change required here
});
};
};
Using an Arrow function within a ECMAScript 2015 Class
class simpleClass {
constructor() {
this.status = 'pending';
this.target = jqueryObject;
}
updateStatus() {
this.target.faceOut('fast', () => {
this.status = "complete";
});
}
}
const s = new simpleClass();
s.updateStatus();
Described code works only in modern browsers.
回答4:
Sorry m8. You have to nest the reference down into the objects like so:
var simpleClass = function () {
var _root = this;
this.status = "pending";
this.target = jqueryObject;
this.updateStatus = function() {
this.root = _root;
_root.target.fadeOut("fast",function () {
this.status = "complete"; //this needs to update the parent class
});
};
};
notice the var _root
回答5:
By setting "this" to a variable you can access easily. Like:
$("#ImageFile").change(function (e) {
var image, file;
var Parent=this;
if ((file = Parent.files[0])) {
var sFileExtension = file.name.split('.')[file.name.split('.').length - 1];
if (sFileExtension === "jpg" || sFileExtension === "jpeg" || sFileExtension === "bmp" || sFileExtension === "png" || sFileExtension === "gif") {
var reader = new FileReader();
reader.onload = function (e) {
alert(Parent.files[0].name);
};
reader.readAsDataURL(Parent.files[0]);
}
else { alert('Wrong file selected. Only jpg, jpeg, bmp, png and gif files are allowed.'); }
}
})
回答6:
try this:
var sc = (function(scc){
scc = {};
scc.target = jQueryObject;
scc.stt = "stt init";
scc.updateStatus = function(){
var elem = this;
this.target.click(function(){
elem.stt= "stt change";
console.log(elem.stt);
})
}
return scc;
}(sc || {}));
you can also define your target object as private variable
回答7:
You can mantain state using closure variables:
function simpleClass() {
var _state = { status: "pending", target: jqueryObject; }
this.updateStatus = function() {
this.target.fadeOut("fast",function () {
_state.status = "complete"; //this needs to update the parent class
});
}
}
// Later...
var classInstance = new simpleClass();