MENU
More About 'prototype', 'this, And 'new'
In JavaScript you first create an object, then you can modify your own object or create new objects from it. There is no concept of class that is comparable to those in some other languages.
All JavaScript objects, including functions, have an internal property, [[Prototype]]. Some JavaScript implementations allow direct access to [[Prototype]], eg. via __proto__. In general, that internal property is set during object creation, such as:
with new,
with Object.create()
with a literal / function definition(functions default to Function.prototype, numbers to Number.prototype, etc.).
Generally, there is only one way to read this internal property:
with Object.getPrototypeOf()
If you look up a property via o.p or o['p'], and the object does not have such a property -- which can be checked via o.hasOwnProperty('p') -- the runtime looks up the property in the object referenced by [[Prototype]] instead. If the prototype-object also doesn't have such a property, its prototype is checked, in turn, thus walking the original object's prototype chain. This allows us to simulate classes and inheritance in JavaScript.
As for 'this', outside any function, its initial value is Window in browsers, and {} in NodeJS.
console.log(this);When a 'new' keyword is encountered during execution, the following occurs, in the specified order:
A new object is created in the memory.
The new object's internal [[prototype]] property is bound to the external accessible prototype object.
'this' is bound to the new object.
The constructor function is executed, with accessibility to 'this'.
The newly created object is returned. If the constructor returns an object reference, the reference is returned instead.
You can set the value of 'this' using func.call(), func.apply(), or func.bind().
var C = function () {
console.log(this);
};
function f() {
console.log(this);
}
console.log(this);
var a = C();
var b = new C;
b.g = f;
b.g();
var c = {
h: function () {
console.log(this);
}
};
c.h();
var d = c.h;
d();
var e = {
i: function () {
eval("f()");
}
};
e.i();
var o = { a: 10 };
f.call(o);There are two places where 'this' behaves specially:
1) Arrow functions cannot act as constructors and cannot be used to instantiate an object with 'new'. Inside arrow functions, 'this' references the value of 'this' in the background lexical environment, ie. it is looked up in scope like a normal variable.
function C(x) {
this.v = x;
new function () {
console.log(this);
};
(() => {
console.log(this);
})();
}
new C(10);2) In a browser, in DOM event handlers, 'this' references the DOM object from which the event originates.
<!DOCTYPE html>
<html>
<head></head>
<body>
<input id="myButton" type="button" value="HI" onclick="alert(this.value)" />
<script>
document.getElementById("myButton").onclick = function () {
// no arrow function; overrides the above
alert("" + this.value + this.value);
}
</script>
</body>
</html>'this' behaves differently in JavaScript compared to other languages. In JavaScript the value of "this" depends on the "context" in which the function is executed, ie. where 'this' appears.
function C(d, callback) {
this.data = d;
f(function () {
console.log(this.data);
});
}
function f(cb) {
cb();
}
var o = new C('foo', f);function C(d, callback) {
this.data = d;
var self = this;
f(function () {
console.log(self.data);
});
}
function f(cb) {
cb();
}
var o = new C('Hello', f);function C(d, callback) {
this.data = d;
f(function () {
console.log(this.data);
}.bind(this));
}
function f(cb) {
cb();
}
var o = new C('Hello', f);function C(d, callback) {
this.data = d;
f(() => {
console.log(this.data);
});
}
function f(cb) {
cb();
}
var o = new C('Hello', f);