网易试题——关于箭头函数与this和arguments的关系
生活随笔
收集整理的這篇文章主要介紹了
网易试题——关于箭头函数与this和arguments的关系
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
昨天做試題的時候遇到了這個題目
var a = 1;function fn1() {console.log(this.a)}const fn2 = () => {console.log(this.a)}const obj = {a: 10,fn1: fn1,fn2: fn2}fn1()fn2()obj.fn1()obj.fn2()哦這該死的網易,怎么出這么簡單的題目,答案是:1,1,10,10? ?對,應該是這樣的,吧?
可是再仔細一想,不對啊,我記得箭頭函數的this對象好像不是在運行時基于函數的執行環境綁定的,他是有點奇怪的,事后仔細查了資料才知道,原來正確答案應該是 :1,1,10,1
一言概之,是因為:箭頭函數的this和arguments只會從它自己所在作用域鏈的上一層繼承,不會創建自己的this和argumrnts!!!(只有函數才會有this和arguments屬性)
?讓我再舉幾個例子給泥們looklook:
//普通函數var obj = {bar: function () {console.log(this); // 被obj調用,this指向{bar: ?}bar: ? ()__proto__: Object var x = function() {console.log(this)//Window對象};return x;//閉包,this通常(即不使用箭頭函數的情況)默認為全局對象,若在嚴格模式則為undefined}};var fn = obj.bar();fn() ; //箭頭函數 // 創建一個含有bar方法的obj對象,// bar返回一個函數,// 這個函數返回this,// 這個返回的函數是以箭頭函數創建的,// 所以它的this被永久綁定到了它外層函數的this。// bar的值可以在調用中設置,這反過來又設置了返回函數的值。var obj = {bar: function () {console.log(this); // {bar: ?}bar: ? ()__proto__: Object var x = (() => this);return x;}};// 作為obj對象的一個方法來調用bar,把它的this綁定到obj。// 將返回的函數的引用賦值給fn。var fn = obj.bar();//此時外層函數已經運行完畢,他的this已經綁定到{bar: ?}這個環境console.log(fn() === obj); // trueconsole.log(fn()); // {bar: ?}bar: ? ()__proto__: Object // 直接調用fn而不設置this,// 通常(即不使用箭頭函數的情況)默認為全局對象// 若在嚴格模式則為undefined// 但是注意,如果你只是引用obj的方法,// 而沒有調用它,this沒有及時綁定到{bar: ?}這個環境var fn2 = obj.bar;// 那么調用箭頭函數后,this指向window,因為它從 bar 繼承了this。console.log(fn2()() == window); // true/* 此時等于在全局環境中調用 function () {console.log(this); // {bar: ?}bar: ? ()__proto__: Object var x = (() => this);return x;}*/?再來一粒,這次帶有arguments
//普通函數var name = "The Window";var object = {name: "My Object",getNameFunc: function () {console.log(arguments[0],'aa')//4console.log(this.name)//"My Object"return function () {//閉包,this通常指向windowconsole.log(arguments[0],'a')//5return this.name;};}};console.log(object.getNameFunc('4')('5')); // The Window//箭頭函數var name = "The Window";var object = {name : "My Object",getNameFunc : function(a) {console.log(this.name)//"My Object"console.log(arguments[0],'aa')//4return (a) => {console.log(arguments[0],'a')//4,這里是繼承了上一層的argumentsreturn this.name; //雖然是閉包,但成功繼承了上一層的this};}};console.log(object.getNameFunc('4')('5')); //"The Object"//函數都是箭頭函數var name = "The Window";var object = {name : "My Object",getNameFunc : (a) => {console.log(this.name)//"The Window"//console.log(arguments[0],'aa')//errorreturn (a) => {//console.log(arguments[0],'a')//errorreturn this.name; };}};console.log(object.getNameFunc('4')('5')); //"The Window"//此時雖然是object調用了getNameFunc函數,但是箭頭函數的this是指向上一層環境,即全局環境,所以this指向Window對象,而Window對象沒有arguments,所以會出錯箭頭函數還有一個值得注意的特性—— 無法使用call或者apply綁定this值。
由于 箭頭函數沒有自己的this指針,通過?call()?或?apply()?方法調用一個函數時,只能傳遞參數(不能綁定this),他們的第一個參數會被忽略。(這種現象對于bind方法同樣成立)
var name = "The Window";var object = {name : "My Object",getNameFunc : function(a) {console.log(this.name)//"outer"console.log(arguments[0],'aa')//4return (a) => {console.log(arguments[0],'a')//4return this.name; };}};console.log(object.getNameFunc.call({name:'outer'},'4').call({name:'inner'},'5')); //"outer"再來一題,也是網易的
function fun() {return () => {return () => {return () => {console.log(this.name)}}}}var f = fun.call({ name: 'foo' }); f.call({name:'1'})()()//foo f().call({name:'2'})()//foo f()().call({name:'3'})//foo?你做對了嗎?
推薦閱讀
this 指向詳細解析(箭頭函數)
箭頭函數
this
JavaScript中的匿名函數及函數的閉包
徹底理解js中this的指向,不必硬背。
對匿名函數的深入理解(徹底版)
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的网易试题——关于箭头函数与this和arguments的关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java commit()_Java X
- 下一篇: UML画图工具汇总