В чем разница между этими двумя способами создания конструкторских функций в Javascript? [Дубликат]

Итак, вы вызываете adapter.notifyDataSetChanged(), поэтому никакой другой метод notify___ не нужен (изменение набора данных в любом случае отключает анимацию.)

В этом случае самый простой (и наиболее эффективный) способ делать что-то будет, чтобы использовать RealmResults напрямую, а не извлекать каждый элемент в ArrayList, который затем используется точно таким же образом.

Итак, это должно быть как

public static RealmResults<City> getStoredCities(){
        RealmQuery<City> query = getRealmInstance().where(City.class);
        return realm.where(City.class)
                        .findAllSorted("timestamp", Sort.DESCENDING);
}

И

public static void removeCity(City city){
        final String cityName = city.getCityName();
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                RealmResults<City> result = realm.where(City.class).equalTo("cityName", cityName).findAll();
                result.deleteAllFromRealm();
            }
        });
}

И

builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
        RealmHelper.removeCity(getItem(position));
    }
});

И

// dependency: compile 'io.realm:android-adapters:1.3.0' // <-- for Realm 3.x+, use 2.0.0
public class CityListAdapter extends RealmRecyclerViewAdapter<City, CityListViewHolder> { 

    OnItemClickListener onItemClickListener;
    OnItemLongClickListener onItemLongClickListener;

    public CityListAdapter(@NonNull Context context, 
                           @Nullable OrderedRealmCollection<City> data, 
                           OnItemClickListener onItemClickListener, 
                           OnItemLongClickListener onItemLongClickListener) {
        super(context, data, true);
        this.onItemClickListener = onItemClickListener;
        this.onItemLongClickListener = onItemLongClickListener;
    }


    @Override
    public CityListViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.city_item_navigation_viewholder, parent, false);
        CityListViewholder cityListViewholder = new CityListViewholder(view, parent.getContext());
        return cityListViewholder;
    }

    @Override
    public void onBindViewHolder(CityListViewholder holder, int position) {
        holder.cityName.setText(getItem(position).getCityName());
        holder.bindClick(position, onItemClickListener);
        holder.bindLongClick(position, onItemLongClickListener);
    }

    public static class CityListViewholder extends RecyclerView.ViewHolder {
        TextView cityName;
        ImageView cityIcon;

        public CityListViewholder(View itemView, 
                                  Context context) {
            super(itemView);
            cityName = (TextView)itemView.findViewById(R.id.city_name);
            cityIcon = (ImageView)itemView.findViewById(R.id.city_icon);
        }

        public void bindClick(final int position, final OnItemClickListener onItemClickListener){
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onItemClickListener.onItemClick(position);
                }
            });
        }

        public void bindLongClick(final int position, final OnItemLongClickListener onItemLongClickListener) {
            itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    onItemLongClickListener.onItemLongClick(position);
                    return true;
                }
            });
        }
    }
}

Используя RealmRecyclerViewAdapter, вызывается notifyDataSetChanged() всякий раз, когда ваши результаты меняются.

9
задан Edward Anthony 19 March 2016 в 09:47
поделиться

2 ответа

Есть некоторые отличия между Class и Function - большинство людей начнут с того, что класс будет «просто синтаксическим сахаром», но этот сахар имеет значение совсем немного. Когда парсер JS обрабатывает код JavaScript, парсер будет сохранять их в разных узлах AST, как показано здесь, ClassDeclaration и ClassExpression - это разные типы узлов в полученном дереве AST:

https: // github.com/estree/estree/blob/master/es2015.md#classes

Вы можете видеть, что для этого анализатора новая спецификация классов ES6 вводит ряд новых элементов AST для синтаксис:

  • ClassBody
  • MethodDefinition
  • ClassDeclaration
  • ClassExpression
  • MetaProperty

Поскольку синтаксис AST не является стандартным, в зависимости от анализатора может быть больше или меньше типов, но важно заметить, что когда код вводит объявление класса или выражение класса, он будет интерпретироваться по-разному JavaScript.

Это означает, что объявления класса и функции не могут быть обменены. Вы можете увидеть это, если попытаетесь написать

class notWorking {
  return 1;  // <-- creates a parser error
};

. Это связано с тем, что когда парсер встречает ключевое слово класса, он начнет обрабатывать следующий код как ClassBody либо ClassDeclaration, либо ClassExpression, а затем он expexts find MethodDefinitions.

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

function myClass() {
    var privateVar;
}

Объявление класса не может иметь этого:

class myClass {
    var privateVar; // ERROR: should be a method
}

Это потому, что синтаксис класса допускает только методы для объявления внутри тела класса. По крайней мере, сейчас.

Однако существует предложение создать частные поля:

https://github.com/zenparsing/es-private-fields

Таким образом, в будущем вы могли бы сказать

class myClass {
   #privateVar; // maybe this works in the future?
}

Существует отдельный ответ, рассматривающий частные свойства в классах ES6, что предполагает некоторые обходные пути, например использование символов:

Частные свойства в JavaScript Классы ES6

var property = Symbol(); // private property workaround example
class Something {
    constructor(){
        this[property] = "test";
    }
}

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

Важное различие между объявлениями функций и объявлениями классов состоит в том, что объявляются объявления функций, а объявления классов - нет. Сначала вам нужно объявить свой класс, а затем получить доступ к нему

Объявления классов и объявления функций весьма схожи;

function foo1() {} // can be used before declaration
class  foo2{}      // new foo2(); works only after this declaration

Выражения класса работают аналогично функции например, они могут быть назначены переменной:

var myClass = class foobar {};

Больше различий 1

  1. Тело exression / декларации класса всегда выполняется в Строгий режим - не нужно указывать, что вручную
  2. У классов есть специальный конструктор ключевых слов - может быть только один из них, или возникает ошибка. Функции могут иметь несколько определений переменной функции с именем «конструктор»
  3. . Классы имеют специальное ключевое слово super, которое относится к конструктору родительских классов. Если вы находитесь внутри конструктора, вы можете вызвать super (x, y); для вызова конструктора родительского класса, но внутри метода вы можете вызвать super.foobar () для вызова вызова любой функции родительского класса.
  4. Внутри тела класса вы можете определить функцию со статическим ключевым словом, чтобы ее можно было вызывать, используя только ClassName.FunctionName () -syntax.
  5. В объявлениях классов и выражениях можно использовать ключевое слово extends, например class Dog extends Animal
  6. MethodDeclaration не нуждается в функции - префикс, таким образом, вы можете определить функцию «ok» внутри класса «m» следующим образом: class m {ok () {}}. На самом деле даже не разрешено определять функцию как class m {function ok () {}}

Однако после того, как парсер завершил работу, класс экземпляр, по сути, работает так же, как и любой другой объект.

Новый синтаксис ES6 Class является, по существу, более понятным способом выражения объектов традиционным способом ООП, и если вам это нравится, вы должны его использовать.

EDIT: также синтаксис класса ES6 имеет и другое ограничение: он не позволяет использовать функции-члены с помощью лексической привязки с использованием стрелки жира. Кажется, что ES7 имеет экспериментальную функцию . Это может быть полезно, например, когда методы привязки к обработчикам событий, связанный с этим вопрос здесь .

1 https: // developer. mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

16
ответ дан John Sampson 17 August 2018 в 18:12
поделиться
  • 1
    Спасибо за объяснения и ссылки, помогает много. – Edward Anthony 19 March 2016 в 16:35
  • 2
    Я также добавил уведомление о отсутствующем синтаксисе сильной стрелки для объявления класса ES6. – Tero Tolonen 19 March 2016 в 17:26
  • 3
    @TeroTolonen: Это вряд ли "особенность" что отличает классы от функций. Вы можете использовать функции стрелок в конструкторе, а не на прототипе. – Bergi 19 March 2016 в 17:34
  • 4
    @Bergi: Я имею в виду вот так: class a {n = (val) = & gt; {}} – Tero Tolonen 19 March 2016 в 17:38
  • 5
    @TeroTolonen: Что это должно быть? Очевидно, это синтаксическая ошибка, например function n = (val) => {}. Вы должны использовать class a { constructor() { this.n=val=>{…}; } } - то же, что и в конструкторе, созданном с использованием ключевого слова function. – Bergi 19 March 2016 в 17:40

class это не что иное, как синтаксический сахар над созданием логического класса javascript с использованием function. если вы используете function как class, вся функция действует как конструктор, если вы хотите поместить другие функции-члены, вам нужно сделать это в конструкторе, таком как this.something = ... или var something = ... в случае частных членов (если вы не вводите снаружи, предположите, что вы создаете объект с другими методами / свойствами), но в случае класса вся функция фактически не действует конструктором, вы можете явно ее разделить с другими функциями и данными члена.

0
ответ дан Koushik Chatterjee 17 August 2018 в 18:12
поделиться
Другие вопросы по тегам:

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