当前位置: 首页 > 科技观察

关于“这”的七道面试题,你能答对吗?

时间:2023-03-16 01:42:31 科技观察

本文已获得原作者Shadeed授权翻译。在JavaScript中,这表示函数调用上下文。这样做的难点在于它有一个复杂的行为,这也是面试中经常考到的一个点。本文列出了7个关于此的有趣面试题:问题1:变量vs属性问题2:猫的名字问题3:延迟问候问题4:手动方式问题5:问候与告别问题6:刁钻的长度问题7:调用参数问题1:变量vs属性的打印结果是什么:constobject={message:'Hello,World!',getMessage(){constmessage='Hello,Earth!';returnthis.message;}};console.log(object.getMessage());//??回答:“你好,世界!”object.getmessage()是一个方法调用,此时的this就是object的意思。该方法还有一个变量声明constmessage='Hello,Earth!'。这个变量都不会影响this.message的值。问题2:下面的代码打印Cat的名字是什么:functionPet(name){this.name=name;this.getName=()=>this.name;}constcat=newPet('Fluffy');console.log(cat.getName());//Whatislogged?const{getName}=cat;console.log(getName());//Whatislogged?Answer:'Fluffy'and'Fluffy'whenfunctionasconstructornewPet('Fluffy')调用时,构造函数内部的this等于构造的对象。Pet构造函数中的this.name=name表达式在构造的对象上创建一个name属性。this.getName=()=>this.name在构造的对象上创建方法getName。并且因为使用了箭头函数,所以箭头函数内部的this值等于外部作用域的this值,即Pet。调用cat.getName()和getName()返回表达式this.name,其计算结果为“Fluffy”。问题三:延迟问候下面的代码打印了什么:constobject={message:'Hello,World!',logMessage(){console.log(this.message);//Whatislogged?}};setTimeout(object.logMessage,1000);答案:1秒后,打印undefined。尽管setTimeout()函数使用object.logMessage作为回调,但object.logMessage仍然用作常规函数,而不是方法。在常规函数调用期间,this等于全局对象,即浏览器上下文中的window。这就是为什么logMessage方法中的this.message等于window.message,是未定义的。问题四:手动方式如何调用logMessage函数,让它打印“Hello,World!”?message:'Hello,World!'};functionlogMessage(){console.log(this.message);//"Hello,World!"}答案:至少有3种方式:message:'Hello,World!'};functionlogMessage(){console.log(this.message);//记录'Hello,World!'}//Usingfunc.call()methodlogMessage.call(object);//Usingfunc.apply()methodlogMessage.apply(object);//CreatingaboundfunctionconstboundLogMessage=logMessage.bind(object);boundLogMessage();问题5:问候和告别下面的代码打印了什么:constobject={who:'World',greet(){return`Hello,${this.who}!`;},farewell:()=>{return`再见,${this.who}!`;}};console.log(object.greet());//记录了什么?console.log(object.farewell());//记录了什么?回答:“你好,世界!”和'再见,未定义!'。当调用object.greet()时,在greet()方法内部,this等于object,因为greet是一个常规函数。所以object.greet()返回'Hello,World!'。但是farewell()是一个箭头函数,箭头函数中this的值永远等于外作用域中this的值。farewell()的外层作用域是全局作用域,也就是全局对象。所以object.farewell()实际上返回'Goodbye,${window.who}!'结果是“再见,未定义!”。问题6:棘手的长度以下代码打印了什么:varlength=4;functioncallback(){console.log(this.length);//Whatislogged?}constobject={length:5,method(callback){callback();}};object.method(回调,1,2);答案:4callback()是在method()内部使用常规函数调用调用的。由于在常规函数调用期间this的值等于全局对象,因此this.length结果为window.length。.第一条语句varlength=4位于最外层范围内,并在全局对象窗口上创建一个属性length。问题7:下面调用参数的代码打印了什么:varlength=4;functioncallback(){console.log(this.length);//记录了什么?}constobject={length:5,method(){arguments[0]();}};object.method(回调,1,2);答案:3obj.method(callback,1,2)被调用时带有3个参数:callback、1和2。因此,method()中的参数特殊变量是一个具有以下结构的类数组对象:{0:callback,1:1,2:2,length:3}因为arguments[0]()是arguments对象上的回调方法Called,所以回调里面的arguments等于arguments。所以callback()中的this.length和arguments.length一样都是3。~完了,我是小智,下期见!作者:Shadeed译者:前端小智来源:dmitripavlutin原文:https://dmitripavlutin.com/javascript-this-interview-questions/