真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

JavaScript的self和this使用小結(jié)

一、self
這個非常簡單。我們知道,打開任何一個網(wǎng)頁,瀏覽器會首先創(chuàng)建一個窗口,這個窗口就是一個window對象,也是js運行所依附的全局環(huán)境對象和全局作用域?qū)ο蟆elf 指窗口本身,它返回的對象跟window對象是一模一樣的。也正因為如此,window對象的常用方法和函數(shù)都可以用self代替window。舉個例子,常見的寫法如“self.close();”,把它放在標記中:“關(guān)閉窗口”,單擊“關(guān)閉窗口”鏈接,當前頁面關(guān)閉。
二、this關(guān)鍵字
在講this之前,看下面的一段代碼:



本來的目的是想在body中添加一個span元素,對于這個span元素,制定了它的字體顏色,懸浮在它上面的鼠標樣式和單擊觸發(fā)事件。問題就出現(xiàn)在它的單擊事件上(彈出"單擊我:undefined")。也許有人會說你丫傻呀,寫這么多sb代碼還不就是為了實現(xiàn)下面這個東東嗎?
this的dom測試
1、this到底指什么?
我們熟悉的c#有this關(guān)鍵字,它的主要作用就是指代當前對象實例(參數(shù)傳遞和索引器都要用到this)。在javascript中,this通常指向的是我們正在執(zhí)行的函數(shù)本身,或者是指向該函數(shù)所屬的對象(運行時)。
2、常見使用方式
(1)、直接在dom元素中使用


分析:onclick事件直接調(diào)用thisTest函數(shù),程序就會彈出undefined。因為thisTest函數(shù)是在window對象中定義的,
所以thisTest的擁有者(作用域)是window,thisTest的this也是window。而window是沒有value屬性的,所以就報錯了。
b、正確的方式


分析:在前面的示例中,thisTest函數(shù)定義在全局作用域(這里就是window對象),所以this指代的是當前的window對象。而通過document.getElementById("btnTest").onclick=thisTest;這樣的形式,其實是將btnTest的onclick屬性設(shè)置為thisTest函數(shù)的一個副本,在btnTest的onclick屬性的函數(shù)作用域內(nèi),this歸btnTest所有,this也就指向了btnTest。其實如果有多個dom元素要注冊該事件,我們可以利用不同的dom元素id,用下面的方式實現(xiàn):
document.getElementById("domID").onclick=thisTest; //給button的onclick事件注冊一個函數(shù)。
因為多個不同的HTML元素雖然創(chuàng)建了不同的函數(shù)副本,但每個副本的擁有者都是相對應(yīng)的HTML元素,各自的this也都指向它們的擁有者,不會造成混亂。
為了驗證上述說法,我們改進一下代碼,讓button直接彈出它們對應(yīng)的觸發(fā)函數(shù):


其彈出的結(jié)果是:
//第一個按鈕
function onclick(){
thisTest()
}
//第二個按鈕
function thisTest(){
this.value="提交中";
}
從上面的結(jié)果你一定理解的更透徹了。
By the way,每新建一個函數(shù)的副本,程序就會為這個函數(shù)副本分配一定的內(nèi)存。而實際應(yīng)用中,大多數(shù)函數(shù)并不一定會被調(diào)用,于是這部分內(nèi)存就被白白浪費了。所以我們通常都這么寫:





這是因為我們使用了函數(shù)引用的方式,程序就只會給函數(shù)的本體分配內(nèi)存,而引用只分配指針。這樣寫一個函數(shù),調(diào)用的地方給它分配一個(指針)引用,這樣效率就高很多。當然,如果你覺得這樣注冊事件不能兼容多種瀏覽器,可以寫下面的注冊事件的通用腳本:
//js事件 添加 EventUtil.addEvent(dom元素,事件名稱,事件觸發(fā)的函數(shù)名) 移除EventUtil.removeEvent(dom元素,事件名稱,事件觸發(fā)的函數(shù)名)
var EventUtil = new eventManager();
//js事件通用管理器 dom元素 添加或者移除事件
function eventManager() {
//添加事件
//oDomElement:dom元素,如按鈕,文本,document等; **oEventType:事件名稱(如:click,如果是ie瀏覽器,自動將click轉(zhuǎn)換為onclick);**oFunc:事件觸發(fā)的函數(shù)名
this.addEvent = function(oDomElement, oEventType, oFunc) {
//ie
if (oDomElement.attachEvent) {
oDomElement.attachEvent("on" + oEventType, oFunc);
}
//ff,opera,safari等
else if (oDomElement.addEventListener) {
oDomElement.addEventListener(oEventType, oFunc, false);
}
//其他
else {
oDomElement["on" + oEventType] = oFunc;
}
}
this.removeEvent = function(oDomElement, oEventType, oFunc) {
//ie
if (oDomElement.detachEvent) {
oDomElement.detachEvent("on" + oEventType, oFunc);
}
//ff,opera,safari等
else if (oDomElement.removeEventListener) {
oDomElement.removeEventListener(oEventType, oFunc, false);
}
//其他
else {
oDomElement["on" + oEventType] = null;
}
}
}
正像注釋寫的那樣,要注冊dom元素事件,用EventUtil.addEvent(dom元素,事件名稱,事件觸發(fā)的函數(shù)名)即可, 移除時可以這樣寫:EventUtil.removeEvent(dom元素,事件名稱,事件觸發(fā)的函數(shù)名)。這是題外話,不說了。
(3)、類定義中使用this關(guān)鍵字
這個其實再常見不過,看示例:
function thisTest()
{
var tmpName = 'jeff wong';
this.userName= 'jeff wong';
}
var test= new thisTest();
alert(test.userName==test.tmpName);//false
alert(test.userName); //jeff wong
alert(test.tmpName); //undefined
分析一下結(jié)果,其實這里的this和c#里的是類似的。
(4)、為腳本對象添加原形方法
理解這里的前提是你必須了解js里的原型概念(說道這里,kao,我還真的需要面壁一下):js中對象的prototype屬性,是用來返回對象類型原型的引用的。所有js內(nèi)部對象都有只讀的prototype屬性,可以向其原型中動態(tài)添加功能(屬性和方法),
但該對象不能被賦予不同的原型。但是對于用戶定義的對象可以被賦給新的原型??磦€簡單的示例:
//js的內(nèi)部對象String,向其原型中動態(tài)添加功能(屬性和方法)
//去掉字符串兩端的空白字符
String.prototype.Trim = function() {
return this.replace(/(^\s+)|(\s+$)/g, "");
}
function thisTest()
{
var tmpName = 'jeff wong';
this.userName= ' jeff wong ';
}
//給用戶定義的對象添加原型方法
thisTest.prototype.ToString = function()
{
alert(this.userName); //jeff wong(有空格)
alert(this.userName.Trim()); //jeff wong (無空格)
//alert(tmpName); //腳本錯誤,tmpName未定義
}
var test= new thisTest();
test.ToString(); //調(diào)用原型的ToString()
function myTest(){
this.userName= ' test ';
}
var test1=new myTest();
//test1.ToString(); //這里暫時不支持調(diào)用ToString()方法
//用戶定義的對象被賦給新的原型
myTest.prototype = new thisTest();
test1.ToString(); //調(diào)用原型的ToString()
測試結(jié)果顯示,這里的this指代的是被添加原形(方法或?qū)傩裕┑念惖膶嵗?,和?)中的定義基本相似。
(5)、在函數(shù)的內(nèi)部函數(shù)中使用this關(guān)鍵字
這個你要是理解作用域和閉包,問題就迎刃而解??醋畹湫偷氖纠?br/>function thisTest()
{
this.userName= 'outer userName';
function innerThisTest(){
var userName="inner userName";
alert(userName); //inner userName
alert(this.userName); //outer userName
}
return innerThisTest;
}
thisTest()();
分析:thisTest()調(diào)用內(nèi)部的innerThisTest函數(shù),形成一個閉包。innerThisTest執(zhí)行時,第一次彈出innerUserName,是因為innerThisTest函數(shù)作用域內(nèi)有一個變量叫userName,所以直接彈出當前作用域下變量的指定值;第二次彈出outer userName是因為innerThisTest作用域內(nèi)沒有userName屬性(示例中的this.userName),所以它向上一級作用域中找userName屬性,這次在thisTest中找到(示例中的this.userName= 'outer userName';),所以彈出對應(yīng)值。
(6)通過Function的call和apply函數(shù)指定特定的this
這個指定來指定去,this就有可能造成“你中有我,我中有你”的局面,不想把自己弄暈了的話,了解一下就可以了。改變this指定對象對于代碼維護也是一件很不好的事情。貼出舊文中的示例代碼結(jié)束吧:
function myFuncOne() {
this.p = "myFuncOne-";
this.A = function(arg) {
alert(this.p + arg);
}
}
function myFuncTwo() {
this.p = "myFuncTwo-";
this.B = function(arg) {
alert(this.p + arg);
}
}
function test() {
var obj1 = new myFuncOne();
var obj2 = new myFuncTwo();
obj1.A("testA"); //顯示myFuncOne-testA
obj2.B("testB"); //顯示myFuncTwo-testB
obj1.A.apply(obj2, ["testA"]); //顯示myFuncTwo-testA,其中[ testA”]是僅有一個元素的數(shù)組
obj2.B.apply(obj1, ["testB"]); //顯示myFuncOne-testB,其中[ testB”]是僅有一個元素的數(shù)組
obj1.A.call(obj2, "testA"); //顯示myFuncTwo-testA
obj2.B.call(obj1, "testB"); //顯示myFuncOne-testB
}
總結(jié):到這里,對于開篇中的span彈出undefined的問題你是不是已經(jīng)豁然開朗?如果你還在懵懂中,給個可有可無的提示:當前的這個span元素有沒有textValue屬性啊?。?br/>三、void
1、定義
javascript中void是一個操作符,該操作符指定要計算一個表達式但是不返回值。
2、語法
void 操作符用法格式如下:
(1). javascript:void (expression)
(2). javascript:void expression
注意:expression是一個要計算的js標準的表達式。表達式外側(cè)的圓括號是可選的,但是寫上去你可以一眼就知道括弧內(nèi)的是一個表達式(這和typeof后面的表達式語法是一樣的)。
3、實例代碼
function voidTest() {
void (alert("it is a void test")); //執(zhí)行函數(shù)
var oTestNum = 1;
void (oTestNum++); //整數(shù)自加
alert(oTestNum);
oTestNum = 1;
void (oTestNum += " void test"); //整數(shù)加字符串
alert(oTestNum);
}
voidTest();
4、在a元素下使用void(0)
(1)適用情況
在網(wǎng)頁中,我們經(jīng)??吹絟tml里的a標簽不需要它導(dǎo)航到某一個頁面時,href屬性設(shè)置的寫法:
link1
link2
注意:第一種“#”的寫法(其實#可以是多個,通常都是1個),當a元素所在的鏈接在瀏覽器一屏以下時,會導(dǎo)致頁面回滾到頂部;所以當我們需要a標簽不導(dǎo)航到其他頁面,不需要網(wǎng)頁位置的回滾,都會采取void(0)那種寫法。
(2)ie6下void(0)造成的詭異問題
這個問題網(wǎng)上有很多討論,個人認為“落葉滿長沙[void]”總結(jié)的很有代表性,這里就不再贅述了。


本文標題:JavaScript的self和this使用小結(jié)
網(wǎng)頁地址:http://weahome.cn/article/gsoopj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部