做网站学生作业,本地的赣州网站建设,淘宝客的网站是如何建设的,wordpress建多个首页1、this 指向谁
多数情况下#xff0c;this 指向调用它所在方法的那个对象。即谁调的函数#xff0c;this 就归谁。
当调用方法没有明确对象时#xff0c;this 就指向全局对象。在浏览器中#xff0c;指向 window#xff1b;在 Node 中#xff0c;指向 Global。#x…1、this 指向谁
多数情况下this 指向调用它所在方法的那个对象。即谁调的函数this 就归谁。
当调用方法没有明确对象时this 就指向全局对象。在浏览器中指向 window在 Node 中指向 Global。严格模式下指向 undefined
this 的指向是在调用时决定的而不是在书写时决定的。这点和闭包恰恰相反。
2、区分 “声明位置” 与 “调用位置”
js 是词法作用域模型对象或方法其生命周期只和声明位置有关。
示例
// 声明位置
var me {name: xiaohong,hello: function() {console.log(${this.name})}
}
var you {name: xiaoming,hello: me.hello
}// 调用位置
me.hello() // xiaohong
you.hello() // xiaoming两次调用的 this 也就分别指向了 me 和 you。
// 声明位置
var me {name: xiaohong,hello: function() {console.log(${this.name})}
}
var name xiaoming
var hello me.hello
// 调用位置
me.hello() // xiaohong
hello() // xiaoming将 me.hello 赋值给变量 hello 时实际上是在创建一个新的函数引用这个引用指向 me 对象中的 hello 方法。但是这个新的引用即变量 hello并不保留与 me 对象的任何关联或绑定。
调用 hello() 时是在全局作用域中调用这个函数而不是作为 me 对象的方法调用。因此在这个调用中this 的值不会指向 me 对象。
// 声明位置
var me {name: xiaohong,hello: function() {console.log(${this.name})}
}
var you {name: xiaoming,hello: function() {var targetFunc me.hellotargetFunc()}
}
var name xiaosan
// 调用位置
you.hello() // xiaosan调用一个对象的方法时例如 me.hello()this 在该方法内部指向调用该方法的对象在这个例子中是 me。但是将一个方法赋值给一个变量例如 var targetFunc me.hello然后像普通函数那样调用这个变量例如 targetFunc()this 就不会再指向原来的对象了。相反在非严格模式下this 会默认指向全局对象在浏览器中是 window而在严格模式下this 会是 undefined。
3、普通函数的this指向总结
① 默认绑定 在全局中声明的变量和函数默认指向Window 函数独立调用时声明式函数、匿名函数 / 赋值式的方式、闭包都是指向Window 立即执行函数、 setTimeout、setInterval 指向 window
② 隐式绑定
对象调用也就是谁调用就是指向谁所以就是指向调用这个函数的对象
存在隐式丢失的问题函数赋值和参数赋值的情况
绑定的事件处理函数指向的是绑定事件处理函数的标签
③ 显式绑定
call / apply / bind 指向第一个参数
④ new绑定
构造函数中的this指向实例化出来的对象
4、箭头函数
箭头函数内部是没有this指向的箭头函数的this指向父级作用域的this如果没有则this指向的就是Window。
箭头函数注意事项 使用了箭头函数this就不是指向window而是父级指向是可变的 不能够使用arguments对象 不能用作构造函数这就是说不能够使用new命令否则会抛出一个错误 var Foo () {console.log(this);};var a new Foo(); // 报错Foo is not a constructor不可以使用 yield 命令因此箭头函数不能用作 Generator 函数
示例
function foo() {console.log(this) // obj对象// 情况一// function test() {// console.log(this) // Window// }// test()// 情况二// function test() {// console.log(this) // obj对象// }// test.call(this)// 情况三var test () {console.log(this) // obj对象}test()
}
var obj {a: 1,foo: foo
}
obj.foo()const obj {sayThis: () {console.log(this);}
};
// 因为JavaScript没有块作用域所以在定义sayThis的时候里面的this就绑到window上去了
obj.sayThis(); // window
const globalSay obj.sayThis;
globalSay(); // window 浏览器中的global对象const liEle document.querySelectorAll(li);
liEle.forEach((item, key) {// 箭头函数的this指向的是父级程序// forEach()的this指向windowconsole.log(打印1, this) // Windowitem.addEventListener(click, () {console.log(打印2, this) // Window})
})const button document.getElementById(btn);
button.addEventListener(click, () {console.log(this) // Window
})function Cat(title) {this.title title
}
Cat.prototype.sayName () {console.log(this) // Windowreturn this.title
}
const cat new Cat(我是标题啊);
console.log(cat.sayName()) // undefinedfunction foo() {console.log(this) // obj对象var test () {console.log(this) // obj对象}return test
}
var obj {a: 1,foo: foo
}
obj.foo()()function foo1() {console.log(this) // obj对象
}
var foo2 () {console.log(this) // Window
}
var obj {a: 1,foo1: foo1,foo2: foo2
}
obj.foo1()
obj.foo2()function foo1() {console.log(this) // obj2对象
}
var foo2 () {console.log(this) // Window
}
var obj {a: 1,foo1: foo1,foo2: foo2
}
var obj2 {a: 2
}
obj.foo1.call(obj2)
obj.foo2.call(obj2)function foo() {console.log(this) // Windowvar test () {console.log(this) // Window}return test
}
var obj {a: 1,foo: foo
}
var obj2 {a: 2,foo: foo
}
foo().call(obj)const obj {// 普通函数this指向调用它的对象fn1: function() {console.log(this) // {fn1: ƒ, fn2: ƒ, fn3: ƒ}},// 箭头函数this指向是父级程序的this指向// 父级程序是obj对象但只有函数有thisobj对象没有this// 父级程序没有this指向的是windowfn2: () {console.log(this) // Window对象}, // fn3是一个普通函数this指向的是obj对象fn3: function() {// fn4是一个箭头函数this指向的是父级程序的this指向// 父级程序是fn3fn3的this指向的是obj对象所以fn4箭头函数的this也是指向obj对象const fn4 () {console.log(this) // {fn1: ƒ, fn2: ƒ, fn3: ƒ}}fn4()}
}
obj.fn1()
obj.fn2()
obj.fn3()var x 11;
var obj {x: 22,y: this,say: () {console.log(this.x);}
}
obj.say(); // 11
console.log(obj.y); // window解析obj 对象中的 this 指向的就是 window也就是全局环境。所以obj.y打印的是window对象**因为箭头函数中的 this 指向父级程序的指向。**从以上例子可以看出来父级obj指向了window所以this.x打印的是11
var a 11;
function fn() {this.a 22;let b () {console.log(this.a)}b();
}
var x new fn(); // 22解析箭头函数中会往上寻找this直到找到所代表的this为止。例子中构造函数被实例化成为一个对象x那x中的this指代的就是对象x本身所以箭头函数this就代表x对象x对象内部的a值为22所以输出22。
var name window
var obj1 {name: 1,fn1: function(){ console.log(this.name) },fn2: () console.log(this.name),fn3: function (){return function(){console.log(this.name)}},fn4: function(){return () console.log(this.name)}
}
var obj2 {name: 2
};obj1.fn1(); // 1
obj1.fn1.call(obj2); // 2
obj1.fn2(); // window
obj1.fn2.call(obj2); // window
obj1.fn3(); // window
obj1.fn3().call(obj2); // 2
obj1.fn3.call(obj2)(); // window
obj1.fn4(); // 1
obj1.fn4().call(obj2); // 1
obj1.fn4.call(obj2)(); // 2function Foo() {getName function () {alert(1);};return this;
}
Foo.getName function () {alert(2);
};
Foo.prototype.getName function () {alert(3);
};
var getName function () {alert(4);
};
function getName() {alert(5);
}Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3解析
预编译中声明提升function getName{} 属于函数声明式提升到最前面。
所以全局的getName被替换成为function(){ alert(4) }
执行完Foo()后函数返回了thisthis指向window。所以Foo().getName(相当于window.getName()而函数中的getName是全局的执行函数的时候替换掉了之前的输出为4的getName当前就是输出1
9、资料 【前端面经】JS this 基本指向原则解析 普通函数和箭头函数this 指向的区别如何改变this指向