JavaScript高階程式設計 this

2021-09-16 22:24:24 字數 4747 閱讀 5985

在函式中this到底取何值,是在函式真正被呼叫執行的時候確定的,函式定義的時候確定不了

因為this的取值是執行上下文環境的一部分,每次呼叫函式,都會產生乙個新的執行上下文環境。

所謂建構函式就是用來new物件的函式。其實嚴格來說,所有的函式都可以new乙個物件,但是有些函式的定義是為了new乙個物件,而有些函式則不是。另外注意,建構函式的函式名第乙個字母大寫(規則約定)。例如:object、array、function等。

function foo() 

}var f1 = new foo();

console.log(f1.name); //yzh

console.log(f1.year); //1996

以上**中,如果函式作為建構函式用,那麼其中的this就代表它即將new出來的物件。

注意,以上僅限newfoo()的情況,即foo函式作為建構函式的情況。如果直接呼叫foo函式,而不是new foo(),情況就大不一樣了。

function foo() 

}foo(); //window

這種情況下this是window。

如果函式作為物件的乙個屬性時,並且作為物件的乙個屬性被呼叫時,函式中的this指向該物件。

var obj = 

console.log(this.x); //10}};

obj.fn();

以上**中,fn不僅作為乙個物件的乙個屬性,而且的確是作為物件的乙個屬性被呼叫。結果this就是obj物件。

如果fn函式不作為obj的乙個屬性被呼叫,會是什麼結果呢?

var obj = 

};var f1 = obj.fn;

f1();

如上**,如果fn函式被賦值到了另乙個變數中,並沒有作為obj的乙個屬性被呼叫,那麼this的值就是window,this.x為undefined。

為了防止看不懂這塊先理解下基礎並重要的東西

在函式內部,有兩個特殊的物件:arguments和this.

主要介紹下arguments,它是類陣列物件,包含傳入函式的所有引數,這個物件還有乙個叫callee的屬性,該屬性為乙個指標,指向擁有這個arguments物件的函式。

這個例子主要用於消除函式的執行與同名函式的緊密耦合現象。**如下:

function factorial(num)  else 

}var truefactorial = factorial;

factorial = function() ;

alert(truefactorial(5)); //120

alert(factorial(5)); //0

每個函式都包含兩個屬性:length和prototype.

length表示函式希望接受的命名引數的個數

function sayname(name)      

function sum(num1, num2)

function sayhi()

alert(sayname.length); //1

alert(sum.length); //2

alert(sayhi.length); //0

prototype屬性這裡不再重複介紹。

function sum(num1, num2)

function callsum1(num1, num2)

function callsum2(num1, num2)

alert(callsum1(10,10)); //20

alert(callsum2(10,10)); //20

callssum1()執行sum()函式時傳入this作為this值(在全域性作用域中呼叫,所以傳入的物件為window物件)下面的例子同理。

function sum(num1, num2)

function callsum(num1, num2)

alert(callsum(10,10)); //20

傳遞引數並非兩個函式的真正用武之地,真正強大的地方是擴充函式賴以執行的作用域

window.color = "red";

var o = ;

function saycolor()

saycolor(); //red

saycolor.call(this); //red

saycolor.call(window); //red

saycolor.call(o); //blue

如下**如果不用函式的方法來實現。

window.color = "red";

var o = ;

function saycolor()

saycolor(); //red

o.saycolor = saycolor;

o.saycolor(); //blue

如果要輸出o物件裡的color屬性值,必須把saycolor函式賦給物件o並呼叫 o.saycolor()時,this引用的物件為o

var obj = ;

var fn = function()

console.log(this.x); //10

};fn.call(obj);

在全域性環境下,this永遠是window,這個應該沒有非議。

console.log(this === window); //true
普通函式在呼叫時,其中的this也都是window。

var x = 10;

var fn = function()

fn();

注意以下的情況

var obj = 

f();}};

obj.fn();

函式f雖然是在obj.fn內部定義的,但是它仍然是乙個普通的函式,this仍然指向window。

總結:this指向呼叫該函式的物件

function fn() 

fn.prototype.getname = function()

var f1 = new fn();

f1.getname(); //yzh

在fn.prototype.getname函式中,this指向的是f1物件。因此可以通過this.name獲取f1.name的值

bind()方法建立乙個新的函式, 當被呼叫時,它的this關鍵字被設定為提供的值 ,在呼叫新函式時,提供任何乙個給定的引數序列。

這個函式其實也很重要,只是當時紅寶書也沒提及很多。

語法

fun.bind(thisarg[, arg1[, arg2[, ...]]])

引數
thisarg

當繫結函式被呼叫時,該引數會作為原函式執行時的 this 指向。當使用new 操作符呼叫繫結函式時,該引數無效。
arg1, arg2, ...

當繫結函式被呼叫時,這些引數將置於實參之前傳遞給被繫結的方法。
返回值
返回由指定的this值和初始化引數改造的原函式拷貝

描述

bind() 函式會建立乙個新函式(稱為繫結函式),新函式與被調函式(繫結函式的目標函式)具有相同的函式體(在 ecmascript 5 規範中內建的call屬性)。當目標函式被呼叫時 this 值繫結到 bind() 的第乙個引數,該引數不能被重寫。繫結函式被呼叫時,bind() 也接受預設的引數提供給原函式。乙個繫結函式也能使用new操作符建立物件:這種行為就像把原函式當成構造器。提供的 this 值被忽略,同時呼叫時的引數被提供給模擬函式。

示例建立繫結函式

this.x = 9; 

var module =

};module.getx(); // 返回 81

var retrievex = module.getx;

retrievex(); // 返回 9, 在這種情況下,"this"指向全域性作用域

// 建立乙個新函式,將"this"繫結到module物件

// 新手可能會被全域性的x變數和module裡的屬性x所迷惑

var boundgetx = retrievex.bind(module);

boundgetx(); // 返回 81

JavaScript高階程式設計

ecmascript有5種基本型別資料 另外還有一種複雜的資料型別 typeof就是用來檢測變數的資料型別的,typeof可能會返回以下值 typeof操作符在檢測引用型別的值時,總是會返回object,所以用處不大。instanceof用來檢測物件型別的,返回值是 true false。例如 pe...

javascript 高階程式設計 二

這裡我們直接進入主題 在js剛剛開始的時候,必須面臨乙個問題,那就是如何使的js的載入和執行不會影響web核心語言html的展示效果,和html和諧共存。在這個背景下 2 xhtml中的應用 在html中如果字串,那麼html就會認為js指令碼已經結束所以會產生乙個錯誤用一下 來替換 來替換aler...

javascript 高階程式設計 四

新的一天開始,讓我們伴隨者輕快的心情,開始今天的筆記 1 操作符 1 在ecmascript中操作的時候,如果遇到有乙個操作值不是數值型 number 那麼就會在後台呼叫number 方法,將其轉化成number 2 和上面的三個操作符是不一樣的,只要其中乙個操作值不是number,那麼就會在後台呼...