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

JavaScript中?this?的綁定指向規(guī)則

 更新時(shí)間:2022年06月07日 09:01:39   作者:??jpliu????  
這篇文章主要介紹了JavaScript中?this?的綁定指向規(guī)則,this的指向問(wèn)題存在各種各樣的,關(guān)于如何綁定指向,下面文章作簡(jiǎn)單介紹需要的小伙伴可以參考一下

問(wèn)題來(lái)源

在 js 中,有一個(gè)疑惑的點(diǎn) this, 它的指向問(wèn)題,存在各種各樣的,來(lái)看一下,它是如何綁定指向的吧

  • 函數(shù)在調(diào)用時(shí),JavaScript 會(huì)默認(rèn)給 this 綁定一個(gè)值
  • this 的綁定和定義的位置(編寫(xiě)的位置)沒(méi)有關(guān)系
  • this 的綁定和調(diào)用方式以及調(diào)用的位置有關(guān)系
  • this 是在運(yùn)行時(shí),動(dòng)態(tài)綁定的

this 綁定規(guī)則

1.默認(rèn)綁定

注意: 嚴(yán)格模式下默認(rèn) this 為 undefined ,非嚴(yán)格模式下才是 window

作為獨(dú)立函數(shù)調(diào)用時(shí),采用的默認(rèn)綁定規(guī)則:

function foo() {
  console.log(this) // window
}

function test1() {
  console.log(this) // window
  test2()
}
function test2() {
  console.log(this) // window
  test3()
}
function test3() {
  console.log(this) // window
}

test1()

function fn(fnc) {
  fnc()
}

var obj = {
  bar: function () {
    console.log(this)
  }
}

fn(obj.bar) // window 因?yàn)閌obj.bar`取出的是函數(shù),函數(shù)再被獨(dú)立執(zhí)行的

2.隱式綁定

作為對(duì)象方法調(diào)用時(shí),采用隱式綁定規(guī)則

function foo() {
  console.log(this)
}

var obj = {
  bar: foo
}
obj.bar() // obj

var obj1 = {
  bar: foo
}
var obj2 = {
  obj1: obj1
}
obj2.obj1.bar() // obj1

var obj3 = {
  foo: foo
}
var bar = obj1.foo
// 取出函數(shù),獨(dú)立調(diào)用了
bar() // window

3.顯示綁定

使用 call、apply、bind 進(jìn)行綁定

function foo() {
  console.log(this)
}

// bind
var obj = {
  name: 'jpliu'
}
var bar = foo.bind(obj)
bar() // obj

// call/apply
foo.call(window) // window
foo.call({ name: 'jpliu' }) // {name: 'jpliu'}
foo.call(123) // Number對(duì)象的123     Number?{123}
foo.apply('123') // String 對(duì)象的'123'  String?{'123'}

4.new 綁定

通過(guò) new 關(guān)鍵字實(shí)例化對(duì)象的時(shí)候,綁定為實(shí)例化的對(duì)象

function Person(name) {
  console.log(this) // Person {}
  this.name = name // Person { name: 'jpliu' }
}
var p = new Person('jpliu')
console.log(p)

5.內(nèi)置方法

// 其實(shí)算是隱式綁定,因?yàn)檫@些方法都是 `window`的
window.setTimeout(function () {
  // 這里或許沒(méi)這么簡(jiǎn)單,這個(gè)是回調(diào)函數(shù),與隱式綁定,沒(méi)啥關(guān)系,這里是瀏覽器實(shí)現(xiàn)的黑盒
  // 在 v8 中,有一個(gè)測(cè)試用例,模擬,是采用 call 綁定的,this是指向的 window
  // 所以這個(gè)看具體如何實(shí)現(xiàn)
  console.log(this) // window
}, 2000)

// 2.監(jiān)聽(tīng)點(diǎn)擊
const boxDiv = document.querySelector('.box')
// 隱式綁定 `boxDiv` 的`onclick` 方法觸發(fā)
boxDiv.onclick = function () {
  console.log(this)
}
// `addEventListener`的`this`是隱式綁定
// 當(dāng)`callback`的`this`沒(méi)有顯示綁定時(shí)
// 使用`bind`顯示綁定`addEventListener`的`this`
boxDiv.addEventListener('click', function () {
  console.log(this)
})
boxDiv.addEventListener('click', function () {
  console.log(this)
})
boxDiv.addEventListener('click', function () {
  console.log(this)
})

// 3.數(shù)組.forEach/map/filter/find
// 可以通過(guò)第二個(gè)參數(shù)綁定回調(diào)函數(shù)的`this`
var names = ['abc', 'cba', 'nba']
names.forEach(function (item) {
  console.log(item, this)
}, 'abc')
names.map(function (item) {
  console.log(item, this)
}, 'cba')

6.規(guī)則優(yōu)先級(jí)

1.默認(rèn)規(guī)則的優(yōu)先級(jí)最低

2.顯示綁定優(yōu)先級(jí)高于隱式綁定

function foo() {
  console.log(this)
}

var obj = {
  name: 'obj',
  foo: foo.bind('aaa')
}

// [String: 'aaa']
obj.foo()

3.new 綁定優(yōu)先級(jí)高于隱式綁定

var obj = {
  name: 'obj',
  foo: function () {
    console.log(this)
  }
}

// new的優(yōu)先級(jí)高于隱式綁定
// foo {}
var f = new obj.foo()

4.new 綁定優(yōu)先級(jí)高于 bind

  • new 綁定和 call、apply 是不允許同時(shí)使用的,所以不存在誰(shuí)的優(yōu)先級(jí)更高
  • new 綁定可以和 bind 一起使用,new 綁定優(yōu)先級(jí)更高
function foo() {
  console.log(this)
}
var bar = foo.bind('aaa')
// foo {} 不是 [String: 'aaa']
var obj = new bar()

7.規(guī)則之外

1.null 或者 undefined

// 非嚴(yán)格模式下
// apply/call/bind: 當(dāng)傳入null/undefined時(shí), 自動(dòng)將this綁定成全局對(duì)象
foo.apply(null)
foo.apply(undefined)

var bar = foo.bind(null)
bar()

// 嚴(yán)格模式下,就是 `null/undefined`

2.間接函數(shù)引用

var obj1 = {
  name: 'obj1',
  foo: function () {
    console.log(this)
  }
}

var obj2 = {
  name: 'obj2'
}

// 這里是取出了obj1.foo函數(shù),賦值給了obj2.bar
// = 運(yùn)算法的返回值,就是右側(cè)的值, ob1.foo 的函數(shù)定義
// 相當(dāng)于取出函數(shù),然后獨(dú)立調(diào)用, 所以指向 window
;(obj2.bar = obj1.foo)()

3.箭頭函數(shù),箭頭函數(shù)是無(wú)法使用 bind/call/apply 綁定 this 的,箭頭函數(shù)的 this 是定義的時(shí)候所處的上下文環(huán)境,無(wú)法變更,屬于靜態(tài) this, 而不是動(dòng)態(tài)綁定的

8.實(shí)踐

var name = 'window'

var person = {
  name: 'person',
  sayName: function () {
    console.log(this.name)
  }
}

function sayName() {
  var sss = person.sayName
  sss() // window: 獨(dú)立函數(shù)調(diào)用
  person.sayName() // person: 隱式調(diào)用
  person.sayName() // person: 隱式調(diào)用
  ;(b = person.sayName)() // window: 賦值表達(dá)式(獨(dú)立函數(shù)調(diào)用), 使用 = 號(hào)運(yùn)算符之后,返回了 person.sayName 這個(gè)函數(shù)方法,后續(xù)調(diào)用,跟 person 無(wú)關(guān)
}
sayName()
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(隱式綁定)
// person1.foo1.call(person2); // person2(顯示綁定優(yōu)先級(jí)大于隱式綁定)

// person1.foo2(); // window(不綁定作用域,上層作用域是全局)
// person1.foo2.call(person2); // window

// person1.foo3()(); // window(獨(dú)立函數(shù)調(diào)用)
// person1.foo3.call(person2)(); // window(獨(dú)立函數(shù)調(diào)用)
// person1.foo3().call(person2); // person2(最終調(diào)用返回函數(shù)式, 使用的是顯示綁定)

// person1.foo4()(); // person1(箭頭函數(shù)不綁定this, 上層作用域this是person1)
// person1.foo4.call(person2)(); // person2(上層作用域被顯示的綁定了一個(gè)person2)
// person1.foo4().call(person2); // person1(上層找到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
person1.foo1.call(person2) // person2(顯示高于隱式綁定)

person1.foo2() // person1 (上層作用域中的this是person1)
person1.foo2.call(person2) // person1 (上層作用域中的this是person1)

person1.foo3()() // window(獨(dú)立函數(shù)調(diào)用)
person1.foo3.call(person2)() // window
person1.foo3().call(person2) // person2

person1.foo4()() // person1
person1.foo4.call(person2)() // person2
person1.foo4().call(person2) // person1
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()() // window
person1.obj.foo1.call(person2)() // window
person1.obj.foo1().call(person2) // person2

person1.obj.foo2()() // obj
person1.obj.foo2.call(person2)() // person2
person1.obj.foo2().call(person2) // obj

到此這篇關(guān)于JavaScript中 this 的綁定規(guī)則的文章就介紹到這了,更多相關(guān)JS this 綁定規(guī)則內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論