I'm sorry to ask such a basic question but despite lots of reading on javascript over the last few months and on this issue specifically, I'm just not getting something about it's execution context and "this". So I'm hoping an explanation using my specific scenario will help. I have a constructor in which I have some local functions and some exposed functions (mimicking public/private methods).
function blog() {
if (!(this instanceof blog))
return new blog();
function internal(){
alert(this);
}
this.external = function(){
alert(this);
internal();
}
}
var b = new blog();
b.external();
In external
, "this" is b, an instance of blog as I expect. I was wrongfully expecting this to hold true inside internal
as well, but it's actually the global window object. As an experiment I tried changing external
's call to this.internal()
which gives an error that this.internal is not a function. This is when I realized I'm really not following how it's working. Ok, I haven't defined a property of blog named internal, but if internal isn't a function defined on my blog instance, what is it and where is it defined? Maybe I have this structured wrong.
Please see xdazzs answer here: https://stackoverflow.com/a/12241726/2469255
However, to solve your problem you need to define what this
is to that function.
Your internal call is called without providing a this context so it binds to the global object, unlike you this.external which has scoped it to the blog object. rewriting your code as follows will solve this:
function blog() {
if (!(this instanceof blog))
return new blog();
function internal(){
console.log(this);
}
this.external = function(){
console.log(this);
internal.bind(this);
internal.call(this); // this in internal will be the object blog.
}
}
var b = new blog();
b.external(); //blog {external: function} blog {external: function}
Alternatively a lot of people prefer the var self = this
to ensure problems like this don't occur and you know exactly what's being set, where. There's a lot of contention over that particular thought so YMMV
Let me try to explain.
This piece of code bellow will only be reachable, if you simple call blog()
without a new
key word.
if (!(this instanceof blog))
return new blog();
But, this is not a recommended pratice, cause it's affecting the clearly of your code.
Because this:
var realObj = new Blog();
is the right code to instantiate an Object and the code bellow:
var obj = blog();
are not clear enough and could guide you to mistakes.
JavaScript have originally a Prototypal Inheritance and you have a better explaination here from Douglas Crockford.
The main reason that internal()
don't have the same reference from external
is because internal have a scope pointing to global and when you create an instance of blog the external scope are pointing to object blog.
Really confuse because this
inside the declaration of blog are pointing to global, so why when you instantiate blog this
change?
When browser start to read your code, it put what it found in memory, referencing by the scope. Remember scope are controlled with {}
, so when he found your declaration this.external
he associate to the scope and when you declare using new
this
become the scope of the object so this
don't refer anymore to global scope.
take a look at this code at jsbin.com
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.