熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

JavaScript中幾個重要的屬性

2013-11-15 12:05:20  來源: JSP教程 

  this
this表示當前對象如果在全局作用范圍內使用this則指代當前頁面對象window 如果在函數中使用this則this指代什麼是根據運行時此函數在什麼對象上被調用 我們還可以使用apply和call兩個全局方法來改變函數中this的具體指向
先看一個在全局作用范圍內使用this的例子

代碼如下:
<script type=>
consolelog( === window);
consolelog(windowalert === alert);
consolelog(parseInt( ));
</script>

  
函數中的this是在運行時決定的而不是函數定義時如下

代碼如下:
foo() {
consolelog(fruit);
}
fruit = ;
foo();
pack = {
fruit:
foo: foo
};
packfoo();

  
全局函數apply和call可以用來改變函數中this的指向如下

代碼如下:
foo() {
consolelog(fruit);
}
fruit = ;
pack = {
fruit:
};
fooapply(window);
fooapply(pack);

  
apply和call兩個函數的作用相同唯一的區別是兩個函數的參數定義不同
因為在JavaScript中函數也是對象所以我們可以看到如下有趣的例子

 代碼如下:
foo() {
( === window) {
consolelog();
}
}
fooboo = () {
( === foo) {
consolelog();
} ( === window) {
consolelog();
}
};
foo();
fooboo();
foobooapply(window);

  
prototype
prototype本質上還是一個JavaScript對象 並且每個函數都有一個默認的prototype屬性
如果這個函數被用在創建自定義對象的場景中我們稱這個函數為構造函數 比如下面一個簡單的場景

 代碼如下:
Person(name) {
name = name;
}
Personprototype = {
getName: () {
name;
}
}
zhang = Person();
consolelog(zhanggetName());

  
作為類比我們考慮下JavaScript中的數據類型 字符串(String)數字(Number)數組(Array)對象(Object)日期(Date)等 我們有理由相信在JavaScript內部這些類型都是作為構造函數來實現的比如
Array() {
}
arr = Array( );
arr = [ ];
同時對數組操作的很多方法(比如concatjoinpush)應該也是在prototype屬性中定義的
實際上JavaScript所有的固有數據類型都具有只讀的prototype屬性(這是可以理解的因為如果修改了這些類型的prototype屬性則哪些預定義的方法就消失了) 但是我們可以向其中添加自己的擴展方法
Arrayprototypemin = () {
min = [];
( i = ; i < length; i++) {
([i] < min) {
min = [i];
}
}
min;
};
consolelog([ ]min());
注意這裡有一個陷阱向Array的原型中添加擴展方法後當使用forin循環數組時這個擴展方法也會被循環出來
下面的代碼說明這一點(假設已經向Array的原型中擴展了min方法)
arr = [ ];
total = ;
( i arr) {
total += parseInt(arr[i] );
}
consolelog(total);
解決方法也很簡單
arr = [ ];
total = ;
( i arr) {
(arrhasOwnProperty(i)) {
total += parseInt(arr[i] );
}
}
consolelog(total);
constructor
constructor始終指向創建當前對象的構造函數比如下面例子

代碼如下:
arr = [ ];
consolelog(arrconstructor === Array);
Foo = () { };
consolelog(Fooconstructor === Function);
obj = Foo();
consolelog(objconstructor === Foo);
consolelog(objconstructorconstructor === Function);

  
但是當constructor遇到prototype時有趣的事情就發生了
我們知道每個函數都有一個默認的屬性prototype而這個prototype的constructor默認指向這個函數如下例所示

 代碼如下:
Person(name) {
name = name;
};
PersonprototypegetName = () {
name;
};
p = Person();
consolelog(pconstructor === Person);
consolelog(Personprototypeconstructor === Person);
consolelog(pconstructorprototypeconstructor === Person);

  
當時當我們重新定義函數的prototype時(注意和上例的區別這裡不是修改而是覆蓋) constructor的行為就有點奇怪了如下示例

代碼如下:
Person(name) {
name = name;
};
Personprototype = {
getName: () {
name;
}
};
p = Person();
consolelog(pconstructor === Person);
consolelog(Personprototypeconstructor === Person);
consolelog(pconstructorprototypeconstructor === Person);

  
為什麼呢?
原來是因為覆蓋Personprototype時等價於進行如下代碼操作

 代碼如下:
Personprototype = Object({
getName: () {
name;
}
});

  
而constructor始終指向創建自身的構造函數所以此時Personprototypeconstructor === Object即是

 代碼如下:
Person(name) {
name = name;
};
Personprototype = {
getName: () {
name;
}
};
p = Person();
consolelog(pconstructor === Object);
consolelog(Personprototypeconstructor === Object);
consolelog(pconstructorprototypeconstructor === Object);

  
怎麼修正這種問題呢?方法也很簡單重新覆蓋Personprototypeconstructor即可

 代碼如下:
Person(name) {
name = name;
};
Personprototype = Object({
getName: () {
name;
}
});
Personprototypeconstructor = Person;
p = Person();
consolelog(pconstructor === Person);
consolelog(Personprototypeconstructor === Person);
consolelog(pconstructorprototypeconstructor === Person); 
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/20262.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.