面向?qū)ο?/h3>
- 類,原型患雇,實例三者打交道
- 類里面存放的都是私有屬性和方法
- 原型prototype上存的都是公有的屬性和方法
- 類里面的this都指向?qū)嵗?/li>
- 類里面的this跟var沒有任何關(guān)系妈经,var是用來預(yù)解釋的
- 類里面會自動幫我們創(chuàng)建和返回this
對象:屬性 和 方法
寫面向?qū)ο蟮男「[門
- 把全局變量都作為私有屬性
- 把全局函數(shù)都作為公有方法
- 面向?qū)ο笾械膖his淮野,永遠(yuǎn)執(zhí)行實例
屬性判斷:判斷某個屬性,是否在某個對象上
- in 公有+私有:"attr" in obj => true / false
- hasOwnProperty 是否為私有: fl.hasOwnProperty('attr')=>true / false
- hasPubProperty 是否為公有(不是系統(tǒng)提供的吹泡,是自己寫的)
- 思路:必須是元素身上的屬性骤星,并且不是私有屬性
function hasPubProperty(attr,obj){
if(attr in obj && !obj.hasOwnProperty(attr)){
return attr;
}
}
- isPropertyOf 判斷是否在原型鏈上:obj1.isPropertyOf(boj2)
循環(huán)遍歷
- for...in...循環(huán):只能遍歷自己給對象添加的私有屬性+公有屬性,不能遍歷對象的系統(tǒng)屬性
- hasOwnProperty和propertyIsEnumerable爆哑,都可以遍歷自己定的私有屬性洞难,不能遍歷公有屬性和系統(tǒng)自帶的屬性
關(guān)于Object和Function之間的關(guān)系
- 對象的老大 Object
- 函數(shù)的老大 Function
- Object是Function的爹
- Function是Object這個基類的爹
- Object.prototype是Function.prototype的爹
- 所有的對象,都可以使用Object.prototype上的方法
- 但是揭朝,只有函數(shù)數(shù)據(jù)類型队贱,才能使用Function。prototype的方法潭袱,因為所有函數(shù)數(shù)據(jù)類型是Function這個類的實例
函數(shù)的三種角色
- 普通函數(shù)->作用:預(yù)解釋 作用域鏈 上級作用域 代碼從上到下執(zhí)行
- 類->作用:類 原型 實例 原型鏈
- 對象->作用:跟普通的對象一樣柱嫌, 都可以添加屬性和方法
Function.prototype
- Function.prototype雖然是個匿名函數(shù),但是他具有普通prototype一樣的功能
call apply bind
- fa.call():有兩類參數(shù)
- 第一個參數(shù):用來改變call前面函數(shù)中this關(guān)鍵字的指向
- 從第二個參數(shù)開始:給call前面的函數(shù)從左到右屯换,一個個的傳參
- call改完this编丘,傳完參數(shù)之后与学,函數(shù)會“立即執(zhí)行”
- fa.apply():有兩個參數(shù) -> 跟call功能一樣,但是傳參形式不同
- 第一個參數(shù):用來改變apply前面函數(shù)中this關(guān)鍵字的執(zhí)行
- 第二個參數(shù)(數(shù)組):也是給apply前面的函數(shù)從左到右嘉抓,一個個的傳參
- fa.bind():預(yù)處理機(jī)制
- 參數(shù)跟call一樣
- bind()給前面的函數(shù)索守,改完this,傳完參后抑片,不會立即執(zhí)行卵佛,只會返回一個函數(shù)的定義階段;
- 在需要的地方調(diào)用
this小總結(jié)
- 當(dāng)元素身上的事件被觸發(fā)的時候敞斋,會執(zhí)行一個函數(shù)截汪,函數(shù)中的this執(zhí)行當(dāng)前這個元素
- 當(dāng)函數(shù)被調(diào)用的時候,看前面是否有點渺尘,點前面是誰挫鸽,this就是誰,沒有點鸥跟,this就是window
- 自執(zhí)行函數(shù)中的this丢郊,永遠(yuǎn)指向window
- 回調(diào)函數(shù)中的this,一般指向window医咨,但是可以通過thisArg更改this指向
- 構(gòu)造函數(shù)中的this枫匾,指向?qū)嵗?/li>
- 當(dāng)遇到call、apply拟淮、bind的時候干茉,以上規(guī)則全失效,他們?nèi)齻€就是用來更改this指向的
繼承
- call繼承:子類只繼承父類“私有”的屬性和方法很泊,不繼承公有
<script>
function F(){
this.x = 100;
this.y = 200;
}
F.prototype.a = 111;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function Son(){
F.call(this);
}
var s1 = new Son;
console.dir(s1);
</script>
- 拷貝繼承:子類只繼承父類“公有”的屬性和方法角虫,不繼承私有
<script>
// 通過此方法繼承的公有在第一個__proto__上
function extend(obj1,obj2) {
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
return obj1;
}
function F() {
this.x = 100;
this.y = 100;
}
F.prototype.a = 123;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){}
extend(S.prototype,F.prototype);
var s1 = new S;
console.dir(s1);
</script>
- 原型鏈繼承:子類把父類私有和公有的屬性和方法,都放在自己的prototype上
<script>
//通過此方法繼承委造,公有在__proto__找到的__proto__上
function extend(obj){
function Tmp() {}
Tmp.prototype = obj.prototype;
return new Tmp;
}
function F(){
this.x = 100;
this.y = 200;
}
F.prototype.a = 111;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){};
S.prototype = new F;
var s1 = new S;
console.dir(s1);
</script>
- 混合式繼承:call繼承+拷貝繼承
// 最后S繼承的屬性位置和F一樣
function extend(obj1,obj2) {
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
return obj1;
}
function F() {
this.x = 100;
this.y = 100;
}
F.prototype.a = 123;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){
F.call(this);
}
extend(S.prototype,F.prototype);
var s1 = new S;
console.dir(s1);
- 寄生式組合繼承
function setCreat(obj){
function Tmp(){}
Tmp.prototype = obj.prototype;
return new Tmp();
}
function F() {
this.a = 1;
this.b = 2;
}
F.prototype.c = 3;
F.prototype.d = function () {};
var f1 = new F;
console.dir(f1);
function Son(){
F.call(this);
}
Son.prototype = setCreat(F);
var s1 = new Son;
console.dir(s1);
可視區(qū)的寬度和高度
- 寬度:document.documentELement.clientWhidth || document.body.clientWidth
- 高度:document.documentElementlientHeight || document.body.clientHeight
對象:屬性 和 方法
- 思路:必須是元素身上的屬性骤星,并且不是私有屬性
function hasPubProperty(attr,obj){
if(attr in obj && !obj.hasOwnProperty(attr)){
return attr;
}
}
- 所有的對象,都可以使用Object.prototype上的方法
- 但是揭朝,只有函數(shù)數(shù)據(jù)類型队贱,才能使用Function。prototype的方法潭袱,因為所有函數(shù)數(shù)據(jù)類型是Function這個類的實例
- 第一個參數(shù):用來改變call前面函數(shù)中this關(guān)鍵字的指向
- 從第二個參數(shù)開始:給call前面的函數(shù)從左到右屯换,一個個的傳參
- call改完this编丘,傳完參數(shù)之后与学,函數(shù)會“立即執(zhí)行”
- 第一個參數(shù):用來改變apply前面函數(shù)中this關(guān)鍵字的執(zhí)行
- 第二個參數(shù)(數(shù)組):也是給apply前面的函數(shù)從左到右嘉抓,一個個的傳參
- 參數(shù)跟call一樣
- bind()給前面的函數(shù)索守,改完this,傳完參后抑片,不會立即執(zhí)行卵佛,只會返回一個函數(shù)的定義階段;
- 在需要的地方調(diào)用
<script>
function F(){
this.x = 100;
this.y = 200;
}
F.prototype.a = 111;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function Son(){
F.call(this);
}
var s1 = new Son;
console.dir(s1);
</script>
<script>
// 通過此方法繼承的公有在第一個__proto__上
function extend(obj1,obj2) {
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
return obj1;
}
function F() {
this.x = 100;
this.y = 100;
}
F.prototype.a = 123;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){}
extend(S.prototype,F.prototype);
var s1 = new S;
console.dir(s1);
</script>
<script>
//通過此方法繼承委造,公有在__proto__找到的__proto__上
function extend(obj){
function Tmp() {}
Tmp.prototype = obj.prototype;
return new Tmp;
}
function F(){
this.x = 100;
this.y = 200;
}
F.prototype.a = 111;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){};
S.prototype = new F;
var s1 = new S;
console.dir(s1);
</script>
// 最后S繼承的屬性位置和F一樣
function extend(obj1,obj2) {
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
return obj1;
}
function F() {
this.x = 100;
this.y = 100;
}
F.prototype.a = 123;
F.prototype.showX = function(){};
var f1 = new F;
console.dir(f1);
function S(){
F.call(this);
}
extend(S.prototype,F.prototype);
var s1 = new S;
console.dir(s1);
function setCreat(obj){
function Tmp(){}
Tmp.prototype = obj.prototype;
return new Tmp();
}
function F() {
this.a = 1;
this.b = 2;
}
F.prototype.c = 3;
F.prototype.d = function () {};
var f1 = new F;
console.dir(f1);
function Son(){
F.call(this);
}
Son.prototype = setCreat(F);
var s1 = new Son;
console.dir(s1);