• this指向


    调用方式示例    函数中this的指向
    通过new调用new method()新对象
    直接调用method()全局对象
    通过对象调用obj.method()前面的对象
    call、apply、bindmethod.call(ctx)第一个参数

    我们说的this指向是一个函数里边的this指向,如果这个this不在函数里边,那this指向取决于环境,如果是浏览器环境,那指向window,如果是node环境,指向空对象。

    函数中的this指向谁,取决于如何去调用这个函数

    创建执行上下文的时候就确定了这一次函数调用的this指向谁,执行上下文什么时候创建的,是执行的时候创建的,执行就是调用,所以this的指向就是函数调用的时候确定的

    1. const shape = {
    2. radius: 10,
    3. diameter() {
    4. return this.radius * 2
    5. },
    6. perimeter: () => 2 * Math.PI * this.radius
    7. }
    8. shape.diameter()
    9. shape.perimeter()
    • A: 20 and 62.83185307179586
    • B: 20 and NaN
    • C: 20 and 63
    • D: NaN and 63
    答案: B

    注意 diameter 的值是一个常规函数,但是 perimeter 的值是一个箭头函数

    对于箭头函数,this 关键字指向的是它当前周围作用域(简单来说是包含箭头函数的常规函数,如果没有常规函数的话就是全局对象),这个行为和常规函数不同。这意味着当我们调用 perimeter 时,this 不是指向 shape 对象,而是它的周围作用域(在例子中是 window)。

    在 window 中没有 radius 这个属性,因此返回 undefined

    1. function Person(firstName, lastName) {
    2. this.firstName = firstName
    3. this.lastName = lastName
    4. }
    5. const lydia = new Person('Lydia', 'Hallie')
    6. const sarah = Person('Sarah', 'Smith')
    7. console.log(lydia)
    8. console.log(sarah)
    • A: Person {firstName: "Lydia", lastName: "Hallie"} and undefined
    • B: Person {firstName: "Lydia", lastName: "Hallie"} and Person {firstName: "Sarah", lastName: "Smith"}
    • C: Person {firstName: "Lydia", lastName: "Hallie"} and {}
    • D:Person {firstName: "Lydia", lastName: "Hallie"} and ReferenceError
    答案: A

    对于 sarah,我们没有使用 new 关键字。当使用 new 时,this 引用我们创建的空对象。当未使用 new 时,this 引用的是全局对象(global object)。

    我们说 this.firstName 等于 "Sarah",并且 this.lastName 等于 "Smith"。实际上我们做的是,定义了 global.firstName = 'Sarah' 和 global.lastName = 'Smith'。而 sarah 本身是 undefined

    1. const person = { name: 'Lydia' }
    2. function sayHi(age) {
    3. console.log(`${this.name} is ${age}`)
    4. }
    5. sayHi.call(person, 21)
    6. sayHi.bind(person, 21)
    • A: undefined is 21 Lydia is 21
    • B: function function
    • C: Lydia is 21 Lydia is 21
    • D: Lydia is 21 function
    答案: D

    使用这两种方法,我们都可以传递我们希望 this 关键字引用的对象。但是,.call 是立即执行的。

    .bind 返回函数的副本,但带有绑定上下文!它不是立即执行的。

    1. function Car() {
    2. this.make = "Lamborghini";
    3. return { make: "Maserati" };
    4. }
    5. const myCar = new Car();
    6. console.log(myCar.make);
    • A: "Lamborghini"
    • B: "Maserati"
    • C: ReferenceError
    • D: TypeError
    答案: B

    返回属性的时候,属性的值等于 返回的 值,而不是构造函数中设定的值。我们返回了字符串 "Maserati",所以 myCar.make等于"Maserati".

    1. class Dog {
    2. constructor(name) {
    3. this.name = name;
    4. }
    5. }
    6. Dog.prototype.bark = function() {
    7. console.log(`Woof I am ${this.name}`);
    8. };
    9. const pet = new Dog("Mara");
    10. pet.bark();
    11. delete Dog.prototype.bark;
    12. pet.bark();
    • A: "Woof I am Mara"TypeError
    • B: "Woof I am Mara","Woof I am Mara"
    • C: "Woof I am Mara"undefined
    • D: TypeErrorTypeError

    答案: A

    我们可以用delete关键字删除对象的属性,对原型也是适用的。删除了原型的属性后,该属性在原型链上就不可用了。在本例中,函数bark在执行了delete Dog.prototype.bark后不可用, 然而后面的代码还在调用它。

    当我们尝试调用一个不存在的函数时TypeError异常会被抛出。在本例中就是 TypeError: pet.bark is not a function,因为pet.barkundefined.

    1. var status = "😎"
    2. setTimeout(() => {
    3. const status = "😍"
    4. const data = {
    5. status: "🥑",
    6. getStatus() {
    7. return this.status
    8. }
    9. }
    10. console.log(data.getStatus())
    11. console.log(data.getStatus.call(this))
    12. }, 0)
    • A: "🥑" and "😍"
    • B: "🥑" and "😎"
    • C: "😍" and "😎"
    • D: "😎" and "😎"
    答案: B

    this关键字的指向取决于使用它的位置。 在函数中,比如getStatusthis指向的是调用它的对象,上述例子中data对象调用了getStatus,因此this指向的就是data对象。 当我们打印this.status时,data对象的status属性被打印,即"🥑"

    使用call方法,可以更改this指向的对象。data.getStatus.call(this)是将this的指向由data对象更改为全局对象。在全局对象上,有一个名为status的变量,其值为”😎“。 因此打印this.status时,会打印“😎”

    1. class Person {
    2. constructor() {
    3. this.name = "Lydia"
    4. }
    5. }
    6. Person = class AnotherPerson {
    7. constructor() {
    8. this.name = "Sarah"
    9. }
    10. }
    11. const member = new Person()
    12. console.log(member.name)
    • A: "Lydia"
    • B: "Sarah"
    • C: Error: cannot redeclare Person
    • D: SyntaxError
    答案: B

    我们可以将类设置为等于其他类/函数构造函数。 在这种情况下,我们将Person设置为AnotherPerson。 这个构造函数的名字是Sarah,所以新的Person实例member上的name属性是Sarah

    1. class Counter {
    2. constructor() {
    3. this.count = 0;
    4. }
    5. increment() {
    6. this.count++;
    7. }
    8. }
    9. const counterOne = new Counter();
    10. counterOne.increment();
    11. counterOne.increment();
    12. const counterTwo = counterOne;
    13. counterTwo.increment();
    14. console.log(counterOne.count);
    • A: 0
    • B: 1
    • C: 2
    • D: 3

    答案: D

    counterOne 是类 Counter 的一个实例。类 Counter 包含一个count 属性在它的构造函数里, 和一个 increment 方法。首先,我们通过 counterOne.increment() 调用方法 increment 两次。现在, counterOne.count 为 2.

    然后,我们创建一个新的变量 counterTwo 并将 counterOne 的引用地址赋值给它。因为对象受引用地址的影响,我们刚刚创建了一个新的对象,其引用地址和 counterOne 的等价。因此它们指向同一块内存地址,任何对其的副作用都会影响 counterTwo。现在 counterTwo.count 为 2

    我们调用 counterTwo.increment() 将 count 的值设为 3。然后,我们打印 counterOne 里的count,结果为 3

    1. const user = {
    2. email: "my@email.com",
    3. updateEmail: email => {
    4. this.email = email
    5. }
    6. }
    7. user.updateEmail("new@email.com")
    8. console.log(user.email)

     

    • A: my@email.com
    • B: new@email.com
    • C: undefined
    • D: ReferenceError
    答案: A

    updateEmail 函数是一个箭头函数,它没有和 user 对象绑定。这就意味着 this 关键字不会引用到 user 对象,但是会引用到全局对象。 user 对象内部的 email 的值不会更新。当打印 user.email 的时候, 原始值 my@email.com 被返回。

  • 相关阅读:
    查看symbol的位置
    three.js 字体精简处理
    windows11 生产力工具配置
    传智健康_第5章 预约管理-预约设置
    5G专网融合时间敏感网络架构技术
    openEuler 服务器安装 JumpServer (all-in-one 模式)
    复制或移动文件时,导入所有文件素材的几种方法
    正则表达式
    如何处理GPU训练显存不足[memory isn't enough][alloc failed][out of memory]
    卷积神经网络的训练算法,卷积神经网络算法实现
  • 原文地址:https://blog.csdn.net/qq_18422039/article/details/138108133