// <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,天下无双。奥里给!