JS this指向问题
首先, 明确一点, 没有嵌套时, 函数中的this指向它的调用者.
嵌套函数, 内部的函数的this指向它的调用者=>window(不是外层函数)
var a = {
f: function (params) {
console.log(this);
function fn() {
console.log(this);
}
fn();
}
};
a.f();
{f: ƒ}
Window {window: Window, self: Window, document: document, name: '', location: Location, …}
其次, 函数既可以在当前运行环境中( this指向对象 ), 又可以在全局环境中( this指向window )
var obj = {
foo: function () { console.log(this.bar) },
bar: 1
};
var foo = obj.foo;
var bar = 2;
obj.foo() // 1
foo() // 2
或者
var foo = function () { console.log(this.bar) };
var bar = 2;
var obj = {
foo: function () { console.log(this.bar) },
bar: 1
};
obj.foo() // 1
foo() // 2
原因: JavaScript 语言之所以有this的设计,跟内存里面的数据结构有关系。
var obj = { foo: 5 };
JavaScript 引擎会先在内存里面,生成一个对象{ foo: 5 },然后把这个对象的内存地址赋值给变量obj。
也就是说,变量obj是一个地址(reference)。后面如果要读取obj.foo,引擎先从obj拿到内存地址,然后再从该地址读出原始的对象,返回它的foo属性。
原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象。举例来说,上面例子的foo属性,实际上是以下面的形式保存的。
{
foo: {
[[value]]: 5
[[writable]]: true
[[enumerable]]: true
[[configurable]]: true
}
}
当属性的值是一个函数。
var obj = { foo: function () {} };
这时,引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo属性的value属性。
{
foo: {
[[value]]: 函数的地址
...
}
}
由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。???
var f = function () {};
var obj = { f: f };
// 单独执行
f()
// obj 环境执行
obj.f()
1 函数形参及内部的this指向: 调用函数者
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
window.a();或a();//this指向window
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();//this指向o
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();////this指向b
2 箭头函数的this=定义时外层对象的this,因为它根本没有自己的this,导致内部的this就是外层代码块的this
var obj = {
foo() {
console.log(this);
},
bar: () => {
console.log(this);
}
}
obj.foo() // {foo: ƒ, bar: ƒ}
obj.bar() // window
注意: 因为是箭头函数,所以他的this是obj的this,即调用obj的=>window
3 构造函数this指向对象
function Fn(){
this.user = "追梦子";
}
var a = new Fn(); //this指向a
console.log(a.user); //追梦子
定时器中的this,指向的是window. =>嵌套函数
setTimeout(function() {
alert(this); // this -> window
},500)
元素绑定事件,执行函数中的this,指向的是当前元素
let $btn = document.getElementById('btn');
$btn.onclick = function(){
alert(this); // this -> $btn
}
对象(全局)中的this
var age=18
var obj={
age1:this.age
}
console.log(obj.age1) //17
只有函数才形成局部作用域,上面的obj的this实际上是全局作用域window