摘要:函數的幾種調用方式普通函數調用作為方法來調用作為構造函數來調用使用方法來調用方法箭頭函數但是不管函數是按哪種方法來調用的,都需要記住一點誰調用這個函數或方法關鍵字就指向誰。作為構造函數來調用構造函數出來的實例,指向這個實例對象。
首先,了解一下this關鍵字。this關鍵字就涉及到函數調用的內容。函數的幾種調用方式:
1 普通函數調用
2 作為方法來調用
3 作為構造函數來調用
4 使用apply/call方法來調用
5 Function.prototype.bind方法
6 ES6箭頭函數
但是不管函數是按哪種方法來調用的,都需要記住一點:誰調用這個函數或方法,this關鍵字就指向誰。
普通函數調用var age = 18; function person(){ this.name = "Tony"; console.log(this); //window console.log(this.name); //Tony console.log(this.age); //18 } person();
代碼中定義一個普通函數person,在調用時實際上person是作為全局對象window的一個方法來進行調用的,即window.person();
因此是window對象調用了person方法,那么person函數當中的this即指window,同時window還擁有了另外一個屬性name,值為“Tony”。
定義一個全局變量age,它相當于是window的一個屬性。在調用person函數時它的this指向window,所以在函數內部可以訪問到age變量,這也解釋了函數內部可訪問全局變量。
作為方法來調用var person = { name : "Tony", showName:function(){ console.log(this.name); } } person.showName(); var name = "Tom"; var showname = person.showName; showname();
定義一個對象person包含一個showName的方法,在對象person內調用方法返回的是Tony,顯然this指向了對象person。
再定義一個全局變量name,將person.showName方法賦值給變量showname,因為在全局定義的嘛,所以showname也相當于window的一個屬性,此時調用showname它的this是指向window的,所以返回的值就是全局變量“Tom”。
var personA = { name : "Tony", showName:function(){ console.log(this.name); } } var personB = { name : "Tom", sayName:personA.showName } personB.sayName(); //Tom
personB對象中的方法調用personA中的方法,雖然showName是personA中定義的,但調用了personB,那this就指向了personB。
作為構造函數來調用function Person(name){ this.name = name; } var personA = new Person("Tony"); console.log(personA.name);
構造函數new出來的實例,this指向這個實例對象。
下面就來了解一下this指向改變的三種方法。
在JavaScript中,call、apply和bind是Function對象自帶的三個方法,這三個方法的主要作用是改變函數中的this指向。所以可知它們的共同點就是都用來改變函數的this對象的指向的;還有就是三者第一個參數都是this要指向的對象,也就是想指定的上下文(函數的每次調用都會擁有一個特殊值——本次調用的上下文(context)——這就是this關鍵字的值。),然后再利用后續參數傳參。而它們的不同也就是傳參的不同,bind?是返回對應函數,便于稍后調用;apply?、call?則是立即調用 。
apply()方法?它接收兩個參數,一個是函數運行的作用域(this),另一個是參數數組。
語法:
apply([thisObj [,argArray] ]);
定義:應用某一對象的一個方法,用另一個對象替換當前對象
說明:如果argArray不是一個有效數組或不是arguments對象,那么將導致一個?TypeError,如果沒有提供argArray和thisObj任何一個參數,那么Global對象將用作thisObj。
function Person(name){ this.name = name; this.showName = function(){ console.log(this.name); } } function Student(name){ Person.apply(this,arguments); } var stu = new Student("Tony"); stu.showName();call()方法?
它第一個參數和apply()方法的一樣,但是傳遞給函數的參數必須列舉出來。
語法:
call([thisObject[,arg1 [,arg2 [,...,argn]]]]);
定義:調用一個對象的一個方法,以另一個對象替換當前對象。
說明:?call方法可以用來代替另一個對象調用一個方法,call方法可以將一個函數的對象上下文從初始的上下文改變為thisObj指定的新對象。
thisObj取值的情況:
1 不傳,或者傳null,undefined, 函數中的this指向window對象
2 傳遞另一個函數的函數名,函數中的this指向這個函數的引用
3 傳遞字符串、數值或布爾類型等基礎類型,函數中的this指向其對應的包裝對象,如 String、Number、Boolean
4 傳遞一個對象,函數中的this指向這個對象
call方法的一些常見例子:
1.
function add(a,b){ console.log(a+b); } function subtraction(a,b){ console.log(a-b); } add.call(subtraction,3,1); //4
定義一個加法函數、加法函數,最后的調用語句意思就是用加法替代了減法,在減法函數中通過call方法改變了this的指向,已經不再計算a-b,而是作用加法中的a+b。
2.
function Student(){ this.name = "Tom"; this.showName = function(){ console.log(this.name); } } function Teacher(){ this.name = "Tony"; } var stu = new Student(); var tea = new Teacher(); stu.showName.call(tea);
定義一個學生函數,它有屬性name和方法showName,而老師函數只有name屬性,最后一個調用語句的意思就是把學生的方法用到了老師函數中執行,即便老師是沒有這個方法的。
3.
function Parent(name){ this.name = name; this.showName = function(){ console.log(this.name); } } function Son(name){ Parent.call(this,name); } var baby = new Son("Tony"); baby.showName();
Parent.call(this,name)意思就是使用父母這個對象替代掉兒子函數中的this對象,那么這個兒子函數中就可以直接調用父母對象中的屬性和方法,這也就是繼承。
bind()方法bind()最簡單的用法是創建一個函數,使這個函數不論怎么調用都有同樣的this值。
var person = { name : "Tony", showName : function(){ console.log(this.name); } } person.showName(); //Tony var name = "Tom"; var getName = person.showName; getName(); //Tom var boundGetName = getName.bind(person); boundGetName(); //Tony
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/109664.html
摘要:面向對象編程對象的原生方法分成兩類自身的方法靜態方法和的實例方法。的靜態方法方法與,參數是對象,返回一個數組,數組的值是改對象自身的所有屬性名區別在于返回可枚舉的屬性,返回不可枚舉的屬性值。 面向對象編程 Objects對象的原生方法分成兩類:Object自身的方法(靜態方法)和Object的實例方法。注意Object是JavaScript的原生對象,所有的其他對象都是繼承自Objec...
在上一篇文章(《javascript高級程序設計》筆記:Function類型)中稍微提及了一下函數對象的屬性—this,在這篇文章中有深入的說明: 函數的三種簡單調用模式 1 函數模式 定義的函數,如果單獨調用,不將其與任何對象關聯,那么就是函數調用模式 function fn(num1, num2) { console.log(this); } // 直接在全局調用 fn();// w...
閱讀 1472·2021-09-30 09:57
閱讀 1481·2021-09-09 09:33
閱讀 2249·2021-09-04 16:40
閱讀 1812·2021-09-01 10:50
閱讀 3259·2021-09-01 10:31
閱讀 2552·2019-08-30 15:56
閱讀 2983·2019-08-30 15:44
閱讀 3486·2019-08-29 17:29