一、Class 原型链与严格模式

1、Class 中的方法存于原型链,属性存于实例

方法存于原型链,但是只能通过实例去调用

  • 错误写法 ```css class Person { constructor(name) {
    1. this.name = name;
    } show() {
      console.log(this);
    
    } }

Person.show(); // Person.show is not a function


- 正确写法
```css
class Person {
    constructor(name) {
        this.name = name;
    }
    show() {
        console.log(this);
    }
}

let p = new Person("张三");
p.show();

结合 this 是谁调用它,它就指向谁,因此其输出结果如下
截屏2022-02-16 下午10.17.38.png
其 name 属性是 p 自带的,但方法其实是存放在原型链上

2、严格模式

  • 严格模式:use strict,在该模式下,方法内的 this 不允许指向 window 对象(本来方法内的 this 都指向window)

    "use strict";
    (function() {
      console.log(this);        // undefined
    })();
    
  • 非严格模式

    (function() {
      console.log(this);    // Window
    })();
    

3、Class 中函数自带严格模式

class Person {
    constructor(name) {
        this.name = name;
    }
    show() {
        console.log(this);
    }
}


let p = new Person("张三");

let c = p.show;
c();

上述代码相当于以下的写法

"use strict";
let c = function() {
    console.log(this);    // undefined
}
c();

显然, 输出为 undefined


二、解决 Class 函数中 This 异常

1、以 bind() 的方式

class Person {
    constructor() {
        this.show = this.show.bind(this);
    }
    show() {
        console.log(this);
    }
}

let p = new Person("张三");
p.show();   // 正常输出

let c = p.show;
c();        // 正常输出
  • 输出结果如下

截屏2022-02-16 下午10.33.17.png

  • 此时二者调用的 show 方法不再是原型链上的方法,而是自身的方法,因此 c 中输出的也是张三
  • 加深理解,看以下代码 ```css class Person { constructor(name) {
      this.name = name;
      this.way = this.show.bind(this);
    
    } show() {
      console.log(this);
    
    } }

let p = new Person(“张三”);

let c = p.show; c(); // undefined

let d = p.way; d(); // 正常输出


<a name="xkN9g"></a>
#### 2、以箭头函数的方式解决

- 常量可直接定义在构造函数外
```css
class Person {
    constructor(name) {
        this.name = name;
        this.sex = "男";
    }
}

let p = new Person("张三");

console.log(p);
  • 上述代码可简写成如下 ```css class Person { sex = “男”; constructor(name) {
      this.name = name;
    
    } }

let p = new Person(“张三”);

console.log(p);


- 其输出结果相同

![截屏2022-02-17 上午5.40.35.png](https://cdn.nlark.com/yuque/0/2022/png/22695934/1645047639974-13e469ae-356c-4ade-a8ad-cd5e5546c3dc.png#clientId=u11bd7f90-4e42-4&crop=0&crop=0&crop=1&crop=1&from=drop&height=101&id=u4a561e17&margin=%5Bobject%20Object%5D&name=%E6%88%AA%E5%B1%8F2022-02-17%20%E4%B8%8A%E5%8D%885.40.35.png&originHeight=164&originWidth=566&originalType=binary&ratio=1&rotation=0&showTitle=false&size=57195&status=done&style=shadow&taskId=ua120963d-5396-424e-bee0-7dab401b95f&title=&width=349)

- 箭头函数: 自身无 this, 若内部调用 this, 则寻找外层的 this
```css
class Person {
    sex = "男"
    show = () => {
        console.log("show 方法执行, sex: " + this.sex);
    }
}


let p = new Person();
let s = p.show;
s();
  • 上述代码中, show() 不再存于原型链, 因为其采用的是 = 赋值的方式,凡事 = 赋值的都存于实例自身,打印实例p的结果如下

截屏2022-02-17 上午5.44.56.png

  • 若采用 function 的方式, 则仍会报错,因为 function 中包含 this,不会去寻找 p 指向的 this ```css class Person { sex = “男” show = function() {
      console.log("show 方法执行, sex: " + this.sex);
    
    } }

let p = new Person(); let s = p.show; s(); // this is undefined ```