Loading...

Конструктор, оператор "new"

Конструктор, оператор "new"

 

Кадимки синтаксис {...}бир гана объектти түзүүгө мүмкүндүк берет. Бирок көп учурда биз көптөгөн окшош, бирдей типтеги объекттерди түзүшүбүз керек, мисалы, колдонуучулар, меню пункттары жана башкалар.

Муну конструктор функциясын жана операторун колдонуу менен жасоого болот "new".

Конструктор функциясы

Конструктордук функциялар техникалык жактан регулярдуу функциялар. Бирок эки конвенция бар:

  1. Конструктор функциясынын аты баш тамга менен башталышы керек.
  2. Конструктор функциясы менен гана аткарылышы керек "new".

Мисалы:

@A@function User(name) {
  this.name = name;
  this.isAdmin = false;
}

let user = new User("Jack");

alert(user.name); // Jack
alert(user.isAdmin); // false@A@

Функция деп аталганда new User(...), төмөнкүдөй болот:

  1. Жаңы бош объект түзүлүп, ага дайындалат this.
  2. Функциянын денеси аткарылат. Ал, адатта this, жаңы касиеттерди кошуп, өзгөртөт.
  3. Мааниси кайтарылат this.

Башка сөз менен айтканда, new User(...)бир нерсе кылат:

@A@function User(name) {
  // this = {};  (неявно)

  // добавляет свойства к this
  this.name = name;
  this.isAdmin = false;

  // return this;  (неявно)
}

Ошентип, let user = new User("Jack")ал ошол эле натыйжаны кайтарат:

let user = {
  name: "Jack",
  isAdmin: false
};@A@

Эми, эгерде биз башка колдонуучуларды түзүш керек болсо, биз жөн гана чалсак болот new User("Ann")ж.б.у.с. new User("Alice")Бул курулуш объекттин сөзмө-сөз бир нече жолу түзүүгө караганда алда канча ыңгайлуу жана окууга ыңгайлуу.

Бул конструкторлордун негизги максаты болуп саналат - бир типтеги объекттерди бир нече түзүү үчүн кодду ишке ашыруу.

Дагы кайталайлы - техникалык жактан каалаган функцияны (жебе функцияларынан башкасы, анткени аларда жок this) конструктор катары колдонсо болот. Аны менен иштетсе болот newжана ал жогорудагы алгоритмди аткарат. Ушул сыяктуу функциялар баш тамга менен башталышы керек - бул функцияны "жаңы" менен чакыруу керек экенин ачык-айкын кылуу үчүн жалпы конвенция.

жаңы функция() {…}

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

@A@// создаём функцию и сразу же вызываем её с помощью new
let user = new function() {
  this.name = "John";
  this.isAdmin = false;

  // ...другой код для создания пользователя
  // возможна любая сложная логика и инструкции
  // локальные переменные и так далее
};@A@

Мындай конструкторду кайра чакырууга болбойт, анткени ал эч жерде сакталбайт, ал жөн гана түзүлүп, дароо чакырылат. Ошентип, бул трюк келечекте кайра колдонуу мүмкүнчүлүгү жок, өзүнчө объектти түзгөн кодду капсулдаштырууга багытталган.

Конструктор режиминде чалуу текшерилүүдө: new.target

өркүндөтүлгөн өзгөчөлүк

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

Функциянын ичиндеги атайын касиетти колдонуп new.target, функция оператор менен newже операторсуз чакырылганын текшере алабыз.

Кадимки функция чалуу болгон учурда, new.targetболот undefined. Эгер ал менен чакырылса newnew.targetал функциянын өзүнө барабар болот.

 
 
@A@function User() {
  alert(new.target);
}

// без "new":
User(); // undefined

// с "new":
new User(); // function User { ... }@A@

newБул функциянын ичинде "конструктор режиминде" же ансыз "кадимки режимде" деп аталганын билүү үчүн колдонулушу мүмкүн .

Биз ошондой эле чалууларды newжана ансыз да жасай алабыз:

@A@function User(name) {
  if (!new.target) { // в случае, если вы вызвали меня без оператора new
    return new User(name); // ...я добавлю new за вас
  }
  this.name = name;
}
let john = User("John"); // переадресовывает вызов на new User
alert(john.name); // John@A@

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

Бирок, бул трюкту бардык жерде колдонуу жакшы эмес, анткени анын жоктугу newиштеп чыгуучуну адаштырышы мүмкүн. Биз newжаңы объект түзүлүп жатканын так билебиз.

Конструктордон маанини кайтаруу, кайтаруу

Адатта, конструкторлордо return. Алардын милдети өзүнө керектүү нерселердин баарын жазуу thisжана бул автоматтык түрдө натыйжа болуп калат.

Бирок, returnбар болсо, анда жөнөкөй эреже колдонулат:

  • Объект менен чакырганда return, анын ордуна объект кайтарылат this.
  • Примитивдик маани менен чакырганда return, ага көңүл бурулбайт.

Башкача айтканда, returnобъект менен ошол объектти кайтарат, калган бардык учурларда кайтарат this.

Мисалы, бул жерде объектти кайтарып, returnалмаштырат :this

@A@function BigUser() {

  this.name = "John";

  return { name: "Godzilla" };  // <-- возвращает этот объект
}

alert( new BigUser().name );  // Godzilla, получили этот объект@A@

Жана бул жерде бош болгон мисал return(же биз примитивди return, кандай болсо да , кийин койсок болот):

 
 
@A@function SmallUser() {

  this.name = "John";

  return; // <-- возвращает this
}

alert( new SmallUser().name );  // John@A@

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

Кашаларды өткөрүп жиберүү

Айтмакчы, төмөнкү кашааларды калтырсак болот new:

@A@let user = new User; // <-- без скобок
// то же, что и
let user = new User();@A@

кашааларды калтыруу жаман практика болуп эсептелет, бирок сиз билесизби, бул синтаксиске спецификация уруксат берет.

Конструктордо методдорду түзүү

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

thisАлбетте, касиеттерге гана эмес, методдорго да кошо алабыз .

Мисалы, new User(name)төмөнкү берилген nameжана ыкмасы менен объект түзөт sayHi:

 
 
@A@function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "Меня зовут: " + this.name );
  };
}

let john = new User("John");

john.sayHi(); // Меня зовут: John

/*
john = {
   name: "John",
   sayHi: function() { ... }
}
*/@A@

Татаал объекттерди түзүү үчүн дагы өркүндөтүлгөн синтаксис бар - класстар , биз кийинчерээк карайбыз.

Бардыгы

  • Конструктордук функциялар же жөн эле конструкторлор кадимки функциялар, бирок аларды капиталдаштыруу үчүн жалпы конвенция бар.
  • Конструктор функциялары менен гана чакырылышы керек newthisМындай чалуу башында бошту жаратып , аягында толтурулган чакырууну кайтарат.

Биз көптөгөн окшош объекттерди түзүү үчүн конструкторлорду колдоно алабыз.

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

Биз объекттерге кайтып келебиз!

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

Аларды карап чыккандан кийин, биз Прототиптер, Мурас жана Класстар бөлүмдөрүндө кеңири изилдөө үчүн объекттерге кайтып келебиз .

Tasks

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

AФункцияларды түзүүгө жана Bжасоого болобу new A() == new B()?

@A@function A() { ... }
function B() { ... }

let a = new A();
let b = new B();

alert( a == b ); // true@A@

Ооба болсо, кодуңуздун мисалын бериңиз.

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

CalculatorҮч ыкма менен объекттерди түзгөн конструктор функциясын түзүңүз :

  • read()колдонуу менен эки маанини сурайт promptжана алардын маанисин объекттин касиеттеринде сактайт.
  • sum()бул касиеттердин суммасын кайтарат.
  • mul()бул касиеттердин продуктуну кайтарат.

Мисалы:

@A@let calculator = new Calculator();
calculator.read();

alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );@A@

Демо иштетүү

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

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

Конструктор функциясын түзүңүз Accumulator(startingValue).

Ал жараткан объект төмөнкүлөргө жөндөмдүү болушу керек:

  • "Учурдагы наркты" менчикте сактаңыз value. Баштапкы маани конструктор аргументинде орнотулган startingValue.
  • Метод жаңы санды окуу жана аны кошуу үчүн read()колдонулушу керек .promptvalue

Башка сөз менен айтканда, мулк valueбаштапкы маанини кошкондо, колдонуучу киргизген бардык баалуулуктардын суммасы болуп саналат startingValue.

Төмөндө сиз иштеп жаткан кодду көрө аласыз:

@A@let accumulator = new Accumulator(1); // начальное значение 1

accumulator.read(); // прибавляет введённое пользователем значение к текущему значению
accumulator.read(); // прибавляет введённое пользователем значение к текущему значению

alert(accumulator.value); // выведет сумму этих значений@A@