this this represents the current object. If this is used in the global scope, it refers to the current page object window; if this is used in a function, what this refers to is based on this function at runtime. On what object it is called. We can also use the two global methods apply and call to change the specific pointer of this in the function.
Let’s first look at an example of using this in the global scope:
This in the function is determined at runtime, not when the function is defined, as follows:
foo() {
console.log(.fruit);
}
fruit = ;
foo();
pack = {
fruit: ,
foo: foo
};
pack.foo();
Global functions apply and call can be used to change the pointer of this in the function, as follows:
foo() {
console.log(.fruit);
}
fruit = ;
pack = {
fruit:
};
foo.apply(window);
foo.apply(pack);
Note: The apply and call functions have the same effect. The only difference is that the two functions The parameter definitions are different .
Because functions are also objects in JavaScript, we can see the following interesting examples:
foo() {
( === window) {
console.log();
}
}
foo.boo = () {
( === foo) {
console.log();
} ( === window) {
console.log();
}
};
foo();
foo.boo();
foo.boo.apply(window);
prototype prototype is essentially a JavaScript object. And every function has a default prototype attribute.
If this function is used in the scenario of creating a custom object, we call this function a constructor. For example, the following is a simple scenario:
Person(name) {
.name = name;
}
Person.prototype = {
getName: () {
.name;
}
}
zhang = Person() ;
console.log(zhang.getName());
As an analogy, let’s consider the data types in JavaScript - String, Number, Array ), Object, Date, etc. We have reason to believe that these types are implemented as constructors inside JavaScript, such as:
Array() {
}
arr1 = Array(1, 56, 34, 12);
arr2 = [1, 56, 34, 12];
Many methods of operating on arrays (such as concat, join, push) should also be defined in the prototype attribute.
In fact, all intrinsic data types of JavaScript have read-only prototype attributes (this is understandable: because if the prototype attributes of these types are modified, the predefined methods disappear), but we can Add your own extension methods to it.
Array.prototype.min = () {
min = [0];
( i = 1; i < .length; i ) {
([i] < min) {
min = [i];
}
}
min;
};
console.log([1, 56, 34, 12].min());
Note: There is a trap here. After adding an extension method to the prototype of Array, this extension method will also be looped out when using for-in to loop the array.
The following code illustrates this (assuming that the min method has been extended to the Array prototype):
arr = [1, 56, 34, 12];
total = 0;
( i arr) {
total = parseInt(arr[i], 10);
}
console.log(total);
The solution is also very simple:
arr = [1, 56 , 34, 12];
total = 0;
( i arr) {
(arr.hasOwnProperty(i)) {
total = parseInt(arr[i], 10);
}
}
console.log(total);
constructor constructor always points to the constructor that created the current object. For example, the following example:
arr = [1, 56, 34, 12];
console.log(arr.constructor === Array);
Foo = () { };
console.log (Foo.constructor === Function);
obj = Foo();
console.log(obj.constructor === Foo);
console.log(obj.constructor.constructor === Function);
But when the constructor encounters prototype, something interesting happens.
We know that each function has a default attribute prototype, and the constructor of this prototype points to this function by default. As shown in the following example:
Person(name) {
.name = name;
};
Person.prototype.getName = () {
.name;
};
p = Person();
console.log( p.constructor === Person);
console.log(Person.prototype.constructor === Person);
console.log(p.constructor.prototype.constructor === Person);
When we redefined the prototype of the function (note: the difference from the above example, this is not a modification but an override), the behavior of the constructor was a bit strange, as shown in the following example:
Person(name) {
.name = name;
};
Person.prototype = {
getName: () {
.name;
}
};
p = Person();
console.log(p.constructor = == Person);
console.log(Person.prototype.constructor === Person);
console.log(p.constructor.prototype.constructor === Person);
Why?
It turns out that when overwriting Person.prototype, it is equivalent to the following code operation:
Person.prototype = Object({
getName: () {
.name;
}
});
while constructor Always points to the constructor that creates itself, so at this time Person.prototype.constructor === Object, that is:
Person(name) {
.name = name;
};
Person.prototype = {
getName: () {
. name;
}
};
p = Person();
console.log(p.constructor === Object);
console.log(Person.prototype.constructor == = Object);
console.log(p.constructor.prototype.constructor === Object);
How to correct this problem? The method is also very simple, just re-overwrite Person.prototype.constructor:
Person(name) {
.name = name;
};
Person.prototype = Object({
getName: () {
.name;
}
});
Person.prototype.constructor = Person;
p = Person();
console.log(p.constructor === Person);
console.log(Person. prototype.constructor === Person);
console.log(p.constructor.prototype.constructor === Person);