1.基本阐述
- this就是执行时确定的
function func() {
/*
executionContext = {
this: {} // context执行上下文中,指定this,指向函数当前的上下文
}
*/
console.log('this::', this)
}
//全局(global 或者 Window)或 者undefined(严格模式)
func();
2. 五种场景
2.1 函数直接调用时(自然执行就是全局)
function func() {
console.log('this::', this)
}
function outer() {
func();
}
outer();
// 自然执行时,就是全局或undefined(严格模式)
// outer自然执行(不被访问操作符访问,不被点出来(a.outer())),不会向外找
// 不在对象上
2.2 函数被对象调用(执行时谁点出来的就是谁)
- 简单调用
var teacher = {
buybuybuy: function () {
console.log('this::', this)
}
};
teacher.buybuybuy();
// this:: { buybuybuy: [Function: buybuybuy] }
// this就是调用该函数的对象
- 复杂调用
var teacher = {
name: 'teacher',
hand: {
name: 'hand',
buybuybuy: function () {
console.log('this::', this.name)
}
}
};
// this:: hand,只看buybuybuy最后是被谁调用的
teacher.hand.buybuybuy();
var teacher = {
name: 'teacher',
buybuybuy: function () {
console.log('this::', this.name)
}
};
var wife = {
name: 'wife',
};
//--------------------------------------------------
wife.buybuybuy = teacher.buybuybuy;
wife.buybuybuy(); // 这个this是wife
//--------------------------------------------------
var buybuybuy = wife.buybuybuy; //此处点出来没执行,只是点出来一个function
buybuybuy(); // 此时是自然执行,非严格模式,是全局
//--------------------------------------------------
window.addEventListener('scroll', wife.buybuybuy) // 全局
function addEventListener (name, func) {
func(); // 执行时是全局
}
//--------------------------------------------------
var a = (1, 2); // 逗号,返回第二个值
var buybuybuy = (1, teacher.buybuybuy);
buybuybuy(); // this是全局
(1, teacher.buybuybuy)(); // ()执行,this是全局
2.3 new一个实例时(this是new执行时new出来的对象)
JS中模拟类用的是function,new一个类的构造函数
function Person() {
console.log('this::', this)
}
var teacher = new Person();
// this就是teacher(new出来的对象)
// console出来的是teacher的构造函数 Person {}
function Person() {
this.buybugbuy = function () { // 隐式绑定
console.log('this::', this);
}
}
var teacher = new Person();
wife.buybugbuy = teacher.buybugbuy;
wife.buybugbuy(); // this是wife wife调用的
2.4 call / apply / bind 强行改变this
- call / apply / bind对比
function buybuybuy(first, second) {
console.log('this::', this, first, second);
}
var wife = {
name: 'wife',
}
buybuybuy(); // 全局 undefined undefined
buybuybuy.call(wife, 1, 2); // this:: { name: 'wife' } 1 2
buybuybuy.apply(wife, [3, 4]); // this:: { name: 'wife' } 3 4
// call apply都是立刻执行, bind并非立即执行
// bind返回了一个新函数,是绑定过对象的函数,不改原函数
var wifeBuybuybuy = buybuybuy.bind(wife);
buybuybuy(); // 全局
wifeBuybuybuy(); // { name: 'wife' } undefined undefined
teacher.wifeBuybuybuy(); // wifeBuybuybuy已经被bind绑定过了,不执行teacher规则
- 手写一个bind
var newBind = function (context) {
const func = this; // 调用newBind的函数是this func
return function () {
func.apply(context, arguments);
}
}
Function.prototype.newBind = newBind;
- React中应用bind实例,为什么需要bind
class SubApp extends React.Component {
render() {
var del = this.props.delete; // 拿到父组件传来的delete
del(); // 不是被点出来,执行那刻,未被绑定过传递,不知道this是谁
return <div onClick={del}></div>
}
}
class App extends React.Component {
delete() {
console.log(this) // this是app的实例
this.xxx
}
render() {
// 父组件传递时候绑定过this,子组件接收后不会丢失this
// .bind(this) App实例 给子组件传递绑定的函数 有性能问题
return <SubApp onClick = {this.delete.bind(this)} />
}
}
2.5 箭头函数
- 箭头函数this指向箭头函数
定义时, 离箭头函数最近的非箭头函数执行上下文的this - 例1
const outer = () => {
console.log('this::', this)
}
var wife = {
name: 'wife',
}
wife.outer = outer;
wife.outer(); // this并不是wife,而是全局
- 例2
function buybuybuyOuter() {
console.log('this-outer::', this);
// 定义时
// this就是离我最近的非箭头函数的上下文的this
const buybuybuy = () => {
console.log('this::', this);
}
buybuybuy(); // { name: 'wife', buybuybuyOuter: [Function: buybuybuyOuter] }
}
var wife = {
name: 'wife'
}
wife.buybuybuyOuter = buybuybuyOuter;
wife.buybuybuyOuter(); // { name: 'wife', buybuybuyOuter: [Function: buybuybuyOuter] }
- 例3
function buybuybuyOuter() {
console.log('this-outer::', this); // wife
const buybuybuy = () => {
console.log('this::', this); //wife
}
function innerCall(){
console.log('innerCall::', this);
buybuybuy();
}
innerCall(); // 全局
}
var wife = {
name: 'wife'
}
wife.buybuybuyOuter = buybuybuyOuter;
wife.buybuybuyOuter(); // 顺序 this-outer::wife innerCall::winows this::wife
this 不听 all bind apply 不听 三板斧