Здесь является одним из хороших источников 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.
Есть много подходов к этому,
Учитывая
var lines = File.ReadLines(@"D:\Test.txt");
Примечание : File.ReadLines
возврат Enumerbale
, поэтому он будет загружать каждую строку лениво
Вариант 1 : регулярное выражение с использованием Положительного отстранения и шаблона (?<=2:\[X:)\d+
[ 1123]
foreach (var line in lines)
{
var match = Regex.Match(line,@"(?<=2:\[X:)\d+");
if(match.Success)
Console.WriteLine(match.Value);
}
Вариант 2 : Простой string.Split
foreach (var line in lines)
{
var results = line.Split(new[] { "2:[X:", "][Y:" }, StringSplitOptions.RemoveEmptyEntries);
if(results.Length>1)
Console.WriteLine(results[1]);
}
Вариант 3 : «Возможно», более производительный подход с использованием [1115 ] Указатели fixed
и unsafe
public static unsafe (bool found, int value) ParseLine(string line)
{
const string prefix = "2:[X:";
fixed (char* pLine = line,pPrefix = prefix)
{
var pLen = line.Length + pLine;
var found = false;
var result = 0;
var i = 0;
for (char* p = pLine ,pP = pPrefix; p < pLen; p++)
{
if (!found )
{
if( *p == *(pP+i)) i++;
if( i ==prefix.Length) found = true;
continue;
}
if (*p < '0' || *p > '9')
break;
result = result * 10 + *p - '0';
}
return (found, result);
}
}
...
var results = File.ReadLines(@"D:\Test.txt")
.Select(ParseLine)
.Where(result => result.found)
.Select(result => result.value);
foreach (var result in results)
Console.WriteLine(result);
Примечание : речь идет не об использовании регулярных выражений, а о различных подходах. [ 1126]
Я не отмечал это, однако я подозреваю, что Указатели будут самыми быстрыми, split
будут следующими, а Regex , возможно, будут самыми медленными (даже если используя скомпилированный), однако это наиболее читаемый и поддерживаемый, а также надежный подход (именно поэтому я поставил его первым)
+----------+------------+-----------+-----------+
| Method | Mean | Error | StdDev |
+----------+------------+-----------+-----------+
| RegEx | 3,358.3 us | 65.169 us | 66.923 us |
| Split | 1,980.9 us | 38.440 us | 48.614 us |
| Pointers | 287.4 us | 4.396 us | 4.112 us |
+----------+------------+-----------+-----------+
Тестовый код [ 1128]
public class Test
{
private Regex _regex;
private string[] data;
[GlobalSetup]
public void Setup()
{
_regex = new Regex(@"(?<=2:\[X:)\d+", RegexOptions.Compiled);
data = File.ReadLines(@"D:\Test3.txt")
.ToArray();
}
[Benchmark]
public List<int> RegEx()
{
return data.Select(line => _regex.Match(line))
.Where(x => x.Success)
.Select(match => int.Parse(match.Value))
.ToList();
}
[Benchmark]
public List<int> Split()
{
return data.Select(line => line.Split(new[] { "2:[X:", "][Y:" }, StringSplitOptions.RemoveEmptyEntries))
.Where(results => results.Length > 1)
.Select(results => int.Parse(results[1]))
.ToList();
}
[Benchmark]
public List<int> Pointers()
{
return data.Select(ParseLine)
.Where(result => result.found)
.Select(result => result.value)
.ToList();
}
public static unsafe (bool found, int value) ParseLine(string line)
{
const string prefix = "2:[X:";
fixed (char* pLine = line,pPrefix = prefix)
{
var pLen = line.Length + pLine;
var found = false;
var result = 0;
var i = 0;
for (char* p = pLine ,pP = pPrefix; p < pLen; p++)
{
if (!found )
{
if( *p == *(pP+i)) i++;
if( i ==prefix.Length) found = true;
continue;
}
if (*p < '0' || *p > '9')
break;
result = result * 10 + *p - '0';
}
return (found, result);
}
}
}