Skip to content

this指向

不同的场景,this 指代的含义不同

  • 在全局代码中使用this,指代全局对象

    在真实的开发中,很少在全局代码使用this

  • 在函数中使用this,它的指向完全取决于函数是如何被调用的

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

    我们直接看代码示例

    js
    function Fn (name,age) {
        consoloe.log("this",this,this.name,this.age)
    }
    
    var obj = {
        test:function("张三",10)){
     		consoloe.log("this",this,this.name,this.age)
        }
    }
    
    var m = obj.test;
    
    
    Fn("张三",10));//this指向window,在全局调用。
    new Fn("张三",10));//this.指向一个新对象 相当于在函数第一行加一句 var this = {};
    obj.test("张三",10));//this指向obj
    m("张三",10));//this指向window,因为是在全局下调用的,开发者应自觉的遵循,避免出现这种骚操作
    
    Fn.call({},"张三",10);//call方法可以将this指向改变到{}中。
    
    var arr= [1,2]; 
    Fn.applay(arr,['张三',20]);//apply也是可以改变this指向,区别在于使用数组传递参数,这里的this就指向了arr
    • 补充知识
    js
    var obj = {};//相当于 new Object()来创建的对象。
    //所有对象的原型链的顶层都是Object
    
    "属性名" in 对象  //这是新语法,判断当前属性名是否在这个对象身上(包含原型)
    
    对象.hasOwnProperty();//判断某个属性是否在对象身上(不包含原型)

this练习

js
var person1 = {
  name: 'monica',
  age: 17,
  sayHi: function () {
    // 完成该方法,打印姓名和年龄
    console.log(this.name, this.age);
  },
};


person1.sayHi(); // monica 17

/* 扩展:如果不使用this,某天改变了person1的指向,那么代码就会异常 */
var person2 = person1;
person1 = "2";
person2.sayHi(); // monica 17
js
// 为所有对象添加方法print,打印对象的键值对

var obj = {
    name: "monica",
    age: 17,
}

var obj2 = {
    name: "lili",
    age: 18,
}


/* 
1. 为所有对象添加方法
2. 打印键值对
3. 不打印原型上的属性和方法
*/
Object.prototype.print = function () {
    for (let k in this) {
        // 使用对象的方法hasOwnProperty过滤原型上的属性和方法
        if (this.hasOwnProperty(k)) {
            console.log(k, this[k]);
        }
    }
}

obj.print();
obj2.print();
js
function User(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.fullName = firstName + lastName;
}

// 能否不使用new,通过User函数创建对象(不能更改User函数)
var u1 = {};
User.call(u1, "John", "Doe");
console.log(u1.fullName);

MIT License