JS中的this

2022-03-10  本文已影响0人  wyc0859
const age = 18;
function myFunction(a, b) {
  return a * b;
}
const res1 = myFunction(10, 2);
console.log("res1:", res1); // 20

以上函数不属于任何对象。但是在JS中,始终存在一种默认的全局对象。
在 HTML 中,默认全局对象是 HTML 页面本身,所有上面的函数 属于 HTML 页面。
在浏览器中,这个页面对象(window)就是浏览器窗口 ,上面的函数自动成为一个窗口函数

console.log("window:", window); 

注意上面这行代码:window等于浏览器窗口,所以在终端运行这里是会报错的

this的最终指向,是那个调用它的对象

函数(对象方法)中的this

function funa() {
  const funName = "函数A";
  //console.log("函数下window等于this吗?", window === this); //true
  console.log("函数下this:", this); //浏览器下是window对象,终端下是Object [global]
  console.log("this.funName:", this.funName, funName); //this.funName: undefined 函数A
//之所以是undfined ,是因为this的对象是全局对象window,
//而funName不是全局变量,因此window无法获取到funName
}
funa(); 

浏览器执行了funa()函数,this就是window
终端执行了funa()函数,this就是Object [global]

console.log("this:", this); //this: {}
console.log("this.age:", this.age); //this.age: undefined
//console.log("window等于this吗?", window === this); //false

直接console.log("this:", this); 会返回{}
如上面 执行了funa()函数,是浏览器执行的funa(),this就是window
但就这样放个this在外部,什么都没执行,this哪里来的调用它的对象,所以是{}


const obj = {
  name: "我是对象",
  say: function () {
    console.log("obj对象的say方法", this); // {say: ƒ say()} 
  },
};
obj.say();

上面代码,this的最终指向,是那个调用它的对象,很明显是obj


常见的情况

for循环时,常用 x = obj[key] x()操作。但此时的x()this是window需注意

var testobj = {
  age: 23,
  eat: function () {
    console.log("this:", this);
    console.log("年龄:", this.age);
  },
};
function prt(obj) {
  testobj.eat(); //this是testobj,有年龄
  obj["eat"](); //this是testobj,有年龄
  const x = obj["eat"];
  x(); //this是window,年龄是undefined
}
prt(testobj);
外部直接用也是一样
testobj.eat(); //this是testobj,有年龄
testobj["eat"](); //this是testobj,有年龄
const x = testobj["eat"];
const y = testobj.eat;
x(); //this是window,年龄是undefined
y(); //this是window,年龄是undefined

构造函数下的this

const objc = new func("参数");
func构造函数体内部的this是objc,不是func

function func(param) {
  funName = "变量"; //这个不是属性
  this.funName = "实例属性"; //这是构造函数属性

  console.log("func:", this, this.prototype); //明显this是objc
  //func  {funName: '实例属性'} undefined
  //this.prototype为undefined,证明不是构造函数,而是实例对象

  //这个不是方法,仅普通函数
  const c1 = function () {
    console.log("普通函数:", this);
  };
  //这个才是构造函数的方法
  this.c2 = function () {
    console.log("构造函数的方法:", this); //this是objc
  };
  this.c3 = () => {
    console.log("构造函数的方法-箭头函数:", this); //this是objc
  };
}

const objc = new func("参数"); 
//new一个对象,底层分3步,了解的话,就知道内部this一定是objc了
console.log("objc.funName:", objc.funName); //实例属性
console.log("func.funName:", func.funName); //undefined,这是调用静态

// objc.c1(); //会报错
objc.c2(); //func {funName: '实例属性', c2: ƒ c3: ƒ}
objc.c3(); //箭头函数:func {funName: '实例属性', c2: ƒ, c3: ƒ}

借用构造函数下的this

function Girl(height, bra) {
  this.height = height;
  this.bra = bra;
  console.log("Girl的this:", this); //young {height: 175, bra: 'C'}
  this.cry = function () {
    console.log(`${this.name}哭了`);
  };
}
Girl.prototype.smile = function () {
  console.log("她笑了");
};

function young(name, height, bra) {
//console.log("young:", young); //ƒ young(name, height, bra){} 函数体
//换成打印young(),会报错
  console.log("this:", this); //young {}
  Girl.apply(this, [height, bra]); // young借用Girl继承并调用了它
  this.name = name;
}

const xiaoB = new young("小b", 175, "C");
xiaoB.cry(); //小b哭了
console.log("xiaoB:", xiaoB);
//young {height: 175, bra: 'C', name: '小b', cry: ƒ}

//xiaoB.smile(); //报错
//注意:借用构造函数只是把参数传给了父类,但并不能访问父类的原型对象空间。
console.log("yong的原型对象空间:", young.prototype); 
//还是原有的 constructor仍指向自己
上一篇下一篇

猜你喜欢

热点阅读