javascript
javascript this指针指向?
前言
理解javascript的指針就需要先了解js的執(zhí)行環(huán)境和作用域!執(zhí)行環(huán)境的定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了它們各自的行為。每個執(zhí)行環(huán)境都有一個與之關(guān)聯(lián)的變量對象,環(huán)境中定義的所有的變量和函數(shù)都保存在這個對象中。雖然我們編寫的代碼無法訪問這個對象,但解析器在處理數(shù)據(jù)時(shí)會在后臺使用它。
1、全局執(zhí)行環(huán)境
全局執(zhí)行環(huán)境是最外圍的一個執(zhí)行環(huán)境,根據(jù)js實(shí)現(xiàn)的宿主環(huán)境的不同,表示執(zhí)行環(huán)境的對象也不一樣。在web瀏覽器中認(rèn)為window就是全局執(zhí)行的對象。因此所有的全局變量和函數(shù)都是作為window對象進(jìn)行創(chuàng)建的。某個執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后,該環(huán)境被銷毀,保存在其中的所有的變量和函數(shù)定義也會被銷毀。每個函數(shù)都有自己的執(zhí)行環(huán)境,當(dāng)執(zhí)行流進(jìn)入一個函數(shù)的時(shí)候,函數(shù)的環(huán)境就會被推入一個環(huán)境棧中。而在函數(shù)執(zhí)行之后,棧將其環(huán)境彈出。
2、作用域鏈
當(dāng)代碼在一個環(huán)境中執(zhí)行時(shí)候,會創(chuàng)建變量的一個作用域鏈(scope chain)。作用域鏈的用途,是保證對執(zhí)行環(huán)境有權(quán)訪問的所有的變量和函數(shù)的有序訪問。作用域鏈的前端,始終都是當(dāng)前執(zhí)行的代碼所在的環(huán)境的變量對象,如果這個環(huán)境是函數(shù),則將其活動對象作為變量對象?;顒訉ο笤谧铋_始的時(shí)候只包含一個變量,arguments對象。作用域鏈的下一個對象來自包含(外部)環(huán)境,而再下一個對象則來自下一個包含對象,這樣一直延續(xù)到全局。
JavaScript由于其在運(yùn)行期進(jìn)行綁定的特性,JavaScript 中的 this 可以是全局對象、當(dāng)前對象或者任意對象,這完全取決于函數(shù)的調(diào)用方式。JavaScript 中函數(shù)的調(diào)用有以下幾種方式:作為對象方法調(diào)用,作為函數(shù)調(diào)用,作為構(gòu)造函數(shù)調(diào)用,和使用 apply 或 call 調(diào)用。
看下面第一個例子
var point = {?
? ? ? x : 0,?
? ? ? y : 0,?
? ? ?moveTo : function(x, y) {?
? ? ? ? ? ? ? ? ? ? ?console.log(this);//1
? ? ? ? ? ? ? ? ? ? ?this.x = this.x + x;?
? ? ? ? ? ? ? ? ? ? ?this.y = this.y + y;?
? ? ? ? ? ? ?}?
? ?};
point.moveTo(1,1); //this 綁定到當(dāng)前對象,即point對象
console.log(point);//2
第一個位置上的this我們打印的時(shí)候發(fā)現(xiàn)這里的this指向就是point 這個對象!
point.moveTo()這個方法執(zhí)行后就更改了對象point的屬性x和y
第二個例子
function func(x) {?
? ? ? ?this.x = x;
? ? ? console.log(this);
}?
func(2);
我們發(fā)現(xiàn)這個時(shí)候的this指向是window ?why?
這個很好理解,func(2) 可以寫成window.func(2);由于任何函數(shù)或者全局的屬性都是window對象下面的,那么這里的this當(dāng)然就是window
第三個例子
var point = {?
? ? ? x : 0,?
? ? ? y : 0,?
? ? ? moveTo : function(x, y) {?
? ? ? ? ? ? ? ? ? ? ? // 內(nèi)部函數(shù)
? ? ? ? ? ? ? ? ? ? ?var moveX = function(x) {?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? console.log(this);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? this.x = x;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? };?
? ? ? ? ? ? ? ? ? ? ?// 內(nèi)部函數(shù)
? ? ? ? ? ? ? ? ? ? ?var moveY = function(y) {?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? this.y = y;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?console.log(this);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? };?
? ? ? ? ? ? ? ? ? ? moveX(x);?
? ? ? ? ? ? ? ? ? ? console.log(moveX() in point);//false
? ? ? ? ? ? ? ? ? ? console.log(moveX() in window);//true
? ? ? ? ? ? ? ? ? ? moveY(y);?
? ? ? ? ? }?
};?
point.moveTo(1,1);?
point.x; //=>0?
point.y; //=>0
上面的代碼我們分析下很好理解!執(zhí)行point.moveTo(1,1)里面有兩個方法,moveX和moveY,這兩個方法并沒有綁定到對象point上,我們知道所有的方法都是屬于window對象的,那么這里的moveX和moveY實(shí)際上是window上調(diào)用的,并不是屬于point對象!
第四個例子
function Point(x,y){?
? ? ? ? ? console.log(this);//第一次是通過new創(chuàng)建的,返回的是Point{} 它是一個對象,不是單純的方法了
? ? ? ? ? this.x = x; // this ?
? ? ? ? ?this.y = y; // this ?
}
var np=new Point(1,1);//所以這里可以理解成這樣
/*
? ? ? ? ? ?var np = {
? ? ? ? ? ? ? ? ? ? ? x = 1,
? ? ? ? ? ? ? ? ? ? ? y =1
? ? ? ? ? ? ? ?};
*/
np.x;//1
var p=Point(2,2);//這個時(shí)候不是通過new創(chuàng)建,就相當(dāng)于window.Point(2,2),它就綁定到window上了!所以this指向window
console.log(p);//由于函數(shù)Point沒有返回值,所以這里的p = undefined
p.x;//error, p是一個空對象undefined
總結(jié):
| 普通函數(shù) | 全局對象window |
| 對象的方法 | 該對象 |
| 構(gòu)造函數(shù) | 新構(gòu)造的對象 |
文章參考地址:
http://www.cnblogs.com/isaboy/?
http://www.cnblogs.com/isaboy/archive/2015/10/29/javascript_this.html
轉(zhuǎn)載于:https://www.cnblogs.com/shizhouyu/p/4952615.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的javascript this指针指向?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《独行月球》总票房破20亿!位居内地票房
- 下一篇: 你遇到了吗?三大运营商擅自给用户开通视频