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仍指向自己
网友评论