一、 解析器在调用函数时每次都会向函数内部传递一个参数,这个参数就是this,this指向的是一个对向,这个对象就是上下文对象,根据调用形式的不同,函数会指向不同的对象。
二、 如果要判断一个运行中函数的 this 绑定, 就需要找到这个函数的直接调用位置。 找到之后 就可以顺序应用下面这四条规则来判断 this 的绑定对象。
- new调用,绑定到新创建的对象,注意:显示return函数或对象,返回值不是新创建的对象,而是显式返回的函数或对象。
通过new操作符调用构造函数,会经历以下4个阶段。
创建一个新的对象; 将构造函数的this指向这个新对象; 指向构造函数的代码,为这个对象添加属性,方法等; 返回新对象。
含有return的情况
(1)//return{} 结果返回undefined
function fn(){
this.user='追梦子';
return {};
}
var a=new fn;
console.log(a.user);
(2)//return 1 该结果返回追梦子
function fn(){
this.user='追梦子';
return 1;
}
var a=new fn;
console.log(a.user);
(3)//return函数 ,this指向返回的函数,返回undefined
function fn(){
this.user='追梦子';
return function(){};
}
var a=new fn;
console.log(a.user);
2.call 或者 apply( 或者 bind) 调用:严格模式下,绑定到指定的第一个参数。非严格模式下,null和undefined,指向全局对象(浏览器中是window),其余值指向被new Object()包装的对象。
call与applay后面的参数,都是向将要执行的函数传递参数。其中call以一个一个的形式传递,apply以数组的形式传递。这是他们唯一的不同。
call一般用来继承,apply可以用来计算数组的最大值 Math.max.apply(null,[1,2,3,4,5]
3.对象上的函数调用:绑定到那个对象。
4.普通函数调用: 在严格模式下绑定到 undefined,否则绑定到全局对象。
// 非严格模式
var name = 'window';
var doSth = function(){
console.log(this.name);
}
doSth(); // 'window'
// 严格模式
'use strict'
var name = 'window';
var doSth = function(){
console.log(typeof this === 'undefined');
console.log(this.name);
}
doSth(); // true,// 报错,因为this是undefined
5.箭头函数调用模式
先看箭头函数和普通函数的重要区别:
1、没有自己的this、super、arguments和new.target绑定。
2、不能使用new来调用。 3、没有原型对象。 4、不可以改变this的绑定。 5、形参名称不能重复。
箭头函数中没有this绑定,必须通过查找作用域链来决定其值。 如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象。 比如:
var name = 'window';
var student = {
name: '若川',
doSth: function(){
// var self = this;
var arrowDoSth = () => {
// console.log(self.name);
console.log(this.name);
}
arrowDoSth();
},
arrowDoSth2: () => {
console.log(this.name);
}
}
student.doSth(); // '若川'
student.arrowDoSth2(); // 'window'