1. 程式人生 > >剛看到一道JS面試題,關於this指向的問題,很有意思,記錄一下

剛看到一道JS面試題,關於this指向的問題,很有意思,記錄一下

感謝@百里乘風、@qq_43146937指出的文章中的錯誤。

let宣告變數會形成塊級作用域,且不存在宣告提升,而var存在宣告提升。所以當使用let宣告變數時,不存在宣告提升,length屬性實際上並沒有新增到window物件中。從下面的例子可以看出

所以原文程式碼跑出來的結果是有錯誤的。就像下面的結果

我當時能跑出10,2這個結果是因為事先在控制檯使用var宣告過length屬性,而且沒有關閉瀏覽器,所以window物件上保留著length屬性。

使用var宣告變數,才是這篇文章實際想要分享出來的東西,就像下面。

var length = 10;
function fn() {
    console.log(this.length);
}

var obj = {
  length: 5,
  method: function(fn) {
    fn();
    arguments[0]();
  }
};

obj.method(fn, 1);//輸出是什麼?

是不是奇怪為啥輸入(fn,1)兩個引數,是不是賊奇怪為什麼不是10和5或者5和5??哈哈,慢慢解釋。

最先我以為是形參與實參的問題,但是後來發現不是這樣,於是去跑了個例子

var length = 10;
function fn() {
    console.log(this.length);
}
 
var obj = {
  length: 5,
  method: function() {
    fn();
  }
};
 
obj.method();

上面例子的程式碼執行後,輸出依然是10。如果按照之前實參與形參的想法,輸出應該是5的,所以與形參和實參沒有關係。這裡的this繫結到了全域性物件上,即window物件上。

var length = 10;
function fn() {
    console.log(this.length);
}
 
var obj = {
  length: 5,
  method: function() {
    fn.call(this);
  }
};
 
obj.method();

當我利用call方法改變this的繫結後,輸出就是5了,說明this繫結到了obj物件上。

此時這個問題就需要回到那句"this永遠指向呼叫他的物件"話了,在執行obj.method()方法時,如果函式內部有this,則this確實是指向obj,但是method()內部執行的是fn()函式,而fn()函式繫結的物件是window,即window.fn()。還是用例子來說明。

var length = 10;
function fn() {
    console.log(this.length);
}
 
var obj = {
  length: 5,
  method: function() {
    console.log(this.length);//輸出5,執行method方法時,this繫結到呼叫物件obj上
    fn();//輸出10,執行method方法時,內部執行的是fn()函式,this繫結到了window上,即window.fn();
  }
};
 
obj.method();//輸出5 10

然後別忘了全域性函式fn同時也屬於arguments陣列中的一員,即當作為arguments成員之一呼叫的時候,其作用域就繫結到了arguments上,this也就是指向了arguments物件,所以arguments[0]()這段程式碼呼叫了身為成員的fn()函式,this.length就等於是arguments.length,又因為method傳入的引數為2個,所以最後輸出2。

果然var宣告變數坑真多。。。

題目是在https://zhuanlan.zhihu.com/p/36550058看到的

我也轉載了一波,在本人部落格https://blog.csdn.net/sinat_36521655/article/details/80254621中也可以看

前端萌新,嘿嘿。如解釋有誤,希望大家指出來。

相關推薦

看到一道JS試題關於this指向的問題有意思記錄一下

感謝@百里乘風、@qq_43146937指出的文章中的錯誤。 let宣告變數會形成塊級作用域,且不存在宣告提升,而var存在宣告提升。所以當使用let宣告變數時,不存在宣告提升,length屬性實際上並沒有新增到window物件中。從下面的例子可以看出 所以原文程式碼

一道JS試題所引發的"血案"透過現象尋本質再從本質現象

覺得本人寫的不算很爛的話,可以登入關注一下我的GitHub部落格,新手寫東西寫的不好之處,還望見諒,畢竟水平有限,寫東西只為交流提高,一起學習,還望大神多加指點,指出紕漏,和提出寶貴的意見,部落格會堅持寫下去。 今天同學去面試,做了兩道面試題,全部做錯了,發過來給我看,我一眼就看出來了,因為這種題我做過,至

js試題關於this指向分析

分析以下問題的列印結果及原因: 1、 let num = 10; function fn() { console.log(this.num); } let obj = {

關於一道JS試題的思考

ges 會有 作用 初學 沒有 使用 很好 obj 值傳遞 題目: for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(new Date, i); },

js試題關於變量提升作用域全局變量

fine log js面試 提升 per nbsp lin undefine 變量 /**********seperate line************/ var a = 10; function test() {   a = 100;   cons

一道Python試題:給出d = [True, False, True, False, True]請利用列表d只用一句話返回列表[0,2,4]

分享 忽略 class pytho 面試題 inf pos 如何 返回   前言:還是我,一個不知死活的小白,冒著生命危險去了一家有逼格的公司面試,去面試的路上就經歷了一番波折,公交車死等不來,最後差點誤了面試時間,這都不算什麽了,雖然對面試不抱什麽希望,但在技術面被虐成了

一道考察運算子優先順序的JS試題

文章目錄 題目 分析 1. Foo.getName() 2 .getName 3. Foo().getName() 4. getName()

#套路非常深的一道Java試題 你中招了嗎?

在求職的過程中,技術測試是不可缺少的一部分,也是最關鍵的一部分,但是有些面試官喜歡去抽一些“套路”比較深的題目,看看面試者對於程式設計的理解是否深刻,這其中的題目中,也不乏有佼佼者! 如果有想學習java的程式設計師,可來我們的java學習扣qun:79979,2590免費送java的視訊教程噢

一道關於物件賦值的js試題

一道關於物件賦值的js面試題   var a = { n : 1};     var b = a;     a.

一道Java試題 讀取一篇英文文章輸出其中出現單詞的次數最多的5個,寫java函式

package com.test.string; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayLis

一道常被人輕視的前端JS試題

前言 年前剛剛離職了,分享下我曾經出過的一道面試題,此題是我出的一套前端面試題中的最後一題,用來考核面試者的JavaScript的綜合能力,很可惜到目前為止的將近兩年中,幾乎沒有人能夠完全答對,並非多難只是因為大多面試者過於輕視他。 題目如下: function Foo() { getNa

一道簡單試題來解讀JS中的閉包和作用域

先上程式碼 var count=10;//全域性作用域 標記為f1 function add(){ var count=0;//函式全域性作用域 標記為f2 return function(){ count+=1;//函式的內部作用域 alert(

一道經典試題-----setTimeout(function(){}0)

一道經典面試題—–setTimeout(function(){},0) 先看題: 1 for (var i = 0; i < 3; i++) { 2 setTimeout(function() { 3 console.log(i); 4 }, 0); 5 co

一道試題:請寫sql查詢出成績小於60的同學的姓名和平均分並按平均分排序

給出如下3張表,stu表、sc表和course表: /* Navicat MySQL Data Transfer Source Server         : db_fightLandlor Source Server Version : 50520 Source Ho

曹工雜談:一道阿里試題兩個執行緒交替列印奇偶數

一、前言 這些天忙著寫業務程式碼,曹工說Tomcat系列暫時沒時間寫,先隨便寫點其他的。 逛部落格園的時候,發現一篇園友的阿里面試文章,https://www.cnblogs.com/crossoverJie/p/9404789.html。 裡面提到了:兩個執行緒,交替列印奇偶數這道筆試題。 看了園友

why哥被阿里一道基礎試題給幹懵了一氣之下寫出萬字長文。

這是why的第 65 篇原創文章 荒腔走板 大家好,我是 why,歡迎來到我連續周更優質原創文章的第 65 篇。老規矩,先荒腔走板聊聊技術之外的東西。 上面這圖是去年的成都馬拉松賽道上,攝影師抓拍的我。哎,真是陽光向上的 95 後帥小夥啊。 今年由於疫情原因,上半年的馬拉松比賽全部停擺了。今年可能也沒有機

整理出來的前端js試題

禁止 如何改變 產生 字符串 避免 得到 作用 擴展 如何 15、HTTP狀態碼 100 Continue 繼續,一般在發送post請求時,已發送了http header之後服務端將返回此信息,表示確認,之後發送具體參數信息 200 OK 正常返回信

js試題知識點全解(一作用域和閉包)

foo true 方式 聲明 提升 function 這樣的 all 變量提升 問題: 1.說一下對變量提升的理解 2.說明this幾種不同的使用場景 3.如何理解作用域 4.實際開發中閉包的應用 知識點: js沒有塊級作用域只有函數和全局作用域,如下代碼: if(tru

js試題-----作用域與閉包

code 生命 結果 bin 聲明 click 函數 i++ spa 1、問題代碼: var length = 10; function fn(){ console.log(this.length); } var obj = { length:5,

js試題-----DOM操作和BOM操作

dom 數據 prop 樹形 結構 獲取 protocol earch 部分 題目1:DOM是哪種基本的數據結構 答案:DOM是一種樹形結構的數據結構 題目2:DOM操作的常用API有哪些 答案:獲取DOM節點,以及節點的property和Attribute。獲取父節點,獲