this指向指向 箭头函数中的
箭头函数中的this call、、apply和和bind方法的用法以及区别
方法的用法以及区别
thisthis 指向看看箭头函数的案例call、apply和bind方法的用法以及区别来几个面试题试试
this 指向指向
1.普通函数的this:指向它的调用者,如果没有调用者则默认指向window.
2.箭头函数的this: 指向箭头函数定义时所处的对象,而不是箭头函数使用时所在的对象,默认使用父级的this 箭头函数的父级还箭头还是 就从父级开始 向上查找 直到有(实际上箭头
函数里并没有 this,如果你在箭头函数里看到 this,你直接把它当作箭头函数外面的 this 即可。外面的 this 是什么,箭头函数里面的 this 就还是什么,因为箭头函数本身不支持
this。就默认看成使用父级的this)
对象中的函数叫方法
this 是当前对象的引用
如果函数是对象属性 或者类方法 this 就是当前对象
全局下调用的的函数 就是全局的对象 就是window
let obj = {
name :"ThinkerWing",
show:function () {
// console.log(this); // 返回当前对象obj
// return this.name;
function render() {
console.log(this);//Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …} 返回全局的对象
}
render();
}
}
obj.show();
console.log(this===window); //true
console.log(this===obj) //false
函数是不属于任何对象的,this是函数运行时再决定的
function user(name) { //找到当前的参数 不然name变成window
this.name = name; //这是属性 下面那条也是 属性的函数为方法
this.show = function () {
function render() {
console.log(this);//返回window
}
render()
console.log(this); //返回user 对象
}
}
let TK = new user("ThinkerWing");
TK.show();
看看箭头函数的案例
看看箭头函数的案例
let name = {
lastname:"wing",
firstname:["thinker","Thinker"],
show:function () {
console.log(this);
const self = this;
return this.firstname.map(function (value) {
return `${self.firstname}-${value}`
// 由上例子知普通函数就是全局的对象 window 所以这边用常量改变this指针
//(index) 0 thinker,Thinker -thinker
//(index) 1 thinker,Thinker -Thinker
})
}
};
console.table(name.show());
了解一下箭头函数的this 指向 然后利用箭头函数 重写上一个案例
var str = 'window';
const obj = {
str:'obj',
fn: ()=>{
console.log(this.str);
},
fn2: function(){
console.log(this.str, '当前词法作用域中的this');
return {
str: '我是fn2中的Obj 碰不到我的 箭头函数的this是指向上一级的',
fn: ()=>{
console.log(this.str);
}
}
}
};
obj.newFn = ()=>{
console.log(this.str);
};
obj.fn2(); //打印 obj 当前词法作用域中的this
obj.fn();//打印window
obj.newFn(); // 指向上一级的str 打印 window
var newObj = obj.fn2();
newObj.fn();//指向fn2()属性的上一级 即对象obj 打印obj的str即打印obj
了解了箭头函数的指向是父级的作用域 此时就不用担心普通函数的this指向全局
let name = {
lastname:"wing",
firstname:["thinker","Thinker"],
show:function () {
console.log(this); // 打印name 对象
return this.firstname.map( (v)=> {
console.log(this); // 打印值与上方的一样 同为name对象
//箭头函数指向父级作用域
return `${this.firstname}-${v}`
//(index) 0 thinker,Thinker -thinker
//(index) 1 thinker,Thinker -Thinker
})
}
};
console.table(name.show());
call、、apply和和bind方法的用法以及区别
方法的用法以及区别
先介绍一下apply是怎么传数组的 通过一个比大小的案例来解释
let arr = [0,1,2,3,4,5,6,7,8,9];
console.log(Math.max.apply(Math,arr)); //打印9
其实 apply 和 call 基本类似,他们的区别只是传入的参数不同。
apply是数组
let TK = {
name:"ThinkerWing"
};
function user(age,sex) {
console.log(age+"岁的"+sex+":"+this.name);
}
user.call(TK,20,"男生"); //打印 20岁的男生:ThinkerWing
user.apply(TK,[20,"男生"]) //打印 20岁的男生:ThinkerWing
来一个证明他们基本类似
function show() {
alert(this.innerHTML)
}
let btn = document.querySelectorAll("button");
for (let i = 0 ; i{
show.apply(event.target) //此处call与apply是一样的
// console.log(this) // 打印 window 因为这里箭头函数的父级就是window
})
}
重新回顾一下this的指向 为什么Age能打印20而fun 同样也是this.age却不行呢?
因为Age指向了全局 而fun中的指向了obj对象,对象中无age定义。
var name = "ThinkerWing", age = 20;
var obj = {
name : 'TK',
Age: console.log(this.age), //打印20
fun:function () {
console.log(this.name+"年龄"+this.age);
}
};
obj.fun() //打印 TK年龄undefined
var name = "ThinkerWing", age = 20;
var obj = {
name : 'TK',
Age: console.log(this.age), //打印20
fun:function (a,b,c) {
console.log(this.name+"年龄"+this.age+a+b+c);
}
};
var demo = {
name:'baby',
age:20
};
//缺少三个传参 因为这边只想调用年龄 姓名 证明三个实现是一样的
obj.fun.call(demo); //baby年龄20undefinedundefinedundefined
obj.fun.apply(demo); //baby年龄20undefinedundefinedundefined
obj.fun.bind(demo)(); //baby年龄20undefinedundefinedundefined
obj.fun.call(demo,"相遇","福州",2019); //baby年龄20相遇福州2019
obj.fun.apply(demo,["相遇","福州",2019]);//baby年龄20相遇福州2019
obj.fun.bind(demo,"相遇","福州",2019)();//baby年龄20相遇福州2019
obj.fun.bind(demo,["相遇","福州",2019])();//baby年龄20相遇,福州,2019undefinedundefined
//以上出了 bind 方法后面多了个 () 外 ,结果返回都一致!
// 由此得出结论,bind 返回的是一个新的函数,你必须调用它才会被执行
All in all (总的来说综上所述):
call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:
call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面
apply 的所有参数都必须放在一个数组里面传进去
bind 除了返回是函数以外,它 的参数和 call 一样。
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!
来几个面试题试试
来几个面试题试试
var obj = {
foo: function(){
console.log(this)
}
}
var bar = obj.foo
obj.foo()
bar()
答案: obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window
因为this就是对当前对象的引用 所以obj.foo() 打印了对象
bar() 是定义对象中的函数 普通的函数就是全局对象
var x = 12;
function test() {
console.log(this.x);
}
var obj = {
x:45,
ss:function () {
console.log(this.x);
}
};
var bar = obj.ss;
test();
obj.ss();
bar()
答案:
test(); //12
obj.ss(); //45
bar() //12
test 只是普通函数 this指向全局 全局变量 x =12;
这题同上题相似 只是换了数据
var name = "222";
var a = {
name :"111",
say : function () {
console.log(this.name);
}
};
var fun = a.say;
fun(); // 答案
a.say(); //答案
var b = {
name : "333",
say : function (fun) {
fun()
}
};
b.say(a.say); //答案
b.say = a.say;
b.say(); // 答案
fun(); //222
a.say(); //111
b.say(a.say); //222
b.say(); // 333
第一问 fun =a.say , 只是一个普通函数 全局变量 222
第二问 a.say() 指向对象 a 的name 111
第三问 先看括号中的a.say 类似将fun=a.say 然后执行fun() fun()的归属是window 不是某个对象中的
第四问 b.say() 指向对象 b 的name 333
作者:ThinkerWing