Loading...

Объект ыкмалары, "this"

Объект ыкмалары, "this"

 

Объекттер, адатта, чыныгы дүйнө объектилерин көрсөтүү үчүн түзүлөт, ал колдонуучулар, буйруктар жана башкалар:

@A@// Объект пользователя
let user = {
  name: "John",
  age: 30
};@A@

Чыныгы дүйнөдөгүдөй эле, колдонуучу иш-аракеттерди жасай алат : корзинага бир нерсени тандап, кирүү, чыгуу, төлөө ж.б.у.с.

JavaScript'те мындай аракеттер касиеттердеги функциялар менен көрсөтүлөт.

Метод мисалдары

Биринчиден, келгиле, колдонуучуга userсалам айтууну үйрөтөлү:

 
 
@A@let user = {
  name: "John",
  age: 30
};

user.sayHi = function() {
  alert("Привет!");
};

user.sayHi(); // Привет!@A@

user.sayHiБул жерде биз жөн гана саламдашуу функциясын түзүү үчүн Функция туюнтмасын колдондук жана аны объектибиздеги касиетке дайындадык .

Андан кийин биз аны окшош деп атасак болот user.sayHi(). Колдонуучу азыр сүйлөй алат!

Объекттин касиети болгон функция ошол объекттин ыкмасы деп аталат.

sayHiОшентип, биз объект ыкмасын алдык user.

Албетте, биз алдын ала жарыяланган функцияны төмөнкүдөй ыкма катары колдонсок болот:

 
 
@A@let user = {
  // ...
};
// сначала, объявляем
function sayHi() {
  alert("Привет!");
}
// затем добавляем в качестве метода
user.sayHi = sayHi;

user.sayHi(); // Привет!@A@
Объектке багытталган программалоо

Биз реалдуу дүйнөдө объекттерди көрсөтүү үчүн объекттерди колдонуп кодубузду жазганда, бул объектке багытталган программалоо же кыскача "OOP" деп аталат.

OOP бул чоң предметтик аймак жана өзүнчө кызыктуу илим. Туура объекттерди кантип тандоо керек? Алардын ортосундагы өз ара аракеттенүүнү кантип уюштуруу керек? Бул архитектуралык дизайн жана бул темада объектиге багытталган дизайн ыкмалары сыяктуу сонун китептер бар. Дизайн үлгүлөрү Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссайдс, же Объектке багытталган талдоо жана Gradi Booch үлгүсүндөгү тиркемелер менен дизайн жана башка көптөгөн китептер.

Методдун стенографиясы

Объекттин литералындагы методдор үчүн кыскараак синтаксис бар:

@A@// эти объекты делают одно и то же

user = {
  sayHi: function() {
    alert("Привет");
  }
};

// сокращённая запись выглядит лучше, не так ли?
user = {
  sayHi() { // то же самое, что и "sayHi: function(){...}"
    alert("Привет");
  }
};@A@

Көрсөтүлгөндөй, биз ачкыч сөздү өткөрүп жиберип "function", жөн гана жаза алабыз sayHi().

Бул эки белгилер толугу менен эквиваленттүү эмес экенин белгилей кетүү керек. Объекттик мураска байланыштуу тымызын айырмачылыктар бар (бул тууралуу кийинчерээк талкууланат), бирок изилдөөнүн бул этабында бул маанилүү эмес. Дээрлик бардык учурларда стенографиялык синтаксиске артыкчылык берилет.

методдордогу "бул" ачкыч сөз

Эреже катары, объект ыкмасы өз ишин аткаруу үчүн объектте сакталган маалыматка жетүү мүмкүнчүлүгүн талап кылат.

Мисалы, ичиндеги кодго user.sayHi()колдонуучунун аты керек болушу мүмкүн, ал user.

Объекттин ичиндеги маалыматка жетүү үчүн метод this.

Маани this- бул ыкманы чакыруу үчүн колдонулган чекитке чейинки объект.

Мисалы:

@A@let user = {
  name: "John",
  age: 30,
  sayHi() {
    // "this" - это "текущий объект".
    alert(this.name);
  }
};
user.sayHi(); // John@A@

Бул жерде, аткаруу убагында, user.sayHi()маани thisболот user(объектке шилтеме user).

Ошондой эле техникалык жактан ачкыч сөзү жок объектке тышкы өзгөрмө аркылуу жетүү мүмкүн this(бул объектке шилтеме бар):

@A@let user = {
  name: "John",
  age: 30,

  sayHi() {
    alert(user.name); // "user" вместо "this"
  }
};@A@

…Бирок мындай код ишенимсиз. Эгерде биз объекттин шилтемесин башка өзгөрмөгө көчүрүүнү чечсек user, мисалы admin = user, өзгөрмөнүн үстүнөн userбашка бир нерсе менен жазсак, анда ыкманы -дан чакырганда туура эмес объектке кирүүгө болот admin.

Бул төмөндө көрсөтүлгөн:

 
 
@A@let user = {
  name: "John",
  age: 30,
  sayHi() {
    alert( user.name ); // приведёт к ошибке
  }
};

let admin = user;
user = null; // перезапишем переменную для наглядности, теперь она не хранит ссылку на объект.

admin.sayHi(); // TypeError: Cannot read property 'name' of null@A@

this.nameАнын ордуна user.nameичинде колдонгон болсок alert, анда бул код иштемек.

"бул" такталган эмес

JavaScript'те "бул" ачкыч сөзү башка программалоо тилдерине караганда башкачараак иштейт. Ал объект ыкмасы болбосо да, каалаган функцияда колдонулушу мүмкүн.

Төмөнкү мисалда синтаксистик ката жок:

function sayHi() {
  alert( this.name );
}

Маани thisконтекстке жараша иштөө убагында эсептелет.

Мисалы, бул жерде бир эле функция эки башка объектке дайындалган жана чалууларда башка "бул" мааниге ээ:

 
 
@A@let user = { name: "John" };
let admin = { name: "Admin" };

function sayHi() {
  alert( this.name );
}

// используем одну и ту же функцию в двух объектах
user.f = sayHi;
admin.f = sayHi;

// эти вызовы имеют  разное значение this
// "this" внутри функции - это объект "перед точкой"
user.f(); // John  (this == user)
admin.f(); // Admin  (this == admin)@A@

admin['f'](); // Admin (нет разницы между использованием точки или квадратных скобок для доступа к объекту)

Эреже жөнөкөй: эгерде чакырылса , анда obj.f()чалуу учурунда fболот thisobjДемек, жогорудагы мисалда бул же user, же admin.

Объектсиз чалуу:this == undefined

Биз атүгүл объектисиз функцияны чакыра алабыз:

 
 
function sayHi() {
  alert(this);
}

sayHi(); // undefined

Мындай коддо катуу режимде ( "use strict") маани thisболот undefined. Эгер биз кирүүгө аракет кылсак this.name- бул ката кетирет.

Катуу эмес режимде маани глобалдык объектthis болот ( браузерде биз буга кийинчерээк Глобалдык объект бөлүмүндө кайрылабыз ). Бул тарыхый жүрүм-турум жана катуу режимди колдонуу менен оңдолот ( ).windowthis"use strict"

Адатта мындай чалуу программалоо катасы болуп саналат. Эгерде функциянын ичинде колдонулса this, анда ал кандайдыр бир объекттин контекстинде чакырылат деп күтөт.

Акысыздын кесепеттериthis

Эгерде сиз мурда башка программалоо тилдерин изилдеген болсоңуз, анда сиз "туруктуу" деген идеяга көнүп калгандырсыз this- бул жерде объектте аныкталган методдор ар дайым thisошол объектке тиешелүү болот.

JavaScript'те this"эркин", анын мааниси ыкма чакырылып жаткан учурда эсептелет жана ал методдун кайсы жерде жарыялангандыгынан көз каранды эмес, тескерисинче, кайсы объект методду чакырып жатканына жараша болот (кайсы объект "чекиттин алдында" келет).

thisИштөө убагында баалоо бул концепциянын артыкчылыктары да, кемчиликтери да бар. Бир жагынан, функция ар кандай объекттерде метод катары кайра колдонулушу мүмкүн (бул ийкемдүүлүктү жогорулатат). Башка жагынан алганда, көбүрөөк ийкемдүүлүк каталардын мүмкүнчүлүгүн жогорулатат.

Бул жерде биздин позиция тилдеги бул архитектуралык чечимдин жакшы же жаман экенине баа берүү эмес. Жакында биз муну менен кантип иштеш керек, кантип пайда алып, көйгөйлөрдөн качуу керектигин түшүнөбүз.

Жебе функцияларында "бул" жок

Жебе функциялары өзгөчө: алардын өздөрүнүн this. Эгерде мындай функциянын ичине кайрылсак this, анда ал сырткы «нормалдуу» функциядан алынат.

Мисалы, бул жерде тышкы ыкманын arrow()мааниси колдонулат :thisuser.sayHi()

 
 
@A@let user = {
  firstName: "Ilya",
  sayHi() {
    let arrow = () => alert(this.firstName);
    arrow();
  }
};

user.sayHi(); // Ilya@A@

Бул жебе функцияларынын өзгөчөлүгү. Бул биз чындап өзүнчө болгубуз келбей this, аны тышкы контексттен алгыбыз келгенде пайдалуу. Бул тема боюнча көбүрөөк мисалдарды кийинчерээк Кайталануучу жебе функциялары бөлүмүндө көрөбүз .

Бардыгы

  • Объекттин касиеттеринде жайгашкан функциялар "методдор" деп аталат.
  • Методдор объекттерге "аракет кылууга" мүмкүндүк берет: object.doSomething().
  • Методдор аркылуу объектке кайрыла алат this.

Мааниси thisиштөө учурунда аныкталат.

  • Андагы кандайдыр бир функцияны жарыялоодо, колдонсоңуз болот this, бирок бул thisфункция чакырылмайынча маанилүү эмес.
  • Функцияны объекттердин ортосунда (бир объекттен экинчисине) көчүрүүгө болот.
  • Функция "ыкма" синтаксиси менен чакырылганда - , чакыруу учурундагы object.method()маани .thisobject

Ошондой эле жебе функциялары өзгөчө экенин дагы бир жолу эске алыңыз - аларда жок this. Жебе функциясынын ичине киргенде this, анын мааниси сырттан алынат.

Tasks

маанилүүлүгү: 5

Бул жерде функция makeUserобъектти кайтарат.

Объекттин касиетине жетүүнүн натыйжасы кандай болот ref? Неге?

@A@function makeUser() {
  return {
    name: "John",
    ref: this
  };
}

let user = makeUser();

alert( user.ref.name ); // Каким будет результат?@A@
чечим
маанилүүлүгү: 5

Үч ыкма менен объектти calculator(калькулятор) түзүңүз:

  • read()(окуу) эки маанини сурайт жана аларды объекттин касиеттери катары сактайт.
  • sum()(сумма) сакталган маанилердин суммасын кайтарат.
  • mul()(көбөйтүү) сакталган маанилерди көбөйтөт жана натыйжаны берет.
let calculator = {
  // ... ваш код ...
};

calculator.read();
alert( calculator.sum() );
alert( calculator.mul() );

Демо иштетүү

Тапшырма үчүн тесттер менен кумкоргонду ачыңыз.

чечим
маанилүүлүгү: 2

ladderБизде өйдө-ылдый чыгууга мүмкүндүк берүүчү объект (тепкич) бар :

let ladder = {
  step: 0,
  up() {
    this.step++;
  },
  down() {
    this.step--;
  },
  showStep: function() { // показывает текущую ступеньку
    alert( this.step );
  }
};

Эми, эгер биз бир нече ирет чалууларды жасашыбыз керек болсо, биз муну төмөнкүдөй кылсак болот:

ladder.up();
ladder.up();
ladder.down();
ladder.showStep(); // 1
ladder.down();
ladder.showStep(); // 0

Методдордун кодун өзгөртүңүз upжана аларды чынжырда чакыра тургандай кылып өзгөртүңүз, мисалы down:showStep

ladder.up().up().down().showStep().down().showStep(); // показывает 1 затем 0

Бул ыкма JavaScript китепканаларында кеңири колдонулат.