この方向性を理解してください

1. このバインディングを理解する

  1. 関数が呼び出されると、JavaScript はデフォルトで this を関数にバインドします。
  2. this のバインディングは、それが定義されている場所 (どこに書かれているか) とは何の関係もありません。
  3. このバインディングは、呼び出しメソッドと呼び出しの場所に関連します。
  4. これは実行時にバインドされます
  5. 優先順位: 新しい > バインド > 適用/呼び出し > 暗黙的なバインディング > デフォルトのバインディング

2. 本規約の拘束力のある規則

  1. デフォルトのバインディング
// 具名函数调用
fucniton foo(){
    
    
  console.log('foo',this)  
}
foo() // this指向window
// 匿名函数调用
// const foo = function(){
    
    
//   console.log('foo', this)
// }
// foo() // this指向window
  1. 暗黙的なバインディング
// 隐式绑定
const info = {
    
    
    name: '张三',
    age: 24,
    sayName() {
    
    
        console.log('this指向', this)
    }
}
info.sayName() // this指向 {name: '张三', age: 24, sayName: ƒ}
  1. バインディングを表示
function foo(name,age) {
    
    
    console.log('参数', name, age)
    console.log('foo被调用时this的指向', this)
}
// apply
// 第一个参数:绑定this
// 第二个参数:已数组形式的实参

// foo.apply('apply', ['张三', 24])
// 参数 张三 24
// this的指向.js:20 foo被调用时this的指向 String {'apply'}

// call
// 第一个参数:绑定this
// 第二个参数:以逗号隔开的参数序列

// foo.call('call', '张三', 24)
// 参数 张三 24
// foo被调用时this的指向 String {'call'}

// bind
// 第一个参数:绑定this
// 第二个参数:以逗号隔开的参数序列
// const changethis = foo.bind('bind', '张佳佳', 24)
// changethis()
// 参数 张佳佳 24
// foo被调用时this的指向 String {'bind'}

// 显示绑定的特殊情况 当apply、call、bind第一个参数为null或者undefined时,this指向window
function foo() {
    
    
    console.log('this', this)
}
// const bindFoo = foo.bind(null)
// bindFoo() // this Window {window: Window, self: Window, document: document, name: '', location: Location, …}
// const bindFoo = foo.bind(undefined)
// bindFoo() // this Window {window: Window, self: Window, document: document, name: '', location: Location, …}

foo.apply(null) // this Window {window: Window, self: Window, document: document, name: '', location: Location, …}
foo.apply(undefined) // this Window {window: Window, self: Window, document: document, name: '', location: Location, …}

foo.call(null) // this Window {window: Window, self: Window, document: document, name: '', location: Location, …}
foo.call(undefined) // this Window {window: Window, self: Window, document: document, name: '', location: Location, …}
  1. 組み込み関数このバインディング
setTimeout(() => {
    
    
    console.log('settimeout', this) // this指向window
}, 1000);

const btn = document.querySelector("#btn")
btn.onclick = function() {
    
    
    console.log('onclick', this) // this指向btn元素
}

btn.addEventListener('click', function() {
    
    
    console.log('addEventListener', this) // this指向btn元素
})
['abc', 'cba'].forEach(element => {
    
    
    console.log('forEach', this) // this指向window
});

5. これを新しいバインドします

function Foo () {
    
    
    this.name = 'zjj'
    this.age = 24
    console.log(this) // Foo {name: 'zjj', age: 24}
}
const foo = new Foo()
console.log(foo) // Foo {name: 'zjj', age: 24}

3、この拘束力のある優先順位

1. デフォルトのバインディングの優先順位が最も低くなります。
2. 明示的なバインディングは暗黙的なバインディングよりも高くなります。

function foo() {
    
    
    console.log('this指向', this)
}
const info = {
    
    
    name: '张三',
    age: 24,
    foo
}
const obj = {
    
     name: '显示绑定' }
info.foo.apply(obj) // this指向 {name: 'apply显示绑定'}
info.foo.call(obj) // this指向 {name: 'call显示绑定'}
const newFun = info.foo.bind(obj)
newFun() // this指向 {name: 'bind显示绑定'}


3. 新しいバインディングは暗黙的なバインディングよりも上位です

  • 新しいオペレーターは何をするのですか?
  • メモリ内に新しいオブジェクトを作成します。
  • この新しいオブジェクトの内部 [[Prototype]] プロパティは、コンストラクターのプロトタイプ プロパティに割り当てられます。
  • コンストラクター内の this には新しいオブジェクトが割り当てられます (つまり、this は新しいオブジェクトを指します)。
  • コンストラクター内のコードを実行します (新しいオブジェクトにプロパティを追加します)。
  • コンストラクターが null 以外のオブジェクトを返す場合は、そのオブジェクトが返され、それ以外の場合は、作成されたばかりの新しいオブジェクトが返されます。

4. 新しいバインディングはバインド表示バインディングよりも上位です

  • 新しいバインディングは apply と call では使用できないため、どちらの優先順位が高いかは問題ありません。
  • 新しいバインディングはバインドの明示的なバインディングよりも上位です
function foo() {
    
    
    console.log('this指向', this)
}
const obj = {
    
    
    name: '张三'
}
const bindFun = foo.bind(obj)
bindFun() // this指向 {name: '张三'}
new bindFun() // this指向 foo {}

5.bind のバインディング優先度は apply や call よりも高くなります。

// bind和apply/call的优先级
function foo() {
    
    
    console.log('this', this)
}
const obj = {
    
     name: '张三' }
const bindFoo = foo.bind(obj)
bindFoo() //this {name: '张三'}
bindFoo.apply('apply') // this {name: '张三'}
bindFoo.call('call') // this {name: '张三'}

Guess you like

Origin blog.csdn.net/Z_J_CSDN/article/details/125610433