js中的this

// 默認綁定
// 在沒有其他規(guī)則使用時的默認綁定
// function foo(){
//  console.log(this.a);
// }
// var a = 2;
// foo();

// 隱含綁定
// 調(diào)用點是否為一個環(huán)境對象,也叫作擁有者或者容器
// function foo(){
//  console.log( this.a );
// };
// var obj = {
//  a: 2,
//  b: 3,
//  fooo: foo,
// };
// obj.fooo();
// foo()被聲明后作為引用屬性添加到obj上,被obj擁有或者包含,所以this指代的是obj


// 隱含的丟失
// 隱含綁定丟失了他的綁定,這就意味著它要退回到默認綁定
// function foo() {
//  console.log(this.a);
// };
// var obj = {
//  a: 2,
//  fooo: foo,
// };
// var bar = obj.fooo;
// var a = 3;
// bar();

// 接下來我們考慮一下傳遞一個回調(diào)函數(shù)
// function foo(){
//  console.log(this.a);
// };
// function doFoo(fn){
//  fn();
// };
// var obj = {
//  a: 2,
//  fooo: foo,
// };
// var a = 3;

// doFoo(obj.fooo);

// 明確綁定
// 隱含綁定: 我們不得不改變目標對象使它自身包含一個對函數(shù)的引用,而后使用這個函數(shù)引用屬性來間接的,將this綁定到這個對象上。
// 明確綁定: 我們強制一個函數(shù)調(diào)用使用某個特定的對象作為this綁定

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

// 當然我們也可以傳遞原始的類型值(string boolean number),這個類型值會被包裝在他的對象類型中,new String() new Number()...

// function sum(){
//  // console.log(this+2);  chai boxing
//  console.log(this); //boxing
// };
// sum.call(5);


// 硬綁定
// 有時候,單獨依靠明確綁定仍然不能為我們先前提到的問題提供解決方案,也就是函數(shù)丟失原本的this綁定,或者被第三方框架覆蓋,等問題。

// function foo(){
//  console.log(this.a);
// };
// var obj = {
//  a: 2,
// };
// var bar = function(){
//  foo.call( obj );
// };
// var a = 3;
// bar();
// bar.call(window);//不會被覆蓋


// 用硬綁定將一個函數(shù)包裝起來的最典型的方法,是為所有傳入的參數(shù)和傳出的返回值創(chuàng)建一個通道

// function foo(something){
//  console.log(this.a , something);
//  return this.a + something;
// };
// var obj = {
//  a: 2,
// };
// var bar = function(){
//  return foo.apply( obj,arguments );
// };
// var b = bar( 3 );
// console.log( b );

// 由于硬綁定是一個非常常用的模式,它已作為ES5中的內(nèi)建工具提供:
// Function.prototype.bind

// 如下使用
// function foo(something){
//  console.log(this.a,something);
//  return this.a + something;
// };
// var obj = {
//  a: 2,
// };
// var bar = foo.bind(obj);
// var b = bar( 3 );
// console.log( b );

// new 綁定  
// js中構(gòu)造器的定義:構(gòu)造器僅僅是一個函數(shù),它們偶然的被前置的new操作符調(diào)用,它們不依附于類,它們也不初始化類,它們本質(zhì)上只是一般的函數(shù),在被使用new來調(diào)用時改變了行為。

// 當在函數(shù)前面被加入new調(diào)用時,也就是構(gòu)造器調(diào)用時,下面這些事情會自動完成
// 1.一個全新的對象會憑空創(chuàng)建 
// 2.這個新構(gòu)建的對象會被接入原型鏈(prototype-linked)
// 3.這個新構(gòu)建的對象被設(shè)置為函數(shù)調(diào)用的this綁定
// 4.除非函數(shù)返回一個它自己的其他對象,這個被new調(diào)用的函數(shù)將自動返回這個新構(gòu)建的對象。


// 綁定的順序
// 函數(shù)中的this綁定規(guī)則的優(yōu)先級

// function foo() {
//     console.log( this.a );
// }

// var obj1 = {
//     a: 2,
//     foo: foo
// };

// var obj2 = {
//     a: 3,
//     foo: foo
// };

// obj1.foo(); // 2
// obj2.foo(); // 3

// obj1.foo.call( obj2 ); // 3
// obj2.foo.call( obj1 ); // 2

// =====得出結(jié)論===>明確綁定 的優(yōu)先權(quán)要高于 隱含綁定

// function foo(something) {
//     this.a = something;
// }

// var obj1 = {
//     foo: foo
// };

// var obj2 = {};

// obj1.foo( 2 );
// console.log( obj1.a ); // 2

// obj1.foo.call( obj2, 3 );
// console.log( obj2.a ); // 3

// var bar = new obj1.foo( 4 );
// console.log( obj1.a ); // 2
// console.log( bar.a ); // 4

// =====得出結(jié)論===>new綁定 的優(yōu)先級要高于 隱含綁定


// 總結(jié)this
// 現(xiàn)在,我們可以按照優(yōu)先順序來總結(jié)一下this的規(guī)則。

// 1.new 綁定
// 2.硬綁定
// 3.明確綁定
// 4.隱含綁定
// 5.默認綁定

// 以上,就是理解對于普通的函數(shù)調(diào)用來說的this綁定規(guī)則所需的全部。

// 當然還有一些特殊的特例

// 如果你傳遞null或undefined作為call,apply或bind的this綁定參數(shù),那么這些值會被忽略掉,取而代之的是 默認綁定 規(guī)則將適用于這個調(diào)用。

// function foo() {

//     console.log( this.a );
//     console.log( this );
// }
// var a = 2;
// foo.call( null ); 


// 擴展
// 詞法this   簡單來說就是用一個變量保存this
// 我們剛剛涵蓋了一般函數(shù)遵守的4種規(guī)則。但是ES6引入了一種不適用于這些規(guī)則特殊的函數(shù):箭頭函數(shù)(arrow-function)。

// 最后,復習一下
// 為執(zhí)行中的函數(shù)判定this綁定需要找到這個函數(shù)的直接調(diào)用點。找到之后,4種規(guī)則將會以 這個 優(yōu)先順序施用于調(diào)用點:

/*
    1、被new調(diào)用?使用新構(gòu)建的對象。
    2、被call或apply(或 bind)調(diào)用?使用指定的對象。
    3、被持有調(diào)用的環(huán)境對象調(diào)用?使用那個環(huán)境對象。
    4、默認:strict mode下是undefined,否則就是全局對象。
*/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容