透彻认识function的this在不同调用环境下的指向
- 事件调用环境
谁触发事件,函数里面的this指向的就是谁
例:.html
<div class="box"></div>
<script>
let box = document.querySelector('.box');
box.onclick = move;
function move(){
this.style.left = '100px';
}
console.log(this);
</script>
结果:window
新建this.js
console.log(this);
结果:node this.js
{}
全局修改this.js
修改this.js
console.log(this === module.exports);
结果:node this.js
true
- 函数内部
【this最终指向的是调用它的对象】普通函数直接调用与window调用
对象中的函数直接调用与window调用
例:.html
<div class="box"></div>
<script>
let box = document.querySelector('.box');
box.onclick = move;
function move(){
this.style.left = '100px';
}
move();//window 严格模式下 undefined 要使用winodw.move()
</script>
【函数被多层对象所包含,如果函数被最外层对象调用,this指向的也只是它上一级的对象】
<script>
var obj ={
a:10,
b:function(){
console.log(this);
}
}
obj.b();// {a:10,b:f}
window.obj.b();// {a:10,b:f}
</script>
<script>
var obj ={
a:10,
b:{
fn:function(){
console.log(this);//声明时,this 没有任何意义
}
}
}
window.obj.b.fn();// {fn:f}
</script>
多层对象中的函数的this指向
对象中的函数被赋值给另一个变量
<script>
var obj ={
a:10,
b:{
fn:function(){
console.log(this);
}
}
}
var abc = obj.b.fn();
abc(); //this 指向 window
</script>
【构造函数中的this指向的是实例对象】
构造函数中的this指向
new运算符的作用
<script>
function fn(){
this.num = 10;
//console.log(this.num);
}
fn.num = 20 ;
fn.prototype.num = 30;
fn.prototype.method = function(){
console.log(this.num)
}
var prototype = fn.prototype;
var method = prototype.method;
new fn().method();// 10
prototype.method();//30
// 等同于 var obj={} obj.x=10 obj.fn= function(){ console.log(this.x)}
// 等同于
var obj={
x:10,
fn: function(){
console.log(this.x)
}
}
method();// undfined
var obj = new fn();
console.log(obj.num) //10
/*
1、调用函数
2、自动创建一个对象(隐式调用) var obj = {}
3、把创建出来的对象和this进行绑定 var this = {}
4、构造函数没有返回值,隐式返回this对象
*/
</script>
【如果构造函数中有return 如果return的值是对象,this指向返回的对象 如果不是对象,则this指向保持原来的规则 return null(null是对象)比较特殊 返回的是this指向保持原来的规则】
<script>
function fn() {
this.num = 10;
return '';
}
var obj = new fn();
console.log(obj.num);//10
</script>
<script>
function fn() {
this.num = 10;
return 1;
}
var obj = new fn();
console.log(obj.num);//10
</script>
<script>
function fn() {
this.num = 10;
return {};
}
var obj = new fn();
console.log(obj.num);//undifined
</script>
<script>
function fn() {
this.num = 10;
return {
num:20
};
}
var obj = new fn();
console.log(obj.num);//20
</script>
<script>
function fn() {
this.num = 10;
return null;
}
var obj = new fn();
console.log(obj.num);//10
</script>
- 了解箭头函数中的this指向的特殊性
箭头函数本身是没有this和arguments的,在箭头函数中引用this实际上调用的是定义的是上一层作用域的this。
上一层作用域,因为对象不能形成对立的作用域的
var obj = {
fn:function(){ //普通函数
console.log(this);
}
}
obj.fn(); //this指向 obj {fn:f}
var obj = {
fn:()=>{
console.log(this);
}
}
obj.fn()//this指向 window
问题引出
例:.html
<div class="box"></div>
<script>
let box = document.querySelector('.box');
box.onclick = move;
function move(){
setTimeout(function(){
this.style.left = '100px';//this 指向window
},1000);
}
console.log(this);
</script>
解决:
<script>
let box = document.querySelector('.box');
box.onclick = move;
function move(){
setTimeout(() => {
this.style.left = '100px';
},1000);
}
console.log(this);
</script>
老的方法解决:
<script>
let box = document.querySelector('.box');
box.onclick = move;
function move(){
var _this = this;
setTimeout(function(){
_this.style.left = '100px';
},1000);
}
console.log(this);
</script>
- 掌握如何改变this指向
<div class="box"></div>
<script>
let box = document.querySelector('.box'),a,b,c;
var obj = {
fn:()=>{
console.log(this); //this 定义时就决定好了 指向 window
}
}
obj.fn.call(box); // call 无效
var obj = {
fn:function(){
console.log(this); //this 定义时就决定好了 指向 window
}
}
obj.fn.call(box,a,b,c); // <div class="box"></div>
obj.fn.apply(box,[a,b,c]);
obj.fn.bin(box);//只是绑定 要执行需要加括号 如:obj.fn.bin(box)()
// call bind 参数一样 apply 传数组
</script>
浙公网安备 33010602011771号