Здесь является одним из хороших источников this
в JavaScript
.
Вот сводка:
this
является объектом window
Если вы используете use strict;
, в котором case this
будет undefined
Если вы вызываете функцию с new
, this
будет новым контекстом, он не будет ссылаться на глобальный this
.
Функции, которые вы создаете, становятся объектами функции. Они автоматически получают специальное свойство prototype
, которое вы можете присвоить значениям. Когда вы создаете экземпляр, вызывая функцию с помощью new
, вы получаете доступ к значениям, присвоенным свойству prototype
. Вы получаете доступ к этим значениям с помощью this
.
function Thing() {
console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
Обычно ошибка заключается в назначении массивов или объектов на prototype
. Если вы хотите, чтобы экземпляры каждого имели свои собственные массивы, создайте их в функции, а не в прототипе.
function Thing() {
this.things = [];
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
Вы можете использовать this
в любой функции объекта ссылаться на другие свойства этого объекта. Это не то же самое, что и экземпляр, созданный с помощью new
.
var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
В обработчике событий HTML DOM this
всегда ссылается на элемент DOM, событие было присоединено к
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs ""
}
var listener = new Listener();
document.getElementById("foo").click();
Если вы не bind
контекст
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById("foo").click();
Внутри атрибутов HTML, в которые вы можете поместить JavaScript, this
является ссылкой на элемент.
Вы можете использовать eval
для доступа к this
.
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
Вы можете использовать with
, чтобы добавить this
в текущую область действия, чтобы читать и записывать значения на this
, явно не ссылаясь на this
.
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with (this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
jQuery во многих местах имеет this
ссылается на элемент DOM.
Одна конструкция, на которую я когда-то наткнулся, выглядела как
Class<T> persistentClass = (Class<T>)
((ParameterizedType)getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
Так что, похоже, есть некоторая магия отражения вокруг, которую я к сожалению, не совсем понимаю ... Извините.
Это невозможно, потому что универсальные шаблоны в Java рассматриваются только во время компиляции. Таким образом, дженерики Java - это всего лишь своего рода препроцессор. Однако вы можете получить фактический класс членов списка.
Нет, это невозможно. Из-за проблем совместимости снизу, обобщения Java основаны на стирании типа , например, во время выполнения, все, что у вас есть, - это не общий объект List
. Есть некоторая информация о параметрах типа во время выполнения, но она находится в определениях классов (т. Е. Вы можете спросить «, какой общий тип используется в определении этого поля? »), а не в экземплярах объектов.
Нет, это невозможно.
Вы можете получить общий тип поля, учитывая, что класс является единственным исключением из этого правила, и даже это немного уловка.
] См. Знание типа обобщенного в Java для примера.
Из-за стирания типа единственный способ узнать тип списка - это передать тип в качестве параметра методу:
public class Main {
public static void main(String[] args) {
doStuff(new LinkedList<String>(), String.class);
}
public static <E> void doStuff(List<E> list, Class<E> clazz) {
}
}