「「You know nothing Jon Snow」web
「「你不知道的JavaScript學習筆記02」app
function foo() {
console.log(this.a) } var a = "fuck"; foo();//fuck 複製代碼
var obj1 = {
a:1, foo:function() { console.log(this.a); } } var obj2 = { b:2, bar:function() { consolelog(this.b); } } obj1.foo();//1 obj2.bar();//2 複製代碼
function foo() {
console.log(this.a); } var obj1 = { a:1, foo:foo } var obj2 = { a:2, obj1 } var obj3 = { a:3, obj2 } obj3.obj2.obj1.foo(); //1; 複製代碼
var obj1 = {
a:1, foo:function() { console.log(this.a); } } var a = "shit"; var bar = obj1.foo; bar(); //shit 複製代碼
在js中,函數屬於Object的之類,在這塊代碼塊中的RHS其實是傳遞函數的引用,而this是由調用宿主和執行上下文決定的,函數執行時執行的是默認綁定的規則編輯器
var obj1 = {
a:1 } function foo() { console.log(this.a); } var a = 2; foo.call(obj1); // 1 foo.apply(obj1); //1 var bar = foo.bind(obj1); bar(); //1 複製代碼
new關鍵字函數
avaScript中的「構造函數」有別於其餘語言,在JavaScript中,在函數調用前用new關鍵字進行聲明,該函數就成了「構造函數」,函數自己並沒有區別。 使用new來調用函數,或者說發生構造函數調用時,會自動執行下面的操做。1.建立(或者說構造)一個全新的對象。2.這個新對象會被執行[[Prototype]]鏈接。3.這個新對象會綁定到函數調用的this。4.若是函數沒有返回其餘對象,那麼new表達式中的函數調用會自動返回這個新對象。學習
//eg
function myNew() { // 第一個參數是構造函數 var Constructor = [].shift.call(arguments); // 建立一個繼承對象 var obj = Object.create(Constructor.prototype); // 執行構造函數,this執行obj var result = Constructor.apply(obj, arguments); // 構造函數返回是對象,優先使用返回的對象,不然是obj return result instanceof Object ? result : obj; // 執行構造函數,this執行obj var result = Constructor.apply(obj, arguments); // 構造函數返回是對象,優先使用返回的對象,不然是obj return result instanceof Object ? result : obj; } var a = 'fuck'; function foo(a) { this.a = a; this.saya = function() { console.log(this.a) } } var b = "shit"; var obj = myNew(foo,b); // new foo(b) obj.saya; //shit; 複製代碼
使用new來調用foo(..)時,咱們會構造一個新對象並把它綁定到foo(..)調用中的this上。new是最後一種能夠影響函數調用時this綁定行爲的方法,咱們稱之爲new綁定。ui
「new綁定 > 顯式綁定 >隱式綁定 >默認綁定this
能夠按照下面的順序來進行判斷:url
1.函數是否在new中調用(new綁定)?spa
若是是的話this綁定的是新建立的對象。prototype
var obj = new foo(); //綁定obj
複製代碼
2.函數是否經過call、apply(顯式綁定)或者硬綁定調用?
若是是的話,this綁定的是指定的對象。
var bar = new foo.call(obj); //綁定obj
複製代碼
3.函數是否在某個上下文對象中調用(隱式綁定)?
若是是的話,this綁定的是那個上下文對象。
var bar = obj.foo(); //綁定obj
複製代碼
4.若是都不是的話,使用默認綁定。若是在嚴格模式下,就綁定到undefined,不然綁定到全局對象。
箭頭函數並非使用function關鍵字定義的,而是使用被稱爲「胖箭頭」的操做符=>定義的。箭頭函數不使用this的四種標準規則,而是根據外層(函數或者全局)做用域來決定this。
function foo() {
return (a) => { console.log(this.a) } } var obj1 = { a:1 } var obj2 = { a:2 } var bar = foo.call(obj1); bar.call(obj2); //1,不是2 複製代碼
foo內部的箭頭函數會捕獲調用foo時的this;箭頭函數的this查詢規則聽從詞法;外層函數綁定的this會間接傳遞給內部的箭頭函數,箭頭函數的綁定沒法被修改。
function foo() {
var _this = this; setTimeout(function(){ console.log(_this.a) },100) } function bar() { setTimeout(()=>{ console.log(this.a) },100) } function baz() { setTimeout(function(){ console.log(this.a) },100) } var obj = { a: 1 } var a = 2; foo.call(obj); //1 bar.call(obj); //1 baz.call(obj); //2, 天惹,回調函數的this執行了默認綁定 複製代碼
「參考文獻: 《你不知道的JavaScript(上卷)》
本文使用 mdnice 排版