Javascript初学者关于This指向的学习笔记

//     <button onclick="test()">点击</button>
//     <button onclick="test1(this)">点击1</button>
//     <button id="btn2">点击2</button>
//     <button id="btn3">点击3</button>
//     <button id="btn4">点击4</button>
//     <button id="btn5">点击5</button>

在绑定中的this指向

//传统绑定
//传统一:
// (一)
function test() {
    console.log(this)  //--->指向window
}

//(二)
function test1(obj) {
    console.log(obj)  //--->指向btn--->注意这里打印的是obj,并且在button标签的onclick里面传了this
}

//传统二:
let btn2 = document.getElementById('btn2');
btn2.onclick = function () {
    console.log(this)//--->指向btn
};

//传统三:
function test3() {
    console.log(this)
}

let btn3 = document.getElementById('btn3');
btn3.onclick = test3; //--->指向btn
//现代绑定
//(一)
function test4() {
    console.log(this)
}

let btn4 = document.getElementById('btn4');
btn4.addEventListener('click', test4);//--->指向btn
//(二)
let btn5 = document.getElementById('btn5');
btn5.addEventListener('click', function f() {
    console.log(this)//--->指向btn
});
//总结:1.通过标签绑定的(点击,点击1),如果没传参数如:点击----->指向windwo,传了参数如:点击1------>指向节点
//2.通过节点绑定的(点击2-点击5)------>指向节点

在面向对象里面(构造函数里面的函数)的this指向

//this单一的指向实例化对象
//但是可以通过call,apply,bind改变this的指向
//例子:一
function Person() {
    this.name = '张三';
    this.type = '阳光型';
    this.move = function () {
        console.log(this)//--------->指向p(指向实例化对象)
    }
}

let p = new Person();
p.move();

//例子:二
function Person2() {
    console.log(this)//------->指向window
}

function Person1() {
    this.name = '张三';
    this.type = '阳光型';
    this.move = function () {
        console.log(this);//--------->指向p1(指向实例化对象)
        Person2()
    }
}

let p1 = new Person1();
p1.move();

//例子:三
function Person4() {
    console.log(this)//------->指向window
}

function Person3() {
    this.name = '张三';
    this.type = '阳光型';
    this.move = function () {
        Person4();
        this.eat = function () {
            console.log('怎么样调用eat方法')
            console.log(this)
        }
        //return this
    }
}

let p3 = new Person3();
//怎么样才能调用到eat的方法呢?
p3.move();
p3.eat();
//---->这样写才能调用到,为什么呢:因为96行的this依旧是指向实例化对象p3,this.eat=function{}相当于是给p3添加了这个eat属性。因此必须要先调用了move方法。才能调用eat方法。
//如果在eat方法后面返回一个this:return this,就可以直接 p3.move().eat();
//例子:四
function Person5() {
    console.log(this)
}

function Person6() {
    this.name = '张三';
    this.type = '阳光型';
    this.move = function () {
        Person5()

    }
}

let p6 = new Person6();
p6.move();
// Person5()里面的this------->指向window,现在让他指向实例化对象p6,那么就是应该这样:
//方法一:115行,Person5().call(this)//通过call方法来改变this的指向
//方法二:这是常规的用法,但是没有方法一简洁。所以建议用方法一
// function Person5(obj){ //-------->通过传参数obj的方法。
//     console.log(obj)     //这个obj就是指向实例化对象p6
// }
// function Person6() {
//     this.name = '张三';
//     this.type = '阳光型';
//     this.move = function () {
//         let _this=this ;   //-------->通过传参数的方法。
//          Person5(_this)
//     }
// }
// let p6 = new Person6();
// p6.move()

在闭包中的this指向

//闭包:将方法和变量私有化,并公开接口(这个接口即是返回的函数)
function closure() {
    let abc = 10;

    function mytest1() {
        console.log('我是mytest1函数');
        console.log(this);//-------------------->指向window
    }

    function mytest2() {
        console.log('我是mytest2函数')
    }

    return mytest1
}

let mytest3 = closure();//--------->closure()();是 let mytest3=closure();mytest3();的简写
mytest3();

//===========如果想同时返回mytest1和mytest2,那么就返回一个对象,里面装mytest1和mytest2
function closure1() {
    let abc = 10;

    function mytest3() {
        console.log('我是mytest1函数');
        console.log(this);//-------------------->指向172行return 出来的新的对象{name: "王五", mytest3: ƒ, mytest4: ƒ}
    }

    function mytest4() {
        console.log('我是mytest2函数')
    }

    return {
        name: '王五',
        mytest3,
        mytest4
    }
}

let mytest5 = closure1();
mytest5.mytest3();

//加难度的例子
function closure2() {
    function test6() {
        console.log('我是test6函数');
        console.log(this);//---------->指向return的新对象
        function test7() {
            console.log('我是test7函数');
            console.log(this)//---------->指向window
        }

        return test7
    }

    return {test6}
}

//问题一:如何调用test7函数
let q = closure2();//首先运行这个函数得到一个对象,就是return{test6}这个对象,这个对象里面装了test6函数
let w = q.test6();//因此运行test6()这个函数,得到w,而w正好是return test7()出来的东西,里面包含了test7()
w();//因此运行这个就能拿到test7这个东西---------->打印:我是test7函数
//总结:this指向节点,实例化对象,window,看谁在调用,就是指向谁
//closure2().test6()()//上面的简写
//如果想改变test7里面的this指向,那么就只需要把193行改成:return test7.bind(this)------>改变以后都同时指向return{test6}这个对象

在箭头函数中的this指向

//1.箭头函数会绑定this
//2.箭头函数 不是声明式函数。说明你在箭头函数前面去调用它,那么就会报错undefined。function f(){}这种就是声明式函数。
//let abc=()=>{}
// 小括号里面只有一个参数的时候,可以省略小括号,没有参数或多个参数都不能省略
//当默认返回的时候,可以省略花括号
//箭头函数不能new 箭头函数没有arguments
// 例子
let obj = {
    name: '张三',
    getObj() {
        console.log(this);//----->指向obj
        return function () {
            console.log(this)//----->指向window
        }
    }
};
obj.getObj()();
//如果换成箭头函数
let obj1 = {
    name: '张三',
    getObj() {
        console.log(this);//----->指向obj
        return () => {
            console.log(this)//----->指向obj
        }
    }
};
obj1.getObj()();
//总结一下:为什么换成箭头函数以后,this的指向变成obj了呢?
//参考阮一峰es6讲解里面的:箭头函数里面的this不在指向调用者,而是指向定义这个箭头函数时的this指向
// (说白了就是跟箭头函数外层的this指向一样了)
//例如
let obj2 = {
    name: '张三',
    getObj() {
        console.log(this);
        return () => {
            console.log(this)
        }
    }
};
let newfun = obj2.getObj.call({name: '李白'});
newfun();
//上面两个this都会指向新的对象{name:'李白'}
//并且箭头函数里面的this一旦绑定,就不会改变
// 如:
function myfun() {
    console.log(this)
    return () => {
        return () => {
            return () => {
                console.log(this.name)
            }
        }
    }
}

let R = myfun.call({name: '王维'});
let R1 = R.call({name: '杜甫'})()()
//274行------------>打印:王维。
// 270行this的指向是’王维‘,函数myfun里面又都是箭头函数,因此指向定义箭头函数的定义者myfun()
//在279行又将定义者指向变成了’王维‘,且箭头函数里面的this一旦绑定,就不会再更改,因此274行打印为’王维‘

以上便是自己的一些学习心得,如有错误,欢迎指正。Javascript,天下无双。奥里给!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值