Зачем нам нужно & ldquo; this & rdquo; ключевое слово при установке функции обратного вызова в React? [Дубликат]

Мне нужно было напечатать ВСЕ строки после шаблона (ok Ed, REGEX), поэтому я остановился на этом:

sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern

Но так как я хотел напечатать все строки AFTER (и исключить pattern)

sed -n '/pattern/,$p' | tail -n+2  # all lines after first occurrence of pattern

Я полагаю, что в вашем случае вы можете добавить head -1 в конец

sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern
30
задан Chaosed0 16 November 2012 в 16:45
поделиться

6 ответов

JavaScript не имеет объектной модели класса на основе классов. Он использует более мощное прототипическое наследование, которое может имитировать классы, но для него не подходит. Все это объект, а объекты [могут] наследовать от других объектов.

Конструктор - это просто функция, которая присваивает свойства вновь созданным объектам. Объект (созданный вызовом с ключевым словом new ) может быть указан через ключевое слово this (которое является локальным для функции).

Метод также является просто функцией, которая называется на объектом - снова с this, указывающим на объект. По крайней мере, когда эта функция вызывается как свойство объекта, используя оператор -члена (точка, скобки). Это вызывает много путаницы для новичков, потому что если вы передадите эту функцию (например, прослушивателю событий), она «отделится» от объекта, к которому он был обращен.

Теперь, где наследование? Экземпляры «класса» наследуются от одного и того же прототипа. Методы определяются как свойства функции для этого объекта (вместо одной функции для каждого экземпляра), экземпляр, на который вы их называете, просто наследует это свойство.

Пример:

function Foo() {
    this.bar = "foo"; // creating a property on the instance
}
Foo.prototype.foo = 0; // of course you also can define other values to inherit
Foo.prototype.getBar = function() {
    // quite useless
    return this.bar;
}

var foo = new Foo; // creates an object which inherits from Foo.prototype,
                   // applies the Foo constructor on it and assigns it to the var
foo.getBar(); // "foo" - the inherited function is applied on the object and
              // returns its "bar" property
foo.bar; // "foo" - we could have done this easier.
foo[foo.bar]; // 0 - access the "foo" property, which is inherited
foo.foo = 1;  // and now overwrite it by creating an own property of foo
foo[foo.getBar()]; // 1 - gets the overwritten property value. Notice that
(new Foo).foo;     // is still 0

Таким образом, мы использовали только свойства этого объекта и довольны им. Но все они являются «общедоступными» и могут быть перезаписаны / изменены / удалены! Если это не важно, вам повезло. Вы можете указать «приватность» свойств, префикс их имен с подчеркиваниями, но это только намек на других разработчиков и может не выполняться (особенно по ошибке).

Итак, умные умы нашли решение, которое использует функцию-конструктор как замыкание, позволяя создавать частные «атрибуты». Каждое выполнение функции javascript создает новую переменную среды для локальных переменных, которая может получить сбор мусора после завершения выполнения. Каждая функция, объявленная внутри этой области видимости, также имеет доступ к этим переменным, и пока эти функции могут быть вызваны (например, прослушивателем событий), среда должна сохраняться. Таким образом, посредством экспорта локально определенных функций из вашего конструктора вы сохраняете эту переменную среду с локальными переменными, к которым могут быть доступны только эти функции.

Давайте посмотрим на нее в действии:

function Foo() {
    var bar = "foo"; // a local variable
    this.getBar = function getter() {
        return bar; // accesses the local variable
    }; // the assignment to a property makes it available to outside
}

var foo = new Foo; // an object with one method, inheriting from a [currently] empty prototype
foo.getBar(); // "foo" - receives us the value of the "bar" variable in the constructor

Эта функция getter, которая определена внутри конструктора, теперь называется « привилегированным методом», поскольку она имеет доступ к «частным» (локальным) «атрибутам» (переменные ). Значение bar никогда не изменится. Вы также можете объявить для него функцию setter, и с этим вы можете добавить некоторую проверку и т. Д.

Обратите внимание, что методы объекта-прототипа не имеют доступа к локальным переменным конструктора, но они могут использовать привилегированные методы. Давайте добавим один:

Foo.prototype.getFooBar = function() {
    return this.getBar() + "bar"; // access the "getBar" function on "this" instance
}
// the inheritance is dynamic, so we can use it on our existing foo object
foo.getFooBar(); // "foobar" - concatenated the "bar" value with a custom suffix

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

Это становится еще более сложным, когда вы настраиваете наследование от одного класса к другому - в основном вы должны сделать дочерний объект-прототип наследуемым от родительского и применить родительский конструктор к дочерним экземплярам для создания «частных атрибутов». Посмотрите на Исправить javascript inheritance , Частные переменные в унаследованных прототипах , Определить членов частного поля и наследование в шаблоне модуля JAVASCRIPT и How реализовать наследование в JS. Выявление шаблона прототипа?

31
ответ дан Community 21 August 2018 в 00:47
поделиться
  • 1
    Это очень помогает в моем понимании того, что именно происходит здесь. Действительно, оригинальным мотиватором было то, что меня раздражало, что я должен поставить this перед всем, но на самом деле понимаю, почему я должен хорошо. – Chaosed0 16 November 2012 в 16:59
  • 2
    В ECMAScript нет «оператора-члена». Правильным термином является « свойство accessor ». – PointedEars 1 October 2013 в 14:58
  • 3
    @PointedEars: Конечно, это официальный термин. Но является «оператором-членом». (казалось бы, придумал MDN), действительно неправильный или не описательный? Оператор в математическом смысле, конечно, не в терминах двоичного оператора ES (§11.5-11.11) – Bergi 1 October 2013 в 15:06
  • 4
    Вероятно, неправильное определение происходит из «JavaScript: окончательного руководства» Дэвида Фланагана (который является чем-то , но «окончательным»), где он фактически перечисляет [ ... ] как «оператор массива». Да, что является неправильным. Рассмотрим возможные «операнды». И каково будет приоритет оператора, особенно для [ ... ]? Я только что отредактировал эту явно ошибочную статью MDN и предложил ее удалить из пространства имен «Операторы». Вы должны обновить свою ссылку и повторно проверить ее через некоторое время. – PointedEars 1 October 2013 в 16:08
  • 5

В javascript this всегда ссылается на объект владельца функции. Например, если вы определяете свою функцию foo() на странице, тогда владелец - это объект javascript windows; или если вы определяете foo() на элементе html <body>, то владелец является телом элемента html; а также если вы определяете функцию onclick элемента <a>, то владелец является якорем.

В вашем случае вы назначаете свойство bar объекту «владелец» в начале и пытаясь вернуть локальную переменную bar.

Поскольку вы никогда не определяли какой-либо локальный varialbe bar, он дает вам, поскольку bar не определен.

В идеале ваш код должен быть определен переменная как var bar;, если вы хотите вернуть нулевое значение.

2
ответ дан Abhishek V 21 August 2018 в 00:47
поделиться
function Foo() {
  this.bar = 0;
  this.getBar = function () { return this.bar };
}

Когда вы вызываете функцию выше с ключевым словом new - вот так ...

var foo = new Foo();

... - происходит несколько вещей:

1) создается объект. 2) функция выполняется с ключевым словом this, ссылающимся на этот объект. 3) этот объект возвращается.

foo, затем становится этим объектом:

{
    bar: 0,
    getBar: function () { return this.bar; }
};

Почему бы не тогда просто сделать это:

var foo = {
    bar: 0,
    getBar: function () { return this.bar; }
};

Вы бы, если это просто один простой объект.

Но создание объекта с конструктором (так оно называется) дает нам большое преимущество в создании нескольких «одинаковых» объектов.

См. в javascript все функции создаются с использованием свойства prototype [object], и все объекты, созданные с помощью этой функции (путем вызова его с новым ключевым словом), связаны с этим прототипом. Вот почему это так здорово - вы можете хранить все распространенные методы (и свойства, если хотите) в объекте прототипа, и сэкономить много памяти. Вот как это работает:

function Foo( bar, bob ) {
   this.bar = bar;
   this.bob = bob;
}

Foo.prototype.calculate = function () {
  // 'this' points not to the 'prototype' object 
  // as you could've expect, but to the objects
  // created by calling Foo with the new keyword.
  // This is what makes it work.
  return this.bar - this.bob;  
};

var foo1 = new Foo(9, 5);
var foo2 = new Foo(13, 3);
var result1 = foo1.calculate();
var result2 = foo2.calculate();

console.log(result1); //logs 4
console.log(result2); //logs 10

Вот и все!

3
ответ дан banzomaikaka 21 August 2018 в 00:47
поделиться

Чтобы приблизиться к ООП в JavaScript, вы можете взглянуть на шаблон проектирования модуля (например, здесь здесь ).

На основании эффекта закрытия , этот шаблон позволяет эмулировать частные свойства в ваших объектах.

С «частными» свойствами вы можете ссылаться на них напрямую по его идентификатору (т. е. ключевое слово this как в конструкторах).

Но в любом случае, замыкания и шаблоны проектирования в JS - продвинутая тема. Итак, ознакомьтесь с основами (также объясненными в упомянутой ранее книге).

2
ответ дан John Doe 21 August 2018 в 00:47
поделиться
  • 1
    Возвращаясь назад и просматривая эту статью (она, безусловно, имеет длину, чтобы быть книгой, но она, похоже, не публикуется) была очень и очень полезна. Спасибо, что принесли это под мой глаз. – Chaosed0 18 November 2012 в 05:23
  • 2
    @ Chaosed0 Всегда приветствую! Не то, чтобы многие книги / статьи о шаблонах проектирования в JS стоили читать, но это хорошо. – John Doe 19 November 2012 в 11:50

этот подобен модификатору объектов общего доступа (переменные или функции), а var является модификатором частного доступа

. Пример

]
var x = {}; 
x.hello = function(){
    var k = 'Hello World'; 
   this.m = 'Hello JavaScript'; 
}

var t = new x.hello(); 
console.log(t.k); //undefined
console.log(t.m); //Hello JavaScript
1
ответ дан Mina Gabriel 21 August 2018 в 00:47
поделиться

Явно говоря, this.foo означает (как вы поняли хорошо), что вас интересует свойство foo текущего объекта, на которое ссылается this. Поэтому, если вы используете: this.foo = 'bar';, вы собираетесь установить свойство foo текущего объекта, на которое ссылается this, равное bar.

Ключевое слово this в JavaScript не " t всегда означает то же самое, что и в C ++. Здесь я могу привести пример:

function Person(name) {
   this.name = name;
   console.log(this); //Developer {language: "js", name: "foo"} if called by Developer
}

function Developer(name, language) {
   this.language = language;
   Person.call(this, name);
}

var dev = new Developer('foo', 'js');

В приведенном выше примере мы вызываем функцию Person с контекстом функции Developer, поэтому this ссылается на объект, который будет создан Developer. Как вы можете видеть из результата console.log, результат this исходит из Developer. С первым аргументом метода call мы укажем контекст, с которым будет вызываться функция.

Если вы не используете this, просто созданное вами свойство будет локальной переменной , Поскольку вы, возможно, знаете, что JavaScript имеет функциональную область, поэтому переменная будет локальной, видимой только для функции, где она объявлена ​​(и, конечно же, все это дочерние функции, объявленные внутри родителя). Вот пример:

function foo() {
    var bar = 'foobar';
    this.getBar = function () {
        return bar;
    }
}

var f = new foo();
console.log(f.getBar());  //'foobar'

Это верно, если вы используете ключевое слово var. Это означает, что вы определяете bar как локальную переменную, если вы забудете var, к сожалению bar станет глобальным.

function foo() {
    bar = 'foobar';
    this.getBar = function () {
        return bar;
    }
}

var f = new foo();
console.log(window.bar);  //'foobar'

Именно локальная область может помочь вам добиться конфиденциальности и инкапсуляции, которая являются одним из самых больших преимуществ ООП.

Пример реального мира:

function ShoppingCart() {
    var items = [];

    this.getPrice = function () {
       var total = 0;
       for (var i = 0; i < items.length; i += 1) {
          total += items[i].price;
       }
       return total;
    }

    this.addItem = function (item) {
        items.push(item);
    }

    this.checkOut = function () {
        var serializedItems = JSON.strigify(items);
        //send request to the server...
    }
}

var cart = new ShoppingCart();
cart.addItem({ price: 10, type: 'T-shirt' });
cart.addItem({ price: 20, type: 'Pants' });
console.log(cart.getPrice()); //30

Еще один пример преимуществ области JavaScript - это шаблон модуля . В шаблоне модуля вы можете имитировать конфиденциальность, используя локальную функциональную область JavaScript. При таком подходе вы можете иметь как частные свойства, так и методы. Вот пример:

var module = (function {

    var privateProperty = 42;

    function privateMethod() {
        console.log('I\'m private');
    }
    return {

       publicMethod: function () {
           console.log('I\'m public!');
           console.log('I\'ll call a private method!');
           privateMethod();
       },

       publicProperty: 1.68,

       getPrivateProperty: function () {
           return privateProperty;
       },

       usePublicProperty: function () {
           console.log('I\'ll get a public property...' + this.publicProperty);
       }

    }
}());

module.privateMethod(); //TypeError
module.publicProperty(); //1.68
module.usePublicProperty(); //I'll get a public property...1.68
module.getPrivateProperty(); //42
module.publicMethod(); 
/*
 * I'm public!
 * I'll call a private method!
 * I'm private
 */

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


Надеюсь, что с информацией this :-) я помог вам понять несколько основных тем JavaScript.

6
ответ дан Minko Gechev 21 August 2018 в 00:47
поделиться
Другие вопросы по тегам:

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