函数执行的主体(不是上下文):谁把函数执行的,执行主体就是谁
this的使用规律:
- 给元素的某个事件绑定方法,当事件触发方法执行的时候,方法中的this是当前操作的元素本身
function fn(n,m){
this.total=n+m;
}
let obj={name:'OBJ'};
fn(10,20); //=>this:window
//obj.fn(20,30); //=>报错:obj中没有fn属性
document.body.onclick=fn; //=>点击后FN中的this:BODY
document.body.onclick=function(){
//=>this:BODY
fn(30,40); //=>this:window
};
fn.call(); //=>this:window 不传或者传递null/undefined都是
fn.call(obj,10,20); //=>this:obj
fn.apply(obj,[10,20]);//=>this:obj APPLY要求传递的参数是数组
document.body.onclick=fn.bind(obj,10,20); //=>BIND是预处理THIS,此时的FN还没有执行,只是把THIS改成了OBJ,点击BODY的时候才执行的 =>“柯理化函数”(预处理机制)
- 当方法执行时,看方法前面是否有点,没有点的话,this是window或者undefined(严格模式);有点的话,点前面是谁this就是谁。
function Fn() {
// ...
}
Fn.prototype.xxx = function () {}
//=>批量给原型设置属性方法的时候:重构类的原型
Fn.prototype = {
constructor: Fn,
getA: function () {},
getB: function () {}
}; */
/* //=>批量给原型设置属性方法的时候:设置别名
let proto = Fn.prototype;
proto.getA = function () {}
proto.getB = function () {}
proto.getC = function () {}
proto.getD = function () {} */
//面向对象中有关私有/公有方法中的THIS问题
* 1.方法执行,看前面是否有点,点前面是谁THIS就是谁
* 2.把方法总的THIS进行替换
* 3.再基于原型链查找的方法确定结果即可
- 构造函数执行,方法体中的this是当前类的实例
function Fn() {
//=>this:f1这个实例
this.x = 100;
this.y = 200;
this.say = function () {
console.log(this.x);
}
}
Fn.prototype.say = function () {
console.log(this.y);
}
Fn.prototype.eat = function () {
console.log(this.x + this.y);
}
Fn.prototype.write = function () {
this.z = 1000;
}
let f1 = new Fn;
f1.say(); //=>this:f1 =>console.log(f1.x) =>100
f1.eat(); //=>this:f1 =>console.log(f1.x + f1.y) =>300
f1.__proto__.say(); //=>this:f1.__proto__ =>console.log(f1.__proto__.y) =>undefined
Fn.prototype.eat(); //=>this:Fn.prototype =>console.log(Fn.prototype.x + Fn.prototype.y) =>NaN
f1.write(); //=>this:f1 =>f1.z=1000 =>给f1设置一个私有的属性z=1000
Fn.prototype.write();//=>this:Fn.prototype =>Fn.prototype.z=1000 =>给原型上设置一个属性z=1000(属性是实例的公有属性)
- 全局下的this指向window
- 回调函数中的this指向window
- 自执行函数中的this是window|undefined
call,bind,apply改变函数中的this指向时,this为这三个的第一个参数
每一个函数(普通函数、构造函数、内置类)都是function这个内置类的实例,因此函数._proto_===Function.prototype,函数调取Function原型上的方法
```javascript //Function.prototype => function anonymous(){} /*- call / apply / bind
- 原型上提供的三个公有属性方法
- 每一个函数都可以调用这个方法执行
- 这些方法都是用来改变函数中的THIS指向的
*/ function fn(){} fn.call(); //=>fn函数基于原型链找到Function.prototype上的call方法,并且让其执行(执行的是call方法:方法中的this是fn) fn.call.call(); //=>fn.call就是Function.prototype上的call方法,也是一个函数,只要是函数就能用原型上的方法,所以可以继续调用call来执行
Function.prototype.call = function $1(){ //… } fn.call => $1 fn.call() => $1() this:fn fn.call.call() => $1.call() => 继续让call执行,this:$1
实例.方法():都是找到原型上的内置方法,让内置方法先执行(只不过执行的时候做了一些事情会对实例产生改变,而这也是这些内置方法的作用),内置方法中的THIS一般都是当前操作的实例
8. ES6箭头函数没有this,this继承上下文
```javascript
window.name='WINDOW';
let obj={
name:'OBJ',
fn:()=>{
console.log(this.name);
}
};
obj.fn();//=>this:window
obj.fn.call(obj);//=>this:window
//==================
document.body.onclick=function(){
//=>this:BODY
let _this=this;
_this.count=0;
/*setTimeout(function(){
//=>this:window
_this.count++;
},1000);*/
setTimeout(()=>{
//=>this:没有自己的THIS,继承下上文中的,也就是BODY
this.count++;
},1000);
}