欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript this綁定與this指向問題的解析

 更新時間:2023年02月27日 10:18:25   作者:舒彬琪  
本文主要介紹了JavaScript this綁定與this指向問題的解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、this 綁定

怎么理解 this?

其實 this 就是一個指針,它指示的就是當前的一個執(zhí)行環(huán)境,可以用來對當前執(zhí)行環(huán)境進行一些操作。

MDN 解釋:在絕大多數(shù)情況下,函數(shù)的調(diào)用方式?jīng)Q定了 this 的值(運行時綁定)。this 不能在執(zhí)行期間被賦值,并且在每次函數(shù)被調(diào)用時 this 的值也可能會不同。ES5 引入了 bind 方法來設(shè)置函數(shù)的 this 值,而不用考慮函數(shù)如何被調(diào)用的。ES2015 引入了箭頭函數(shù),箭頭函數(shù)不提供自身的 this 綁定(this 的值將保持為閉合詞法上下文的值)。

this 是如何綁定的?

每個函數(shù)的 this 是在調(diào)用時被綁定的,完全取決于函數(shù)的調(diào)用位置。我們找到函數(shù)的調(diào)用位置,然后運用以下四種綁定規(guī)則來判斷函數(shù)的 this 指向。

1、默認綁定

函數(shù)的 this 會默認綁定到全局對象 window 上,如果在嚴格模式中,this 綁定到 undefined。

function foo (){
  console.log(this.a)
}
let a = 1
foo() // 1

2、隱式綁定

調(diào)用位置是否有上下文對象,或者被某個對象擁有或包含。

function foo(){
  console.log(this.a)
}
let obj = {
  a: 2,
  foo:foo
}
let a = 1
obj.foo(); // 2

function foo(){
  console.log(this.a)
}
let obj1 = {
  a: 2,
  foo: foo
}
let obj2 = {
  a: 3,
  obj1: obj1
}
let a = 1
obj2.obj1.foo(); // 2

3、顯式綁定

直接改變 this 指向,綁定到另一個執(zhí)行環(huán)境

function foo(){
  console.log(this.a)
}
let obj = {
  a: 1
}
foo.call(obj)

4、new 綁定

new 出來的函數(shù) this 綁定的是新創(chuàng)建的對象

function Foo(a){
  this.a = a
}
let bar = new Foo(2)
console.log(bar.a) // 2

this 綁定優(yōu)先級

默認綁定的優(yōu)先級是最低的

new 綁定 > 顯式綁定 > 隱式綁定 > 默認綁定

1、顯示綁定 VS 隱式綁定

function foo(){
  console.log(this.a)
}
let obj1 = {
  a: 1,
  foo: foo
}
let obj2 = {
  a: 2
}
console.log(obj1.foo()) // 1
obj1.foo.call(obj2) // 2

通過以上代碼我們可以看到 顯式綁定 的優(yōu)先級高于 隱式綁定

2、顯示綁定 VS new 綁定

function foo(a){
  this.a = a
}
let obj1 = {
  foo
}
let bar = foo.bind(obj1)
bar(2)
console.log(obj1.a) // 2
let bar2 = new bar(3)
console.log(obj1.a) // 2
console.log(bar2.a) // 3

new 修改了顯示綁定 調(diào)用 bar 中的 this,所以 new 綁定的優(yōu)先級高于顯式綁定

二、this 指向

判斷準則

第一準則:this 永遠指向函數(shù)運行時所在的對象,而不是函數(shù)被創(chuàng)建時所在的對象。(不包含箭頭函數(shù))

第二準則:無論是否在嚴格模式下,在全局執(zhí)行環(huán)境中(在任何函數(shù)體外部)this 都指向全局對象。

判斷順序

  • 函數(shù)是否在 new 中調(diào)用,如果是的話 this 綁定的是新創(chuàng)建的對象;
  • 函數(shù)是否通過 call、apply、bind 的方式調(diào)用,如果是的話 this 綁定的是指定的對象;
  • 函數(shù)是否在某個上下文中被調(diào)用,如果是的話 this 綁定的是函數(shù)調(diào)用的上下文;
  • 除此之外 this 綁定的就是全局對象 在嚴格模式下綁定的是 undefined。

常見的指向問題

  • 箭頭函數(shù)沒有自己的 this 指針(需要從執(zhí)行上下文來進行判斷)

三、改變 this 指向

有四種方式

  • 變量保存 this:將 this 臨時保存下來
  • call():使用一個指定的 this 值和單獨給出的一個或多個參數(shù)來調(diào)用一個函數(shù)。
  • bind():會有一個返回值,返回值是一個擁有第一個函數(shù)作用域的新的函數(shù)體
  • apply():調(diào)用一個具有給定 this 值的函數(shù),以及以一個數(shù)組(或一個類數(shù)組對象)的形式提供的參數(shù)。

變量保存 this

var _this = window;
var obj = {
    name:"張三",
    show:function(){
        console.log(this) //obj
        console.log(_this) // window
    }
}
obj.show()

call

call() 方法使用一個指定的 this 值和單獨給出的一個或多個參數(shù)來調(diào)用一個函數(shù)。

函數(shù)名稱.bind(參數(shù)1,參數(shù)2,a,b,c.....)
    參數(shù)1:當前函數(shù)的作用域
    參數(shù)2:需要傳遞的參數(shù),參數(shù)是一個一個傳

function fn(a,b){
    console.log(this,a,b)
}
document.onclick = functioin(){
    fn.call(document,1,2)
}

可以使用 call 來實現(xiàn)繼承:寫一個方法,然后讓另外一個新的對象來繼承它(而不是在新對象中再寫一次這個方法)。

function Product(name, price) {
  this.name = name;
  this.price = price;
}
function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}
function Toy(name, price) {
  Product.call(this, name, price);
  this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);

bind

bind 創(chuàng)建一個新的函數(shù),在 bind() 被調(diào)用時,這個新函數(shù)的 this 被指定為 bind() 的第一個參數(shù),而其余參數(shù)將作為新函數(shù)的參數(shù),供調(diào)用時使用。

特性就是會有一個返回值,返回值是一個擁有第一個函數(shù)作用域的新的函數(shù)體

函數(shù)名稱.bind(參數(shù)1,參數(shù)2.....)() // 必須調(diào)用一下
    參數(shù)1:當前函數(shù)的作用域
    參數(shù)2:需要傳遞的參數(shù)

var obj = {
    name:"張三",
    show:function(val){
        console.log(this) //obj  沒有修改前
        console.log(this,1) // document 1     修改后
    }
}
obj.show().bind(document,1)()

MDN:ECMAScript 5 引入了 Function.prototype.bind()。調(diào)用 f.bind(someObject) 會創(chuàng)建一個與 f 具有相同函數(shù)體和作用域的函數(shù),但是在這個新函數(shù)中,this 將永久地被綁定到了 bind 的第一個參數(shù),無論這個函數(shù)是如何被調(diào)用的。

apply

apply() 方法調(diào)用一個具有給定 this 值的函數(shù),以及以一個數(shù)組(或一個類數(shù)組對象)的形式提供的參數(shù)。

函數(shù)名稱.bind(參數(shù)1,[參數(shù)2,a,b,c.....])
    參數(shù)1:當前函數(shù)的作用域
    參數(shù)2:需要傳遞的參數(shù)   數(shù)組

function fn(a,b,c){
    console.log(this,a,b,c)
}
document.onclick = functioin(){
    fn.apply(document,[1,2,3])
}

call ,apply ,bind 三者的區(qū)別

不同點:

  • bind 會有一個返回值,返回值是函數(shù)體,因此需要加上 () 才能調(diào)用 
  • call,apply 是沒有返回值的,當改變函數(shù) this 指向的時候,函數(shù)就會執(zhí)行,不需要加 () 調(diào)用
  • call 傳遞參數(shù)的時候是一個一個傳遞的
  • apply 是傳遞一個數(shù)組或者類數(shù)組對象的參數(shù)

到此這篇關(guān)于JavaScript this綁定與this指向問題的解析的文章就介紹到這了,更多相關(guān)JavaScript this綁定與this指向內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論