<script>
var a = 'window';
/************************************
01: 默认绑定 => 指向全局对象
strict mode 严格模式 undefined
***************************************/
function defaultFn() {
console.log(this.a);
};
defaultFn(); // 2
/************************************
02: 隐式绑定
***************************************/
function hideFoo() {
console.log(this.a);
}
var hideObj = {
a: 2,
say: hideFoo
};
hideObj.say(); // 2 => say函数的调用对象是obj
var obj1 = {
a: 100,
hideObj: hideObj,
hideFoo: hideFoo
};
obj1.hideObj.say(); // 2 => this是hideObj
obj1.hideFoo() // 100 => this是obj1
/************************************
03: 隐式绑定丢失
***************************************/
function hideLostFoo() {
console.log(this.a);
}
var hideLostObj = {
a: 2,
hideLostFoo: hideLostFoo
};
var bar = hideLostObj.hideLostFoo;
bar(); // this是window => 等价 hideLostFoo自调用
function foo1() {
console.log(this.a);
}
function doFoo(fn) {
fn();
}
var obj = {
a: 2,
foo: foo1
};
doFoo(obj.foo); // this是window => 等价 foo1自调用
/************************************
04: 显式绑定 call,bind,apply
***************************************/
function foo1(arg1, arg2) {
console.log(this, arg1, arg2);
console.log(this.a, arg1, arg2, '显式绑定');
}
var obj = {
a: 2
};
// foo1.call(obj,'参数1');
// foo1.apply(obj,['参数2']);
// foo1.bind(obj, ['参数2'])(100); // bind 返回的是一个函数
foo1.call('字符串'); // 简单类型 => 会被默认处理(装箱) new String(arg) new Number(arg)
/************************************
05: new绑定
I. 创建(或者说构造)一个全新的对象。
II. 这个新对象会被执行 [[ 原型 ]] 连接。
III. 这个新对象会绑定到函数调用的 this。
IV. 如果 [ 函数没有返回其他对象 ],那么 new 表达式中的函数调用会自动返回这个新对象
***************************************/
function fq(a) {
this.a = a;
};
fq.prototype.say = function () {
console.log(this.a);
}
var bar = new fq(2);
console.log(bar.a); // 2
// 模拟new 过程
function fq(a) {
const obj = {};
obj.a = a;
Object.setPrototypeOf(obj, fq.prototype)
return obj;
// 或者
// var obj = Object.create(fq.prototype);
// obj.a = a;
// return obj;
}
fq.prototype.say = function () {
console.log(this.a);
}
/************************************
06: 箭头函数绑定
箭头函数没有自己的this,
箭头函数的 this 始终会捕获和继承自其定义时【所处的外层作用域的 this 值】
***************************************/
const ms = {
a: 10,
say: () => {
console.log(this.a);
},
say1(){ // ★不是箭头函数(object.keys(ms).sya1) say1:function say1(){} => 可粗暴认为没有箭头表达式的都是普通函数
console.log(this.a);
},
say2: function () {
console.log(this.a);
},
say3: function () {
console.log(this);
return {
ha: () => {
console.log(this, '--------');
}
}
}
};
ms.say(); // this是window (所处的外层作用域的 this 值)
ms.say1(); // this是 ms
ms.say2();
ms.say3.call({ x: 100 }).ha();
// 构造函数
class Mans {
constructor() {
this.name = 'Mans'
}
printName() {
console.log(this.name);
}
printName1 = () => { // ★ 不在原型上
console.log(this.name);
}
}
const MansCase = new Mans();
MansCase.printName(); // Mans
MansCase.printName1(); // Mans
const otherObj = {
name: 'otherObj',
printName: MansCase.printName,
printName1: MansCase.printName1
}
otherObj.printName(); // otherObj this是otherObj
otherObj.printName1(); // Mans this是MansCase => 这个和上面的 obj1.hideObj.say() 调用者是hideObj
/**********************************************************************
特殊的setTimeout => 黑盒子,该API是浏览器内部提供,并非js部分中的
chromium => 谷歌浏览器开源出来的一个东西(setTimeout代码的执行实现)
fakeWin.setTimeout = function (fn, time) {
fakeWin.setTimeout.called = true;
fakeWin.setTimeout.that = this;
if (typeof fn === "string") {
eval(fn)
} else {
fn.apply(this, Array.prototype.slice.call(arguments, 2)) // this => window
}
};
**************************************************************************/
setTimeout(() => {
console.log(this); // window 不管是否严格模式
}, 100);
var sets = {
say: function () {
// 箭头函数
// setTimeout(() => {
// console.log(this); // sets对象
// }, 100);
setTimeout(function () {
console.log(this); // window
}, 100);
}
}
sets.say();
</script>
this指向
于 2023-09-02 11:59:11 首次发布
文章详细解析了JavaScript中this关键字在不同情况下的行为,包括默认绑定、隐式绑定的丢失、显式绑定(call/bind/apply)、new绑定以及箭头函数的this特性,还探讨了构造函数和setTimeout函数中的this指向。
1518

被折叠的 条评论
为什么被折叠?



