不安分的this 前言:關於javascript中的this,上網一搜一大片的文章。驚! 而我個人認為要想分清this,就有必要先搞清楚“對象”。 目錄: 一.函數對象的認識 二.this 一.函數對象的認識 post出概念: 每逢過節,親戚朋友都會問,小羅你的對象呢? 這裡所指的對象:是指小羅我感 ...
不安分的this
前言:關於javascript中的this,上網一搜一大片的文章。驚!
而我個人認為要想分清this,就有必要先搞清楚“對象”。
目錄:
一.函數對象的認識
二.this
一.函數對象的認識
post出概念:
每逢過節,親戚朋友都會問,小羅你的對象呢?
這裡所指的對象:是指小羅我感覺合適的某個異性。是指實體:實例。
1:小羅感覺合適(對應電腦語言就是:方法)對人友善
2:異性(屬性)女人
那麼回答親戚就說:黃某某
我想表達的是,對象是指某一類人,當使用的時候是明確的某個人。
函數
插入內容,如下引用:
函數對象與其他用戶所定義的對象有著本質的區別,這一類對象被稱之為內部對象,
例如日期對象(Date)、數組對象(Array)、字元串對象 (String)都屬於內部對象。
這些內置對象的構造器是由JavaScript本身所定義的:通過執行new Array()這樣的語句返回一個對象,JavaScript內部有一套機制來初始化返回的對象,而不是由用戶來指定對象的構造方式。
在JavaScript中,函數對象對應的類型是Function,正如數組對象對應的類型是Array,日期對象對應的類型是Date一樣,可以通過 new Function()來創建一個函數對象,也可以通過function關鍵字來創建一個對象。
下麵兩行代碼都是創建一個數組對象myArray: var myArray=[]; //等價於 var myArray=new Array(); 同樣,下麵的兩段代碼也都是創建一個函數myFunction: function myFunction(a,b){ return a+b; } //等價於 var myFunction=new Function("a","b","return a+b");
出自:雨中無傘V-藍色“認識js中的function和this”
就是說:
看到用function關鍵字創建的,和用new Function()創建的內容稱為函數對象(function)
而this就是指向函數對象。
二.this
判斷this所指的具體對象方法:
step1:找到函數真正被調用執行的位置(運行時的位置)
step2:查看有沒有閉包或者直接調用再或者call與apply
step3: this: 當前方法屬於誰,this就是誰!
關鍵字詞:this關鍵字總是返回某個具體對象。再說的詳細一些,就是屬性或方法“當前”所在的某個對象。(重點一)
(1)身處全局變數中
案例:
var name="全局"; function getName(){ var name="局部"; return this.name; }; alert(getName());//全局
step1:找到函數真正被調用執行的位置(運行時的位置)
既是:
alert(getName());
step2:查看有沒有閉包或者直接調用再或者call與apply
沒有這些內容,不會跳了出來。
step3: this: 當前方法屬於誰,this就是誰!
這裡只是聲明瞭那一類,而沒有指出是哪一個人。那麼就會預設指向window
則getName返回的this.name其實是window.name,因此alert出來的是“全局”!
(2)身處局部變數中
在解說之前,要插入一些內容
構造函數:
var obj = new Object();
如上,稱new 調用的函數為構造函數,構造函數和普通函數區別僅僅在於是否使用了new
來調用,它們的返回值也會不同
所謂“構造函數”,就是專門用來生成“對象”的函數。
特點:1可以生成多個對象
2可以通過.
來為對象添加屬性和方法
obj.name = 'Byron'; obj.printName = function(){ console.log(obj.name); };
可以等價於
var obj = { name: 'Byron', printNmae: function(){ console.log(obj.name); } }
自動化就要使用函數嵌套了
function createObj(name, age){ var obj = { name: name, age: age, printName: function(){ console.log(this.name); } }; return obj; } var obj3 = createObj('Byron', 30); obj3.printName();
but:構造出來的對象類型都是Object,沒有識別度
可以改造為
function Person(nick, age){ this.nick = nick; this.age = age; this.sayName = function(){ console.log(this.nick); } } var p1 = new Person();
參考文章:謙行的“JavaScript面向對象”
有瞭如上的基礎,就可以看下方的例子了。
案例:
var name="全局"; var twobin={ name:"局部", getName:function(){ return this.name; } }; alert(twobin.getName());
step1:找到函數真正被調用執行的位置(運行時的位置)
既是:
alert(twobin.getName());
step2:查看有沒有閉包或者直接調用再或者call與apply
沒有這些內容,不會跳了出來。
step3: this: 當前方法屬於誰,this就是誰!
這裡指出是哪一個人twobin。那麼就會預設指向window
則getName返回的this.name其實是twobin.name,因此alert出來的是“局部”!
(3)身處閉包中
var name="全局"; var twobin={ name:"局部", getName:function(){ return function(){ return this.name; }; } }; alert(twobin.getName()());
step1:找到函數真正被調用執行的位置(運行時的位置)
既是:
alert(twobin.getName()());
step2:查看有沒有閉包或者直接調用再或者call與apply
有,所以不能根據第一步,而是
匿名函數的運行時位置來判斷。
function (){
return this.name;
};來確認位置
step3: this: 當前方法屬於誰,this就是誰!
匿名函數所在的對象是window
匿名函數返回的this.name其實是window.name,因此alert出來的就是“全局”!
那麼,如何在閉包中使得this身處在twobin中呢?
var name="全局"; var twobin={ name:"局部", getName:function(){ var that=this; return function(){ return that.name; }; } }; alert(twobin.getName()());
step1:找到函數真正被調用執行的位置(運行時的位置)
既是:
alert(twobin.getName());
step2:查看有沒有閉包或者直接調用再或者call與apply
有,但是this不再匿名函數中
step3: this: 當前方法屬於誰,this就是誰!
這裡指出是哪一個人twobin。那麼就會預設指向window
則getName返回的this.name其實是twobin.name,因此alert出來的是“局部”!
(4)call與apply中的this
在JavaScript中能管的住this的估計也就非call與apply莫屬了。
call與apply就像this的父母一般,讓this住哪它就得住哪,不得不聽話!
var name="全局"; var twobin={ name:"局部", }; function getName(){ alert(this.name); } getName(twobin); getName.call(twobin);
step1:找到函數真正被調用執行的位置(運行時的位置)
既是:
getName(twobin);
step2:查看有沒有閉包或者直接調用再或者call與apply
沒有這些內容,不會跳了出來。
step3: this: 當前方法屬於誰,this就是誰!
這裡只是聲明瞭那一類,而沒有指出是哪一個人。那麼就會預設指向window
則getName返回的this.name其實是window.name,因此alert出來的是“全局”!
而
getName.call(twobin);
其中,call指定this的安身之處就是在twobin對象,因為this被迫只能在twobin那安家,則此時this指向twobin對象, this.name其實是twobin.name,因此alert出來的是“局部”!
這些是我本人話了一個下午的時間總結出來的,應該有些不足。我相信在日後的工作上會慢慢的提煉出更為準確的知識。