13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ciinterface Author {
173af6ab5fSopenharmony_ci  firstName: string;
183af6ab5fSopenharmony_ci  lastName: string;
193af6ab5fSopenharmony_ci  anotherName: Function;
203af6ab5fSopenharmony_ci  asyncName: Function;
213af6ab5fSopenharmony_ci}
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_ciclass C {
243af6ab5fSopenharmony_ci  firstName: string;
253af6ab5fSopenharmony_ci  lastName: string;
263af6ab5fSopenharmony_ci  constructor(firstName: string, lastName: string) {
273af6ab5fSopenharmony_ci    this.firstName = firstName;
283af6ab5fSopenharmony_ci    this.lastName = lastName;
293af6ab5fSopenharmony_ci    this.fullName = this.fullName.bind(this);
303af6ab5fSopenharmony_ci    this.asyncFullName = this.asyncFullName.bind(this);
313af6ab5fSopenharmony_ci   }
323af6ab5fSopenharmony_ci
333af6ab5fSopenharmony_ci   author(): Author {
343af6ab5fSopenharmony_ci       let author: Author = {
353af6ab5fSopenharmony_ci         firstName: this.firstName,
363af6ab5fSopenharmony_ci         lastName: this.lastName,
373af6ab5fSopenharmony_ci         anotherName: this.fullName.bind(this),
383af6ab5fSopenharmony_ci         asyncName: this.asyncFullName.bind(this)
393af6ab5fSopenharmony_ci       }
403af6ab5fSopenharmony_ci       return author
413af6ab5fSopenharmony_ci   }
423af6ab5fSopenharmony_ci
433af6ab5fSopenharmony_ci  fullName(): string {
443af6ab5fSopenharmony_ci    return this.firstName + " " + this.lastName;
453af6ab5fSopenharmony_ci  }
463af6ab5fSopenharmony_ci
473af6ab5fSopenharmony_ci  async asyncFullName(): Promise<string> {
483af6ab5fSopenharmony_ci    return Promise<string>(fullName());
493af6ab5fSopenharmony_ci  }
503af6ab5fSopenharmony_ci
513af6ab5fSopenharmony_ci  sayHello(greet: string) {
523af6ab5fSopenharmony_ci    console.log(greet, this.fullName());
533af6ab5fSopenharmony_ci  }
543af6ab5fSopenharmony_ci
553af6ab5fSopenharmony_ci  async asyncSayHello(greet: string) {
563af6ab5fSopenharmony_ci    const afn = await this.asyncFullName();
573af6ab5fSopenharmony_ci    console.log(greet, afn);
583af6ab5fSopenharmony_ci  }
593af6ab5fSopenharmony_ci}
603af6ab5fSopenharmony_ci
613af6ab5fSopenharmony_ciasync function asyncFoo(): Promise<void> {
623af6ab5fSopenharmony_ci  const person1 = new C("Arthur", "Clarke");
633af6ab5fSopenharmony_ci  const person2 = new C("Ray", "Bradbury");
643af6ab5fSopenharmony_ci
653af6ab5fSopenharmony_ci  await person1.asyncFullName();
663af6ab5fSopenharmony_ci  const afn = await person1.asyncFullName();
673af6ab5fSopenharmony_ci
683af6ab5fSopenharmony_ci  const afn2 = await person1.asyncFullName.apply(person2);
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_ci  const f = person2.asyncFullName.bind(person1);
713af6ab5fSopenharmony_ci  await f();
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_ci  await asyncBar(person1);
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_ci  const ash1: Function = person1.asyncSayHello.bind(person1, "Hello");
763af6ab5fSopenharmony_ci  await ash1()
773af6ab5fSopenharmony_ci
783af6ab5fSopenharmony_ci  const ash2: Function = person1.asyncSayHello.bind(person1);
793af6ab5fSopenharmony_ci  await ash2("Hello")
803af6ab5fSopenharmony_ci
813af6ab5fSopenharmony_ci  await person1.asyncSayHello.apply(person2, "Hello");
823af6ab5fSopenharmony_ci  await person1.asyncSayHello.call(person2, "Hello")
833af6ab5fSopenharmony_ci}
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ciasync function asyncBar(c: C): Promise<string> {
863af6ab5fSopenharmony_ci  const person = new C("Stanislaw", "Lem");
873af6ab5fSopenharmony_ci  return await c.asyncFullName.call(person);
883af6ab5fSopenharmony_ci}
893af6ab5fSopenharmony_ci
903af6ab5fSopenharmony_cifunction foo(): void {
913af6ab5fSopenharmony_ci  const person1 = new C("Arthur", "Clarke");
923af6ab5fSopenharmony_ci  const person2 = new C("Ray", "Bradbury");
933af6ab5fSopenharmony_ci
943af6ab5fSopenharmony_ci  const fullName = person1.fullName.apply(person2);
953af6ab5fSopenharmony_ci
963af6ab5fSopenharmony_ci  const f = person2.fullName.bind(person1);
973af6ab5fSopenharmony_ci  f();
983af6ab5fSopenharmony_ci
993af6ab5fSopenharmony_ci  bar(person1);
1003af6ab5fSopenharmony_ci
1013af6ab5fSopenharmony_ci  const sh1: Function = person1.sayHello.bind(person1, "Hello");
1023af6ab5fSopenharmony_ci  sh1()
1033af6ab5fSopenharmony_ci
1043af6ab5fSopenharmony_ci  const sh2: Function = person1.sayHello.bind(person1);
1053af6ab5fSopenharmony_ci  sh2("Hello")
1063af6ab5fSopenharmony_ci
1073af6ab5fSopenharmony_ci  person1.sayHello.apply(person2, "Hello");
1083af6ab5fSopenharmony_ci  person1.sayHello.call(person2, "Hello")
1093af6ab5fSopenharmony_ci}
1103af6ab5fSopenharmony_ci
1113af6ab5fSopenharmony_cifunction bar(c: C): string {
1123af6ab5fSopenharmony_ci  const person = new C("Stanislaw", "Lem");
1133af6ab5fSopenharmony_ci  return c.fullName.call(person);
1143af6ab5fSopenharmony_ci}
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_ciconst person = {
1173af6ab5fSopenharmony_ci  fn: "Ben",
1183af6ab5fSopenharmony_ci  f1: function () {
1193af6ab5fSopenharmony_ci    return this.fn; // here `this` is the current obj
1203af6ab5fSopenharmony_ci  },
1213af6ab5fSopenharmony_ci  f2: function (): string {
1223af6ab5fSopenharmony_ci    return this.fn; // here `this` is the current obj
1233af6ab5fSopenharmony_ci  },
1243af6ab5fSopenharmony_ci  f3: () => {
1253af6ab5fSopenharmony_ci    return this.fo; // here `this` is `globalThis`
1263af6ab5fSopenharmony_ci  },
1273af6ab5fSopenharmony_ci  f4: (): string => {
1283af6ab5fSopenharmony_ci    return this.fo; // here `this` is `globalThis`
1293af6ab5fSopenharmony_ci  },
1303af6ab5fSopenharmony_ci};
1313af6ab5fSopenharmony_ci
1323af6ab5fSopenharmony_ciconst person1 = {
1333af6ab5fSopenharmony_ci  fn: "Mary",
1343af6ab5fSopenharmony_ci};
1353af6ab5fSopenharmony_ci
1363af6ab5fSopenharmony_ciconsole.log(person.f1.apply(person1));
1373af6ab5fSopenharmony_ciconsole.log(person.f2.apply(person1));
1383af6ab5fSopenharmony_ciconsole.log(person.f3.apply(person1));
1393af6ab5fSopenharmony_ciconsole.log(person.f4.apply(person1));
1403af6ab5fSopenharmony_ci
1413af6ab5fSopenharmony_cifoo.apply(undefined);
142