javascript
js自动触发onclick_每日一题JS中最基本的this情况分析
「~this情況分析?~」
每日一題,希望讓愛學習、思考的前端技術伙伴在一起學習、復盤、成長。?基礎知識要夯實,原理源碼要深入,深度廣度要擴展,堅持每天進步一點點,每天有所收獲。進大廠是最終目標 ?
* 回答面試題的套路
1、先說這個點的明確定義,或者是特性;
2、再說具體的應用場景;
3、說說自己的看法、觀點;
4、可以稍微舉一反三,說說同類特性,或者類似的框架,更好的方案。
項目中this情況使用場景
1)事件綁定;
2)函數執行:1)自執行函數? 2)回調函數;
3)構造函數執行;
4)基于call /apply /bind 改變函數中的this;
5)箭頭函數中沒有自己的this,所用到的this是使用其上下文中的;
JS中最基本的this情況分析
this函數的執行主體?
1)函數執行主體:誰把函數執行的;
2)函數執行上下文:在哪執行的;
//?全局上下文中的this是window;//?塊級上下文中沒有自己的this,所用到的this都是所處上級上下文中的this;console.log(this);?//window
{
????let?n?=?12;
????console.log(this);?//window??上級上下文是全局上下文
}
規律:
1)事件綁定:給當前元素的某個事件行為綁定方法,當事件觸發、方法執行,方法中的this是當前元素本身;
2)普通函數執行
1. 函數執行前面是否有“點”,沒有“點”,this就是window(或者JS嚴格模式下是undefined);
2. 有“點”,“點”前面是誰this就是誰;
3.匿名函數(自執行函數/回調函數)如果沒有經過特殊的處理,則this一般都是window/undefined,但是如果經過一些特殊處理,一切都以處理后的結果為主;
1、事件綁定
document.body.onclick?=?function?()?{????console.log(this);?//body
};
document.body.addEventListener('click',?function?()?{
????console.log(this);?//body
});
//?IE6~8?DOM2事件綁定
document.body.attachEvent('onclick',?function?()?{
????console.log(this);?//window
});?
2、普通函數執行
function?sum?()?{??console.log(this);?//?結果:undefined
}
說明:創建函數,沒有執行。this不知道是誰。
1)有“點”,“點”前面是誰this就是誰
//?開啟JS嚴格模式??=>?擴展:嚴格模式和非嚴格模式的區別//?"use?strict";function?fn()?{
????console.log(this);
}
let?obj?=?{
????name:?'前端學苑',
????fn:?fn
};
fn();?//this->window/undefined
obj.fn();?//this->obj?
2)匿名函數
(function?()?{????console.log(this);?//this->window/undefined
})();
說明:開啟嚴格模式是undefined
function?fn(callback)?{????callback();?//this->window/undefined
}
let?obj?=?{
????//?sum:function(){}
????sum()?{
????????console.log(this); // window
????}
};
//?obj.sum();?//this->obj//?回調函數:把一個函數作為實參值,傳遞給另外一個函數//?=>?fn(function?()?{});
fn(obj.sum);?setTimeout(function?()?{
????console.log(this);?//window或者undefined
},?1000);let?obj?=?{
????name:?'xxx'
};
let?arr?=?[10,?20];
arr.forEach(function?(item,?index)?{
????console.log(this);? // this -> obj
},?obj);
說明:obj 因為觸發回調函數執行的時候,forEach內部會把回調函數中的this改變為傳遞的第二個參數值obj “特殊處理”。
let?obj?=?{????sum()?{
????????console.log(this);
????}
};
obj.sum();?//this->obj
(obj.sum)();?//this->obj
(10,?obj.sum)();?//this->window?
說明:括號表達式,小括號中包含“多項”(如果只有一項,和不加括號沒啥本質區別),其結果是只取最后一項;但是這樣處理后,this會發生改變,變為window/undefined。
3、構造函數調用 ( 實例化后的對象 )
function?School(){???this.said=function(){
????console.log(this);
???}
??}
var?nanj=new?School();
nanj.said();//對象調用自己的方法,this===nanj,類似上面
4、基于call /apply /bind 改變函數中的this
window.name?=?'WINDOW';let?obj?=?{name:?'前端學苑',age:?2};function?fn(x,?y)?{console.log(this,?x?+?y);
}?
fn();?//this->window
obj.fn();?//Uncaught?TypeError:?obj.fn?is?not?a?functionfn.call(obj);?//this->obj??
fn.call(obj,?10,?20);?//this->obj?x->10?y->20
fn.call();?//this->window?嚴格模式下undefined
fn.call(null);?//this->window?嚴格模式下null?「傳遞的是undefiend也是如此」
fn.call(10,?20);?//this->10「對象」?x->20??y->undefined
解析說明:?fn.call(obj);
底層處理方式:fn先基于__proto__找到Function.prototype.call,把call方法執行的時候,call方法內部實現了一些功能:會把fn執行,并且讓fn中的this變為第一個實參值。
* apply的作用和細節上和call一樣,只有一個區別:傳遞給函數實參的方式不一樣。
fn.call(obj,?10,?20);fn.apply(obj,?[10,?20]);?
最后結果和call是一樣的,只不過apply方法執行的時候要求:傳遞給函數的實參信息都要放置在一個數組中,但是apply內部也會向call方法一樣,把這些實參信息一項項的傳遞給函數。
5、箭頭函數沒有自己的this
??實例一:
let?obj?=?{????name:?'前端學苑',
????age:?11,
????fn:?function?()?{
????????//?this->obj
????????let?that?=?this;
????????return?function?()?{
????????????//?this->window
????????????//?如果需要改變obj.name,可以用that替換this
????????????that.name?=?'FE2020';
????????????console.log(this);
????????};
????}
};
let?f?=?obj.fn();
f();
??實例二:
let?obj?=?{????name:?'前端學苑',
????age:?11,
????fn:?function?()?{
????????//?this->obj
????????return?()?=>?{
????????????this.name?=?'FE2020';
????????????console.log(this); // {name:'FE2020', age: 11, fn:f}
????????};
????}
};
let?f?=?obj.fn();
f.call(100);?
說明:
箭頭函數沒有this(方法執行的時候不存在初始this這一項操作),所以基于call/apply操作它都是無用的,沒有this。
* 可以在留言區寫下你的答案或理解,一起成長進大廠。
推薦熱門技術文章:
JS第一座大山:堆棧內存和閉包作用域?(想深入看這里)JS基礎進階- 堆棧內存和閉包作用域
JS基礎進階- 閉包作用域和JS高階編程技巧
覺得本文對你有幫助?請分享給更多人
關注「前端學苑」加星標,提升前端技能
如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~
總結
以上是生活随笔為你收集整理的js自动触发onclick_每日一题JS中最基本的this情况分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python怎么封装方法然后调用_Pyt
- 下一篇: jsp 使用base标签 没有作用_JS