飞跃广告 發表於 2019-12-21 19:30:00

typescript

<p>一、介绍</p>
<p>1.typescript是由微软开发的一款开源的编程语言</p>
<p>2.ts是js的超级,拓展了js语法,更像java/c#这样面向对象语言,更适合开发大型项目。</p>
<p>3.谷歌也在大力支持ts,谷歌的angular2x+ 就是基于ts语法的。</p>
<p>4.最新的Vue ,React 也可以集成ts。</p>
<p>二、安装和编译</p>
<p>1.安装:npm install -g typescript</p>
<p>2.生成配置文件:tsc --init&nbsp; 创建tsconfig.json 文件(eg:可修改输出地址“outDir”:“./js”,等配置)</p>
<p>3.编译:tsc hello.ts&nbsp; (hello.ts 是自己建的ts名)</p>
<p>4.点击菜单栏 任务-运行任务&nbsp; 点击tsc 监视-tsconfig.json ,然后就可以自动生成代码了。</p>
<p>三、ts的数据类型</p>
<p>1.布尔类型(boolean)</p>
<p>2.数字类型(number)</p>
<p>3.字符串类型(string)</p>
<p>4.数组类型(array)</p>
<p>5.元祖类型(tuple)</p>
<p>6.枚举类型(enum)</p>
<p>7.任意类型(any)</p>
<p>8.null 和 undfined</p>
<p>9.void 类型</p>
<p>10.never类型</p>
<p>四、各类型的用法</p>
<p>1.布尔类型(boolean)</p>
<div>
<div class="cnblogs_code">
<pre>let flag:<span style="color: rgba(0, 0, 255, 1)">boolean</span> = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
flag </span>=<span style="color: rgba(0, 0, 255, 1)">false</span>;</pre>
</div>
<p>2.数字类型(number)</p>
</div>
<div class="cnblogs_code">
<div>
<div>let num:number;</div>
<div>num =3;</div>
</div>
</div>
<p>3.字符串类型(string)</p>
<div class="cnblogs_code">
<pre>let str:string = ''<span style="color: rgba(0, 0, 0, 1)">;
str </span>= 'I am string';</pre>
</div>
<p>4.数组类型(array)</p>
<div class="cnblogs_code">
<pre>let arr:string[]=<span style="color: rgba(0, 0, 0, 1)">[];
arr </span>= ['1','2','3','4'];<br>or<br>let arr:Array&lt;number&gt; =;</pre>
</div>
<p>5.元祖类型(tuple)</p>
<div class="cnblogs_code">
<pre>//已知数组元素的个数,并且知道每个元素的类型<br>let tupleArr : =['lalala',2];</pre>
</div>
<p>6.枚举类型(enum)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">enum Color{
    red </span>= 1<span style="color: rgba(0, 0, 0, 1)">,
    blue,
    orange </span>= 5<span style="color: rgba(0, 0, 0, 1)">,
    green </span>= 7<span style="color: rgba(0, 0, 0, 1)">
}
let redNum:Color </span>= Color.red   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">1</span>
let blueNum:Color = Color.blue    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">2</span>
let orangeNum:Color = Color.orange    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">5</span>
<span style="color: rgba(0, 0, 0, 1)">
let red:string </span>= Color   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">red</span>
let blue:string = Color    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">blue</span>
let orange:string = Color    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">orange</span></pre>
</div>
<p>7.任意类型(any)</p>
<div class="cnblogs_code">
<pre>let notSure:any = 4<span style="color: rgba(0, 0, 0, 1)">;
notSure </span>= 'maybe a string instead'<span style="color: rgba(0, 0, 0, 1)">;
notSure </span>= <span style="color: rgba(0, 0, 255, 1)">false</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">okay</span></pre>
</div>
<p>8.null 和 undfined</p>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">strictNullChecks标记的启用是在tsconfig.json文件里进行配置。</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> {</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   "compilerOptions": { //编译选项,可以被忽略,这时编译器会使用默认值</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">         "strictNullChecks": false, //在严格的null检查模式下,null和undefined值不包含在任何类型里,只允许赋值给void和本身对应的类型。</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">   }</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> }</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">"strictNullChecks": false,</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">默认情况下,null 和 undefined 是其它类型的子类型,可以赋值给其它类型,如number类型,此时,赋值后的类型会变成 null 或 undefined。</span>
<span style="color: rgba(0, 0, 0, 1)">let hh: number;
hh </span>= <span style="color: rgba(0, 0, 255, 1)">null</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ok的</span>
hh = undefined;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ok的</span>

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">"strictNullChecks": true,</span>
<span style="color: rgba(0, 0, 0, 1)">let ss: number;
ss </span>= <span style="color: rgba(0, 0, 255, 1)">null</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(255, 102, 0, 1)">提示不可以</span>
ss = undefined;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"><span style="color: rgba(255, 102, 0, 1)">提示不可以</span><br><br>//定义没有赋值就是undifined;<br>let aa :string | undifined;<br>console.log(aa)//undefined<br><br>//一个元素可能是number,null,undifined<br>let num: number | null | undefined<br>num=123;</span></pre>
</div>
<p>9.void 类型</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表示方法没有返回任何类型</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> run(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
    console.log(</span>111<span style="color: rgba(0, 0, 0, 1)">);

}
run()
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表示传参是number类型,函数返回值也是number类型</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sum(num:number): number {
    console.log(</span>111<span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> num + 123<span style="color: rgba(0, 0, 0, 1)">
}
sum(</span>12);</pre>
</div>
<p>10.never类型</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。<br>// 即使 any也不可以赋值给never。通常表现为抛出异常或无法执行到终止点(例如无线循环)。比如:</span>
<span style="color: rgba(0, 0, 0, 1)">let x: never;
let y: number;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 运行错误,数字类型不能转为 never 类型</span>
x = 123<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 运行正确,never 类型可以赋值给 never类型</span>
x = (() =&gt; { <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Error('exception'<span style="color: rgba(0, 0, 0, 1)">) })();

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 运行正确,never 类型可以赋值给 数字类型</span>
y = (() =&gt; { <span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Error('exception'<span style="color: rgba(0, 0, 0, 1)">) })();

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回值为 never 的函数可以是抛出异常的情况</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> error(message: string): never {
    </span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Error(message);
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回值为 never 的函数可以是无限循环这种无法被执行到的终止点的情况</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> loop(): never {
    </span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">) { }
}</span></pre>
</div>
<p>五、类</p>
<p>1.类的写法</p>
<p>2.类的继承</p>
<p>3.属性修饰符(public、protected、private)</p>
<p>4.必传参数和可选参数</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类里面的修饰符:ts里定义属性的时候提供了三种修饰符:</span><span style="color: rgba(0, 128, 0, 1)">
/*</span><span style="color: rgba(0, 128, 0, 1)">
public:共有   在类里面、子类、类外面都可以访问
protected:保护类型   在类里面,子类里面可以访问,在类外部没法访问
private:私有   在类里面可以访问 ,类外面和子类都不访问
属性如果不加修饰符,默认是public
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
class Person {
    name: string; </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">必传,属性修饰符这里没写就默认是public,同public name:string;</span>
<span style="color: rgba(0, 0, 0, 1)">    private sex: string;
    protected age</span>?: number; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">age:可有可没有</span>

    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">namepro:必传,agepro:可传可不传,<span style="color: rgba(255, 102, 0, 1)">可选参数必须配置到 参数的最后面</span> //‘lisi’是namepro的默认值</span>
    constructor(namepro: string = 'lisi', sexpro: string = '男', agepro?<span style="color: rgba(0, 0, 0, 1)">: number) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> namepro;
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.age =<span style="color: rgba(0, 0, 0, 1)"> agepro;
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.sex =<span style="color: rgba(0, 0, 0, 1)"> sexpro;
    }
    run(): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
      console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
    }
}
let zhangsan </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Person('zhangsan', '女'<span style="color: rgba(0, 0, 0, 1)">);
zhangsan.run();
zhangsan.age;</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(255, 102, 0, 1)">提示出错。age是保护类型</span>
<span style="color: rgba(0, 0, 0, 1)">
class Web extends Person {
    constructor(name: string) {
      super(name) //继承父级的参数需要同过super函数传值
    }
    work() {
      console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sex); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"><span style="color: rgba(255, 102, 0, 1)">sex是父类的私有属性,所以子类是访问不到的,这里会提示错误</span></span>
<span style="color: rgba(0, 0, 0, 1)">
    }
}</span></pre>
</div>
<p>5.参数中的三点运算符</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">三点运算符,接受新参传过来的值</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sumFn(...result: number[]): number {
    let sum: number </span>= 0<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (let i = 0; i &lt; result.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
      sum </span>+=<span style="color: rgba(0, 0, 0, 1)"> result;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sum;
}
sumFn(</span>1, 2, 3, 4<span style="color: rgba(0, 0, 0, 1)">);
sumFn(</span>1, 2, 3, 4, 5, 6<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">如果有默认的参数,那传参前面就是默认的参数,剩下的就在。。。的result中</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> sumFn(a:number,b:number,...result: number[]): number {
    let sum: number </span>= a+<span style="color: rgba(0, 0, 0, 1)">b;
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (let i = 0; i &lt; result.length; i++<span style="color: rgba(0, 0, 0, 1)">) {
      sum </span>+=<span style="color: rgba(0, 0, 0, 1)"> result;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sum;
}
sumFn(</span>1, 2, 3, 4<span style="color: rgba(0, 0, 0, 1)">);
sumFn(</span>1, 2, 3, 4, 5, 6)</pre>
</div>
<p>六、ts函数重载</p>
<p>1.ts中的重载:通过为同一个函数提供多个函数类型定义来试下多种功能的目的</p>
<div class="cnblogs_code">
<pre>function getInfo(name: <span style="color: rgba(0, 0, 255, 1)">string</span>): <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
function getInfo(age: number): </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
function getInfo(str: any): any {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> str === <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">string</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">我叫</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> str;
    } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">我的年龄</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> str;
    }
}
getInfo(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">张三</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我叫张三</span>
getInfo(<span style="color: rgba(128, 0, 128, 1)">20</span>)<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我的年龄20</span></pre>
</div>
<p>七、类的静态属性 静态方法</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">1.&nbsp;/*es5中的写法*/&nbsp;<br>function</span><span style="color: rgba(0, 0, 0, 1)"> Person () {
  </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> this.run = function () {} // 实例方法</span>
  <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> this.run = ()=&gt; {}</span>
<span style="color: rgba(0, 0, 0, 1)">}
Person.run </span>= <span style="color: rgba(0, 0, 255, 1)">function</span> () {} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 静态方法</span>
<br>2./*es6的写法*/<br><span style="color: rgba(0, 0, 0, 1)">
class Person1 {
  name:string;
  static sex </span>= 'man'; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 静态属性</span>
<span style="color: rgba(0, 0, 0, 1)">  constructor(name: string) {
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
  }  
  eat() {
    console.log(`${</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name}吃饭`)
  }
  static work() {
  console.log(`这是一个静态方法` </span>+<span style="color: rgba(0, 0, 0, 1)"> Person1.sex)
  </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(`${this.name}哈哈`) // 错误的写法,静态方法里面无法调用类的属性、方法。</span>
<span style="color: rgba(0, 0, 0, 1)">  }
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> p = <span style="color: rgba(0, 0, 255, 1)">new</span> Person1('aaa'<span style="color: rgba(0, 0, 0, 1)">);
p.eat(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 实例方法调用</span>
Person1.work(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 静态方法调用</span></pre>
</div>
<p>八、ts中的抽象类和抽象方法,多态</p>
<p>1.typescript中的抽象类是提供其它类的基类,不能直接被实例化;</p>
<p>2.用abstract关键字定义的抽象方法和抽象类,不包括具体实现必须在派生类实现。</p>
<p>3.&nbsp;抽象类: abstract 修饰, 里面可以没有抽象方法。但有抽象方法(abstract method)的类必须声明为抽象类(abstract class)</p>
<p>4.抽象类用于定义标准</p>
<p>5.&nbsp;多态:父类定义一个方法不去实现,让继承它的子类去实现&nbsp; 每一个子类有不同的表现</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">abstract class Animal {
    name: string;
    constructor(name: string) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
    }
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">抽象方法 ,不包含具体实现,要求子类中必须实现此方法</span>
<span style="color: rgba(0, 0, 0, 1)">    abstract eat(): any;
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">非抽象方法,无需要求子类实现、重写</span>
    run(): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
      console.log(</span>'非抽象方法,不一定要子类实现、重写'<span style="color: rgba(0, 0, 0, 1)">);
    }
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">子类中必须实现父类抽象方法,否则ts编译报错</span>
<span style="color: rgba(0, 0, 0, 1)">class Dog extends Animal {
    eat() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name + '吃鱼'<span style="color: rgba(0, 0, 0, 1)">
    }
}
class Cat extends Animal {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">子类中必须实现父类抽象方法,否则ts编译报错</span>
<span style="color: rgba(0, 0, 0, 1)">    eat() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span>.name + "吃鱼"<span style="color: rgba(0, 0, 0, 1)">;
    }
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dog = <span style="color: rgba(0, 0, 255, 1)">new</span> Dog("tom"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> cat = <span style="color: rgba(0, 0, 255, 1)">new</span> Cat("kitty"<span style="color: rgba(0, 0, 0, 1)">);
console.log(dog.eat());
console.log(cat.eat());

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">多态 ,一种事物的不同表现形态。如下面的代码中 先声明变量f是Animal类型,具体是Dog还是Cat,在new 对象时才知道</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">如果是Dog,则f.eat()调用的是Dog类中的eat方法;如果是Cat,则f.eat()调用的是Cat类中的eat方法,这就是多态!!!</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> f: Animal;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明变量为Animal类型</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">f=new Dog("sunny");</span>
f = <span style="color: rgba(0, 0, 255, 1)">new</span> Cat("sunny"<span style="color: rgba(0, 0, 0, 1)">);
console.log(f.eat());</span></pre>
</div>
<p>九、接口</p>
<p>1.接口:行为和动作的规范,对批量方法进行约束</p>
<p>2.接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面</p>
<p>3.分类:属性接口、函数类型接口、可索引接口、类类型接口</p>
<p>(1)属性接口:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">属性接口</span>
<span style="color: rgba(0, 0, 0, 1)">interface fullName{
    firstName:string;
    secondName:string;
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span> getName(name:fullName):<span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">{
    console.log(name.firstName </span>+<span style="color: rgba(0, 0, 0, 1)"> name.secondName);
}
getName({
    firstName:</span>'Li'<span style="color: rgba(0, 0, 0, 1)">,
    secondName:</span>'haha'<span style="color: rgba(0, 0, 0, 1)">
})</span></pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">interface Shape {
    head: string;
    arm: string;
}
interface Human {
    name: string;
    age: number;
    shape: Shape;
    say(word: string): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">;
}

let jack: Human </span>=<span style="color: rgba(0, 0, 0, 1)"> {
    name: </span>'Jack'<span style="color: rgba(0, 0, 0, 1)">,
    age: </span>18<span style="color: rgba(0, 0, 0, 1)">,
    shape: {
      head: </span>'head'<span style="color: rgba(0, 0, 0, 1)">,
      arm: </span>'arm'<span style="color: rgba(0, 0, 0, 1)">
    },
    say(word: string) {
      console.log(word)
    }
}
jack.say(</span>'hi')</pre>
</div>
<p>(2)函数类型接口:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">函数类型接口</span>
<span style="color: rgba(0, 0, 0, 1)">interface Fn{
    (key:string,val:string):string;
}
let add1:Fn </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(key:string,val:string):string{
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> key+<span style="color: rgba(0, 0, 0, 1)">val;
}
let add2:Fn </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(key:string,val:string){
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> `${key}------<span style="color: rgba(0, 0, 0, 1)">${val}`
}</span></pre>
</div>
<p>(3)可索引接口(数组对象的约束,不常用)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ts定义数组的方式</span>
let arr1: number[] = ;
let arr2: Array</span>&lt;string&gt; = ['11', '22'<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可索引接口的实现</span>
<span style="color: rgba(0, 0, 0, 1)">interface UserArr {
    : string
}
let arr3: UserArr </span>= ['aa', 'bb'] <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ok</span>
console.log(arr3);
let arr4:UserArr</span>=;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">报错</span>
<span style="color: rgba(0, 0, 0, 1)">
interface UserObj{
    :string
}
let arr5:UserObj </span>={name:'张三'} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">OK,但是这样实现已经不是数组,没有意义了,所以不常用</span></pre>
</div>
<p>(4)类类型接口(对类的约束,和抽象类有点像)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">interface Aniaml1 {
    name: string;
    eat(str: string): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">implements ,是对类Aniaml1的实现</span>
<span style="color: rgba(0, 0, 0, 1)">class Dog1 implements Aniaml1 {
    name: string;
    constructor(name: string) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
    }
    eat(str: string) {
      console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span>.name + '吃粮食' +<span style="color: rgba(0, 0, 0, 1)"> str);

    }
}
let d </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Dog1('小黑'<span style="color: rgba(0, 0, 0, 1)">);
d.eat(</span>'肉');</pre>
</div>
<p>4.接口的拓展:接口可以继承接口</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">interface Animal {
    eat(): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">;
}
interface Person extends Animal {
    work(): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">;
}
class Web implements Person {
    name: string;
    constructor(name: string) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.name =<span style="color: rgba(0, 0, 0, 1)"> name;
    }
    eat() {
      console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span>.name + '喜欢吃馒头'<span style="color: rgba(0, 0, 0, 1)">);
    }
    work() {
      console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span>.name + '写代码'<span style="color: rgba(0, 0, 0, 1)">);
    }
}
let zhangsan </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Web('zhangsan'<span style="color: rgba(0, 0, 0, 1)">);
zhangsan.work();</span></pre>
</div>
<p>十、泛型</p>
<p>1.泛型的定义:指在定义函数、接口或者类的时候, 不预先指定其类型,而是在使用时手动指定其类型的一种特性</p>
<p>2.泛型分类:泛型函数、泛型类、泛型接口</p>
<p>(1)泛型函数</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">使用泛型函数(T:类型变量)</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> myfn&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(args: T): T {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> args;
}
let output </span>= myfn&lt;string&gt;("Hello"); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">明确传入类型参数</span>
let output2 = myfn("Hello")<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不传入类型参数,TS根据上下文自动推断类型</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">使用泛型变量(这可以让我们把泛型变量T当做类型的一部分使用,而不是整个类型)</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> myfn1&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(args: T[]): T[] {
    console.log(args.length)
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> args;
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span> myfn2&lt;T&gt;(args: Array&lt;T&gt;): Array&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    console.log(args.length);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> args;
}</span></pre>
</div>
<p>(2)泛型类</p>
<div class="cnblogs_code">
<pre>class add&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">{
    value: T;
    add: (x: T, y: T) </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> T;
}
let myTest </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> add&lt;number&gt;<span style="color: rgba(0, 0, 0, 1)">();
myTest.value </span>= 0<span style="color: rgba(0, 0, 0, 1)">;
myTest.add </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (x, y) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> x +<span style="color: rgba(0, 0, 0, 1)"> y
}</span></pre>
</div>
<p>(3)泛型接口</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">第一种方法</span>
<span style="color: rgba(0, 0, 0, 1)">interface Test {
    </span>&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(args: T): T
}
let myTest: Test </span>= <span style="color: rgba(0, 0, 255, 1)">function</span> &lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(args: T): T {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> args;
}
myTest</span>&lt;string&gt;('20'<span style="color: rgba(0, 0, 0, 1)">);
myTest</span>&lt;string&gt;(20<span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">第二种方法</span>
interface Test1&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    (args: T): T
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span> myfn1&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(args: T): T {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> args;
}
let myTest1: Test1</span>&lt;string&gt; =<span style="color: rgba(0, 0, 0, 1)"> myfn1;
myTest1(</span>'20') <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ok</span>
myTest1(20)<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">报错</span></pre>
</div>
<p>&nbsp;</p>
<p>(4)<strong>泛型约束</strong>(类型变量继承接口)</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">例中,传入的参数必须具有length属性</span>
<span style="color: rgba(0, 0, 0, 1)">interface Test{
    length:number;
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span> myfn&lt;T extends Test&gt;<span style="color: rgba(0, 0, 0, 1)">(args:T):T{
    console.log(args.length)
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> args;
}
myfn(</span>3); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">error</span>
myfn("abc") <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">3</span></pre>
</div>
<p>十一:模块</p>
<p>1.模块的概念</p>
<p>2.模块导出的几种方式:export导出声明、export导出语句、export default、import 导入模块</p>
<p>3.模块封装(DB库)</p>
<p>4.命名空间</p>
<p>十二、装饰器</p>
<p>1.概念</p>
<p>2.分类:属性装饰器、方法装饰器、方法参数装饰器、类装饰器(装饰器的执行顺序也是这样)</p>
<p>3.装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参)</p>
<p>(1)普通装饰器</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类装饰器</span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> logClass(target: any) {
    console.log(target); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">httpClient类</span>
    params.prototype.apiUrl = '动态扩展的属性'<span style="color: rgba(0, 0, 0, 1)">;
    params.prototype.run </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
      console.log(</span>'动态拓展的方法'<span style="color: rgba(0, 0, 0, 1)">);
    }
}

@logClass
class httpClient {
    constructor() {

    }
    getData() {

    }
}
let http: any </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> httpClient();</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类装饰器重载构造函数和当前类的方法(普通装饰器)</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> logClass(target: any) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">target:httpClient 类</span>
    <span style="color: rgba(0, 0, 255, 1)">return</span> class extends target { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">装饰器重载构造函数</span>
      apiUrl: any = '我是修改后的数据'<span style="color: rgba(0, 0, 0, 1)">;
      getData() {
            </span><span style="color: rgba(0, 0, 255, 1)">this</span>.apiUrl + '----'<span style="color: rgba(0, 0, 0, 1)">;
            console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.apiUrl);
      }
    }

}

@logClass
class httpClient {
    public apiUrl: string </span>|<span style="color: rgba(0, 0, 0, 1)"> undefined;
    constructor() {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.apiUrl = '我是构造函数里面的apiUrl'<span style="color: rgba(0, 0, 0, 1)">;
    }
    getData() {
      console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.apiUrl);
    }
}
let http: any </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> httpClient();
console.log(http.apiUrl);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我是修改后的数据</span></pre>
</div>
<p>&nbsp;</p>
<p>(2)装饰器工厂(可传参)</p>
<p>&nbsp; &nbsp; &nbsp;2.1&nbsp; &nbsp;类装饰器</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">类装饰器(装饰器工厂的方式)</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> logClass(params: any) {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">params:传的参数</span>

    <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span> (target: any) {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">target:httpClient类</span>
      console.log(params);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">hello</span>
      console.log(target);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">httpClient类</span>
<span style="color: rgba(0, 0, 0, 1)">
      target.prototype.apiUrl </span>= params; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可以用上传的参数</span>
      target.prototype.run = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
            console.log(</span>'动态拓展的方法'<span style="color: rgba(0, 0, 0, 1)">);
      }
    }
}

@logClass(</span>'hello')   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可以传参</span>
<span style="color: rgba(0, 0, 0, 1)">class httpClient {
    constructor() {

    }
    getData() {

    }
}
let http: any </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> httpClient();
console.log(http.apiUrl);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">hello</span></pre>
</div>
<p>  2.2&nbsp; 属性装饰器</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">属性装饰器</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> logProperty(params: any) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">params:传的值:我是属性装饰器</span>
    <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span> (target: any, attr: any) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">target:httpClient 类,attr:apiUrl</span>
      target =<span style="color: rgba(0, 0, 0, 1)"> params;
    }
}
class httpClient {
    @logProperty(</span>'我是属性装饰器')    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注意后面是不能加分号的</span>
    public apiUrl: string |<span style="color: rgba(0, 0, 0, 1)"> undefined;
    constructor() {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.apiUrl = '我是构造函数里面的apiUrl'<span style="color: rgba(0, 0, 0, 1)">;
    }
    getData() {
      console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.apiUrl);
    }
}
let http: any </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> httpClient();
console.log(http.apiUrl);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我是属性装饰器</span></pre>
</div>
<p>2.3 方法装饰器<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">方法装饰器</span></p>
<div class="cnblogs_code">
<pre><em id="__mceDel"><span style="color: rgba(0, 0, 255, 1)">function</span> get(params: any) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">params:传的值:我是方法装饰器</span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">target:httpClient类,methodName:方法名getData, desc:方法的描述</span>
    <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (target: any, methodName: any, desc: any) {
      target.addPara </span>= '我是拓展的属性';<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">同类装饰器的方法</span>
      target.addFn = <span style="color: rgba(0, 0, 255, 1)">function</span> () {       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">同类装饰器的方法 </span>
            console.log('我是拓展的方法'<span style="color: rgba(0, 0, 0, 1)">);
      }
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改装饰器的方法,把装饰器里面传入的参数改为string类型 </span>
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取当前的方法 desc.value =getData() {console.log(this.apiUrl);}</span>
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">先保存当前的方法</span>
      let oldMethond =<span style="color: rgba(0, 0, 0, 1)"> desc.value;
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改当前的方法</span>
      desc.value = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (...args: any[]) {
            args </span>= args.map((val) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
                </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> String(val)
            })
            console.log(args);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">['123','xxx'] <br>       console.log(params); //我是方法装饰器 </span>
            <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将原来的方法继承到修改后的方法里面,这样既有修改的方法,又包含原有未修改的方法</span>
            oldMethond.apply(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">, args)
      }
    }
}
class httpClient {
    public apiUrl: string </span>|<span style="color: rgba(0, 0, 0, 1)"> undefined;
    constructor() {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.apiUrl = '我是构造函数里面的apiUrl'<span style="color: rgba(0, 0, 0, 1)">;
    }
    @get(</span>'我是方法装饰器'<span style="color: rgba(0, 0, 0, 1)">)
    getData(...args: any[]) {
      console.log(args); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">['123','xxx']</span>
      console.log(<span style="color: rgba(0, 0, 255, 1)">this</span>.apiUrl); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我是构造函数里面的apiUrl</span>
<span style="color: rgba(0, 0, 0, 1)">    }
}
let http: any </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> httpClient();
http.getData;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">['123','xxx']<br>//我是方法装饰器<br></span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">['123','xxx']</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)">我是构造函数里面的apiUrl</span></em></pre>
</div>
<p>2.4&nbsp;方法参数装饰器</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">方法参数装饰器:可以为类的原型增加一些元素数据(一般不用,类装饰器就可以做到这些)</span>
<span style="color: rgba(0, 0, 255, 1)">function</span> logParams(params: any) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">params:传的值:我是方法参数装饰器</span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">target:httpClient类,methodName:方法名getData, paramsIndex:函数参数的index索引</span>
    <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (target: any, methodName: any, paramsIndex: any) {
      target.addUrl </span>= 'params';<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可以为类的原型增加一些元素数据</span>
<span style="color: rgba(0, 0, 0, 1)">    }
}
class httpClient {
    public apiUrl: string </span>|<span style="color: rgba(0, 0, 0, 1)"> undefined;
    constructor() {
    }
   
    getData( @logParams(</span>'我是方法参数装饰器'<span style="color: rgba(0, 0, 0, 1)">) uuid:any) {
      console.log(uuid); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">haha</span>
<span style="color: rgba(0, 0, 0, 1)">    }
}
let http: any </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> httpClient();
http.getData(</span>'haha');</pre>
</div><br><br>
来源:https://www.cnblogs.com/zhengyulu/p/12077981.html
頁: [1]
查看完整版本: typescript