logo资料库

this指向 箭头函数中的this call、apply和bind方法的用法以及区别.pdf

第1页 / 共3页
第2页 / 共3页
第3页 / 共3页
资料共3页,全文预览结束
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
分享到:
收藏