亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入了解JavaScript中的this關鍵字指向

 更新時間:2023年07月24日 10:57:23   作者:coder_7  
這篇文章主要介紹了深入了解JavaScript中的this關鍵字指向,在大多情況下,this出現(xiàn)在函數(shù)中,this指向什么,跟函數(shù)定義的位置無關,跟函數(shù)調用方式有關,需要的朋友可以參考下

全局作用域的this

  • 游覽器:非嚴格模式指向window,嚴格模式指向undefined
  • Node環(huán)境:指向{}
    • 把文件看作module -> 加載編譯 -> 放到一個函數(shù)中 -> 通過 apply({})/call({}) 執(zhí)行這個函數(shù)

調用方式不同,this指向不同

在大多情況下,this出現(xiàn)在函數(shù)中。this指向什么,跟函數(shù)定義的位置無關,跟函數(shù)調用方式有關(綁定規(guī)則相關)。

function foo(){
	console.log(this);
}
var obj = {
	foo: foo
}
//不同的調用方式this的指向不同,不同的調用方式對應著不同的綁定規(guī)則
foo();//window
obj.foo();//obj
foo.call("123");//String{"abc"}

this的綁定規(guī)則

  1. 默認綁定:函數(shù)獨立調用方式,this指向全局對象
  2. 隱式綁定:通過對象調用方法,會隱式的將this指向當前對象
  3. 顯示綁定:通過函數(shù)的apply、call、bind方法改變函數(shù)中this的指向
    • apply/call:會自動調用,第一個參數(shù)都是設置this的指向,apply第二個參數(shù)為數(shù)組,call后面?zhèn)魅霝閰?shù)列表。
    • bind:不會自動調用,會返回一個已經綁定好this的函數(shù),傳參與call一樣
  4. new綁定 :通過new關鍵字調用函數(shù),new 函數(shù)()
    • 創(chuàng)建一個全新的對象
    • 這個新對象會被執(zhí)行prototype連接
    • 執(zhí)行構造函數(shù)中的代碼,為新對象添加屬性(this綁定在這個步驟完成)
    • 如果函數(shù)沒有返回其他對象,表達式會返回這個新對象

this綁定優(yōu)先級(權重)

  • 示綁定(bind>call/apply) > 隱式綁定 > 默認綁定
function fn() {
  console.log(this);
}
fn.bind(123).apply(321);
  • new 綁定 > 隱式綁定 > 默認綁定
  • new 綁定 > 顯示綁定(通過bind綁定this的函數(shù),可以被new關鍵字改變this指向)
function Fn(){
  console.log(this);
}
fn.bind("132");
var obj = new Fn();
  • new關鍵字不能和call/apply一起使用,因為new會主動調用函數(shù),call/apply也會主動調用函數(shù),這樣會產生沖突報錯

綁定優(yōu)先級:new 綁定 > 顯示綁定 > 隱式綁定 > 默認綁定

this規(guī)則之外

忽略顯示綁定

apply/call/bind:當傳入null/undefined時,自動將this綁定成全局對象

function fn(){
  console.log(this);
}
fn.apply(null);
fn.apply(undefined);

間接函數(shù)引用

var obj1 = {
	foo: function(){
		console.log(this);
	}
}
var obj2 = {}
;(obj2.bar = obj1.foo)()//括號中包含賦值表達式,屬于獨立函數(shù)調用,是默認綁定,指向window

箭頭函數(shù) 將頭函數(shù)不會綁定this,arguments屬性箭頭函數(shù)不能作為構造函數(shù)來使用(不能new對象) 簡寫

  • 簡寫一:當參數(shù)只有一個,可以省略括號
  • 簡寫二:當函數(shù)體只有一行,可以省略大括號,并且會將這一行代碼的返回值return
var nums = [0, 1, 2, 3, 4, 5];
var result = nums
  .filter(item => item % 2 === 0)
  .map(item => item * 10)
  .reduce((preVal, curVal) => preVal + curVal, 0);
console.log(result);
  • 簡寫三:如果只有一個行,且需要返回一個對象,那么要將對象用括號包裹。因為省略"{}“后,不知道將對象的”{}"如何解析
var foo = () => ({ name: "foo", age: 18 });//這樣解析時會將對象當作一個整體

箭頭函數(shù)的this綁定

箭頭函數(shù)不遵循this的四種標準規(guī)則,箭頭函數(shù)內部沒有綁定this,也不能通過call/apply/bind綁定this,箭頭函數(shù)的this指向根據(jù)外層作用域決定

var obj = {
  getData() {
    setTimeout(function () {
      console.log(this);
    }, 200);
  },
};
//setTimeout中的函數(shù)屬于獨立調用,所以指向的是window
//如果想讓this指向obj對象,setTimeout中使用箭頭函數(shù)
obj.getData();

this相關面試題

面試題一:

var name = "window";
var person = {
  name: "person",
  sayName: function () {
    console.log(this.name);
  }
};
function sayName() {
  var sss = person.sayName;
  sss(); 
  person.sayName(); 
  (person.sayName)(); 
  (b = person.sayName)(); //包含賦值表達式,屬于間接函數(shù)引用
}
sayName();

答案:window(默認綁定)、person(隱式綁定)、person(隱式綁定)、window(間接函數(shù)引用)

面試題二:

var name = 'window'
var person1 = {
  name: 'person1',
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person2 = { name: 'person2' }
person1.foo1(); 
person1.foo1.call(person2); 
person1.foo2();
person1.foo2.call(person2);
person1.foo3()();
person1.foo3.call(person2)();
person1.foo3().call(person2);
person1.foo4()();
person1.foo4.call(person2)();
person1.foo4().call(person2);

答案解析:

person1.foo1(); //person1:隱式綁定
person1.foo1.call(person2); //person2:顯示綁定
person1.foo2();//window:箭頭函數(shù)的this指向上層作用域的this
person1.foo2.call(person2);//window:箭頭函數(shù)的this指向上層作用域的this,且不能改變箭頭函數(shù)指向
person1.foo3()();//window:先執(zhí)行person1.foo3(),然后拿到返回的函數(shù)再調用,屬于獨立調用,所以指向window
person1.foo3.call(person2)();//window:先執(zhí)行person1.foo3.call(person2),拿到返回的函數(shù)再調用,屬于獨立調用
person1.foo3().call(person2);//person2:先執(zhí)行person1.foo3(),拿到返回的函數(shù)通過call調用this指向了person2
person1.foo4()(); //person1:拿到返回的箭頭函數(shù)后,箭頭函數(shù)沒有this,根據(jù)上層作用域決定,上層foo4函數(shù)指向的是person1對象(foo4是被person1直接調用的),所以內部箭頭函數(shù)也指向peroson1
person1.foo4.call(person2)(); //person2:給foo4綁定this為person2,箭頭函數(shù)調用this指向上層作用域,上層foo4的this被顯示綁定為了person2,那么內部的箭頭函數(shù)也是指向person2
person1.foo4().call(person2); //person1:call調用箭頭函數(shù),依然去上一層找,所以依然是person1

面試題三:

var name = 'window'
function Person (name) {
  this.name = name
  this.foo1 = function () {
    console.log(this.name)
  },
  this.foo2 = () => console.log(this.name),
  this.foo3 = function () {
    return function () {
      console.log(this.name)
    }
  },
  this.foo4 = function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')
person1.foo1()
person1.foo1.call(person2)
person1.foo2()
person1.foo2.call(person2)
person1.foo3()()
person1.foo3.call(person2)()
person1.foo3().call(person2)
person1.foo4()()
person1.foo4.call(person2)()
person1.foo4().call(person2)

答案與解析:

person1.foo1() //person1
person1.foo1.call(person2) //person2
person1.foo2() //person1:箭頭函數(shù),指向上層作用域的this,上層作用域是“Person構造函數(shù)”
person1.foo2.call(person2) //person1::箭頭函數(shù),指向上層作用域的this,不能被顯示綁定
person1.foo3()() //window:拿到返回的函數(shù)后調用,屬于獨立調用
person1.foo3.call(person2)() //window:拿到返回的函數(shù)后調用,屬于獨立調用
person1.foo3().call(person2) //person2:通過call顯示綁定
person1.foo4()() //person1:返回的箭頭函數(shù)去上層作用域找,上層foo的this指向person1
person1.foo4.call(person2)()//person2:返回的箭頭函數(shù)去上層作用域找,上層this通過call指向了person2
person1.foo4().call(person2)//person1:箭頭函數(shù)的this不能被顯示綁定

面試題四:

var name = 'window'
function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj',
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')
person1.obj.foo1()()
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)
person1.obj.foo2()()
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)

答案與解析:

person1.obj.foo1()() //window:獨立調用
person1.obj.foo1.call(person2)() //window:獨立調用
person1.obj.foo1().call(person2) //person2:call顯示綁定
person1.obj.foo2()() //obj:返回的是箭頭函數(shù),this由上層作用域foo2函數(shù)決定,foo2的this指向obj(foo2是被obj直接調用的),所以返回的箭頭函數(shù)this也是指向obj
person1.obj.foo2.call(person2)()//person2:箭頭函數(shù)上層作用域this被call指向person2,所以箭頭函數(shù)也是指向person2
person1.obj.foo2().call(person2)//obj:箭頭函數(shù)this不能被顯示綁定

到此這篇關于深入了解JavaScript中的this關鍵字指向的文章就介紹到這了,更多相關JavaScript中的this內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論