Поскольку Size
имеет шаблон < #
и цифру> или цифру после пробела, это переходит к аргументу sep
.
" #(?=[0-9])"
находит шаблон, например " #1"
" [0-9]"
находит шаблон, например " 1"
|
означает или [119 ] В сумме, ( Предполагая, что эти виды шаблонов не встречаются в имени элемента )
library(tidyverse)
x <- paste(sort(rep(LETTERS[1:4], 3)), paste0(rep("#", 3), rep(11:13, 3)))
y <- paste(sort(rep(LETTERS[1:4], 2)), paste0(rep(1:2, 2), rep("/0", 2)))
mydf <- data_frame(Item = c(x, y))
#---------------------------------
mydf %>%
separate(Item, into = c("Item", "Size"), sep = " #(?=[0-9])| (?=[0-9])")
#> # A tibble: 20 x 2
#> Item Size
#> <chr> <chr>
#> 1 A 11
#> 2 A 12
#> 3 A 13
#> 4 B 11
#> 5 B 12
#> 6 B 13
#> 7 C 11
#> 8 C 12
#> 9 C 13
#> 10 D 11
#> 11 D 12
#> 12 D 13
#> 13 A 1/0
#> 14 A 2/0
#> 15 B 1/0
#> 16 B 2/0
#> 17 C 1/0
#> 18 C 2/0
#> 19 D 1/0
#> 20 D 2/0
Вы, кажется, ожидаете, что это будет вести себя, как это делает на определенных языках OO, где это всегда относится к объекту, метод принадлежит.
Но в JavaScript, функция может быть присоединена к нескольким объектам или никакому объекту вообще. В Вашем примере Вы записали, что функция намеревалась использоваться в контексте одного конкретного объекта... Но ничто не препятствует тому, чтобы я брал ту функцию и присоединил ее к любому другому объекту. Это - просто природа языка - функции являются первоклассными, объектное членство является дополнительным.
Поэтому это относится к контексту, в котором вызвана функция. Прямо сейчас это - любой произвольный объект (указанный через .
, .apply
, или .call()
) или глобальный объект. В будущих версиях языка это будет относиться к контексту, в котором была определена функция: глобальный объект для глобальных функций, внешнего this
для внутренних функций; можно просмотреть это как исправление недостатка дизайна, поскольку в способности практики относиться к глобальному объекту с помощью этого не было особенно полезно.
Рассмотрите идиому a.f()
как сокращение от:
a.f.call(a);
Это - по определению вызов к функции f
, использование объема a
.
var f = a.f;
f(); // f.call(this);
a.f(); // f.call(a);
Если this
и a
не тот же объект, f()
и a.f()
будет использовать различные объемы и поэтому может вести себя по-другому. Рассмотрите различие между статическими методами и методами класса на других языках:
class Foo {
public:
static void a(Foo *scope) {
// do something with given scope
};
void b() {
a(this); // do something with the scope of this object
};
};
Foo foo;
Foo bar;
foo.a(&bar) != foo.b(); // just like f() != a.f()
foo.a(&foo) == foo.b(); // just like f.call(a) == a.f()
Извините, но мне действительно нравится Python ;-)
Я думаю, развязал, "это" - ошибка. Иначе это довольно удобно. Развязанный "это" открывает возможность неверного истолкования контекста, наиболее заметно очевидного в обработке событий браузеров. Также библиотеки JavaScript имеют различные мнения о том, к чему "это" должно относиться в обработке событий и многих конструкциях обратного вызова (как карта, фильтр).
Удаление развязало, "это", вероятно, не будет больше делать вещи трудными.
Править: Я предполагаю, что альтернативный пример синтаксиса сделает мою позицию более ясной.
function Foo()
{
//both this refer to the Foo instance
this.blah=this.function(){this.bar;};
//second this refers to baz
this.blah=baz.function(){this.bar;};
//second this refers to anonymous function itself
this.blah=function(){this.bar;};
}
Я не думаю, делая "это", развязал, была ошибка. Это может иногда сбивать с толку сначала, но существуют серьезные основания для способа, которым это. Первый, который приходит на ум, - то, что, так как JavaScript не является основанным на классе языком, функции не связаны ни с каким определенным классом, таким образом, нет последовательного способа автоматически связать "это" с экземпляром правильного объекта. Например,
function Person(first, last, age) {
this.firstName = first;
this.lastName = last;
this.age = age;
}
Person.prototype.getFullName = function() {
return this.firstName + " " + this.lastName;
};
"это" должно относиться к объекту Человека, но функция, присвоенная Person.prototype.getName, не имеет никакого способа знать, как это будет используемым, таким образом, "это" должно быть связано с любым объектом, к этому обращаются.
То, где это вызывает проблему, когда у Вас есть вложенные функции.
// This is a really contrived example, but I can't think of anything better
Person.prototype.getInfo = function() {
// get name as "Last, First"
function getNameLastFirst() {
// oops. "this" is the global object, *not* the Person
return this.lastName + ", " + this.firstName;
}
// expect something like "Crumley, Matthew: Age 25",
// but you get "undefined, undefined: Age 25"
return getNameLastFirst() + ": Age " + this.age;
};
Синтаксис artificialidiot предложенный был бы удобен, но довольно легко связать, "это" к использованию конкретного объекта применяется:
function bind(func, obj) {
return function() {
return func.apply(obj, arguments);
};
}
Person.prototype.getInfo = function() {
// get name as "Last, First"
var getNameLastFirst = bind(function () {
return this.lastName + ", " + this.firstName;
}, this);
return getNameLastFirst() + ": Age " + this.age;
};
или более "традиционный" метод с помощью закрытий:
Person.prototype.getInfo = function() {
var self = this;
// get name as "Last, First"
function getNameLastFirst() {
return self.lastName + ", " + self.firstName;
}
return getNameLastFirst() + ": Age " + this.age;
};
Я думаю несвязанное, 'это' ключевое слово необходимо, потому что JavaScript является основанным на прототипе языком. Кто-то, которому лучше сообщают может, вероятно, заполнить детали здесь.
То, что это, сильно бесполезно все же. Особенно, если Вы хотите передать метод объекта к функции высшего порядка, вещи начинают становиться ужасными (следование примерам с небольшой справкой от MooTools):
myArray.each(myObject.foo);
Не будет работать, потому что 'это' в myObject.foo будет относиться к myArray вместо myObject. Вместо этого:
myArray.each(myObject.foo.bind(myObject))
Который кажется очень ужасным мне. Вот почему я обычно не программирую объектно-ориентированным способом в JavaScript, но я полагаюсь в большой степени на закрытия вместо этого.