Каково объяснение для поведения 'этого' ключевого слова в JavaScript?

Поскольку Size имеет шаблон < # и цифру> или цифру после пробела, это переходит к аргументу sep.

  1. " #(?=[0-9])" находит шаблон, например " #1"
  2. " [0-9]" находит шаблон, например " 1"
  3. | означает или [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
8
задан Graeme Perrow 12 February 2009 в 17:18
поделиться

7 ответов

Вы, кажется, ожидаете, что это будет вести себя, как это делает на определенных языках OO, где это всегда относится к объекту, метод принадлежит.

Но в JavaScript, функция может быть присоединена к нескольким объектам или никакому объекту вообще. В Вашем примере Вы записали, что функция намеревалась использоваться в контексте одного конкретного объекта... Но ничто не препятствует тому, чтобы я брал ту функцию и присоединил ее к любому другому объекту. Это - просто природа языка - функции являются первоклассными, объектное членство является дополнительным.

Поэтому это относится к контексту, в котором вызвана функция. Прямо сейчас это - любой произвольный объект (указанный через ., .apply, или .call()) или глобальный объект. В будущих версиях языка это будет относиться к контексту, в котором была определена функция: глобальный объект для глобальных функций, внешнего this для внутренних функций; можно просмотреть это как исправление недостатка дизайна, поскольку в способности практики относиться к глобальному объекту с помощью этого не было особенно полезно.

11
ответ дан 5 December 2019 в 05:57
поделиться
  • Это не было
  • Много материала OO
  • Это хорошо способ, которым это
3
ответ дан 5 December 2019 в 05:57
поделиться

Рассмотрите идиому 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()
1
ответ дан 5 December 2019 в 05:57
поделиться
  • Это нужно назвать 'сам' вместо этого
  • Что-либо, что относится к текущему состоянию объектов.
  • Путем выбора 'сам' как название 'этого' и передачи его явно (как первый аргумент) ко всем методам. Таким образом, Вы можете легкий говорить метод экземпляра от статического метода или от функции.

Извините, но мне действительно нравится Python ;-)

1
ответ дан 5 December 2019 в 05:57
поделиться

Я думаю, развязал, "это" - ошибка. Иначе это довольно удобно. Развязанный "это" открывает возможность неверного истолкования контекста, наиболее заметно очевидного в обработке событий браузеров. Также библиотеки 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;};
}
3
ответ дан 5 December 2019 в 05:57
поделиться

Я не думаю, делая "это", развязал, была ошибка. Это может иногда сбивать с толку сначала, но существуют серьезные основания для способа, которым это. Первый, который приходит на ум, - то, что, так как 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;
};
8
ответ дан 5 December 2019 в 05:57
поделиться

Я думаю несвязанное, 'это' ключевое слово необходимо, потому что JavaScript является основанным на прототипе языком. Кто-то, которому лучше сообщают может, вероятно, заполнить детали здесь.

То, что это, сильно бесполезно все же. Особенно, если Вы хотите передать метод объекта к функции высшего порядка, вещи начинают становиться ужасными (следование примерам с небольшой справкой от MooTools):

myArray.each(myObject.foo);

Не будет работать, потому что 'это' в myObject.foo будет относиться к myArray вместо myObject. Вместо этого:

myArray.each(myObject.foo.bind(myObject))

Который кажется очень ужасным мне. Вот почему я обычно не программирую объектно-ориентированным способом в JavaScript, но я полагаюсь в большой степени на закрытия вместо этого.

1
ответ дан 5 December 2019 в 05:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: