JS面向?qū)ο螅?)之Object類(lèi),靜態(tài)屬性,閉包,私有屬性, call和apply的使用,繼承的三種實(shí)現(xiàn)方法
1.Object類(lèi)
在JS中,Object是所有類(lèi)的基類(lèi),使用Object類(lèi)來(lái)創(chuàng)建自定義對(duì)象時(shí),可以無(wú)需定義構(gòu)造函數(shù)(constructor,prototype,hasOwnProperty(property))
var per = new Object(); per.name = 'zhangsan'; per.age = ; alert(per.name + per.age);
我們想在程序中得到一個(gè)對(duì)象變量,只要能存儲(chǔ)大量數(shù)據(jù)即可,這個(gè)時(shí)候,我們可以考慮使用Object類(lèi)。Object類(lèi)避免了對(duì)構(gòu)造器的定義。 Object類(lèi)下另一個(gè)常用的屬性:hasOwnProperty
var per = new Object(); per.name = 'zhangsan'; per.age = ; if per.hasOwnProperty('email'){ alert('具有email'); }else{ alert('無(wú)email'); }
2.靜態(tài)屬性
在有些面向?qū)ο蟮恼Z(yǔ)言當(dāng)中,可以使用static關(guān)鍵字定義類(lèi)的靜態(tài)屬性或者靜態(tài)方法,在JS中,可以進(jìn)行模擬。
語(yǔ)法:
類(lèi)名.屬性名
類(lèi)名.屬性=function(){}
function Person(){ } Person.count = ; var p = new Person(); Person.count++; var p = new Person(); Person.count++; var p = new Person(); Person.count++; alert(Person.count);
添加靜態(tài)屬性和靜態(tài)方法:
function Person(){ Person.count++; //靜態(tài)屬性 Person.getCount=function(){ //靜態(tài)方法 alert('當(dāng)前共有' + Person.count + '個(gè)人'); } } Person.count = ; var p = new Person(); var p = new Person(); var p = new Person(); Person.getCount();
3.閉包
概念:所謂閉包,指的是一個(gè)擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個(gè)函數(shù)),因此這些變量也是該表達(dá)式的一部分。
提出一個(gè)問(wèn)題:
function display(){ var i=; } display(); //在這里,想訪(fǎng)問(wèn)局部變量i
在全局中,不能訪(fǎng)問(wèn)局部變量i,因?yàn)樽饔糜虿煌?,而且,在display函數(shù)執(zhí)行完畢后,局部變量i會(huì)被回收。 閉包的功能:“訪(fǎng)問(wèn)局部變量”和“使變量所占的內(nèi)存不被釋放”
//例 function fn(){ function fn(){ alert('hello'); } return fn; //返回fn函數(shù)首地址 } var test=fn(); //test也指向了fn函數(shù)的首地址 test();
通過(guò)例1我們知道:變量是可以指向函數(shù)的首地址的,函數(shù)也可以返回另一個(gè)函數(shù)的首地址。
//例 function fn(){ var i = ; function fn(){ alert(i); } return fn; //返回fn函數(shù)首地址 } var test=fn(); //test也指向了fn函數(shù)的首地址 test();
通過(guò)例2我們知道:使用一個(gè)拒不函數(shù)包含變量i,這樣局部變量i的內(nèi)存不會(huì)被回收。
//例 function fn(){ var i = ; function fn(){ alert(i++); } return fn; //返回fn函數(shù)首地址 } var test=fn(); //test也指向了fn函數(shù)的首地址 test(); test(); test();
在例3中,因?yàn)閕的內(nèi)存永遠(yuǎn)不會(huì)被回收,所以每次調(diào)用fn2,i的值會(huì)+1。運(yùn)行的結(jié)果是彈出10,彈出11,彈出12。
閉包的原理:在例3中,共有三個(gè)作用域:全局作用域,fn1的作用域,fn2的作用域。在全局作用域里有test=fn1(),其實(shí)這句話(huà)就相當(dāng)于test=fn2。在fn1作用域里有 var i=10和return fn2,在fn2作用域例有alert(i++)。當(dāng)全局作用域下的test=fn1()執(zhí)行時(shí),test指向了fn2的作用域,這個(gè)時(shí)候fn2作用域下的i被全局作用域鉤住,根據(jù)作用域鏈的法則,fn2下并沒(méi)有定義i,所以在fn2下的i往上一層作用域上找,找到了fn1作用域下的var i=10。所以全局的test鉤住了fn2的i,fn2的i鉤住了fn1的i,所以fn1運(yùn)行完畢后,不會(huì)被回收。
4.私有屬性
在面向?qū)ο笏枷胫?,?duì)于有些敏感的,不想公開(kāi)的成員可以定義為私有的,在JavaScript中可以模擬這個(gè)功能。
語(yǔ)法:
function Person(p_name){ var name = p_name; this.age }
var :私有
this :公有
function Person(p_name,p_age){ this.name = p_name; var age = p_age; } var p = new Person('zhangsan',); alert(p.name); alert(p.age);
在上面這個(gè)例子中,我們想用 var 來(lái)表示私有成員屬性,但 Person 構(gòu)造函數(shù)執(zhí)行完畢后, age 會(huì)被回收,不能當(dāng)做成員屬性來(lái)使用。
function Person(p_name,p_age){ this.name = p_name; var age = p_age; this.setAge=function(a){ age = a; } this.getAge=function(){ return(age); } } var p = new Person('zhangsan',); p.setAge(); alert(p.getAge());
this.setAge和this.getAge兩個(gè)方法使用到了局部變量age,所以age不會(huì)被回收。
如果只有set方法,說(shuō)明該屬性是只寫(xiě)屬性。
如果只有g(shù)et方法,說(shuō)明該屬性是只讀屬性。
5.call和apply的使用
call和apply的功能:使用指定的對(duì)象調(diào)用當(dāng)前函數(shù)。call和apply的功能完全相同,只是在語(yǔ)法上略有不同。
語(yǔ)法:
call([thisObj[,arg1[,arg2[,argN]]]])
第一個(gè)參數(shù):函數(shù)執(zhí)行時(shí),this指向誰(shuí)
后面的參數(shù):根據(jù)需要順序指定
apply([thisObj[,argArray]])
第一個(gè)參數(shù):函數(shù)執(zhí)行時(shí),this指向誰(shuí)
第二個(gè)參數(shù):數(shù)組,表示參數(shù)集合
在js中,函數(shù)有幾種調(diào)用形式:
Person(); //Person內(nèi)的this指向window var p=new Person(); //Person內(nèi)的this指向p per.Person(); //Person內(nèi)的this指向per function Person(p_name,p_age){ this.name = p_name; this.age = p_age; } function speak(){ alert(this.name + this.age); } var p = new Person('zhangsan',); //speak(); 這樣調(diào)用this指向window //p.speak(); p對(duì)象沒(méi)有speak屬性
使用call和apply來(lái)調(diào)用
function Person(p_name,p_age){ this.name = p_name; this.age = p_age; } function speak(){ alert(this.name + this.age); } var p = new Person('zhangsan',); speak.call(p); speak.apply(p);
call和apply在執(zhí)行時(shí)做了兩件事:1)將函數(shù)內(nèi)部this指向了第一個(gè)參數(shù) 2)調(diào)用函數(shù)
另外:還可以這樣解決問(wèn)題:
P1.say=speak;
P1.say();
這樣解決和上面解決方法有本質(zhì)上的區(qū)別:
上面的解決辦法是直接調(diào)用speak函數(shù),只不過(guò)函數(shù)內(nèi)部this的指向發(fā)生改變。
下面的解決辦法會(huì)為p1對(duì)象增加屬性,p1對(duì)象的“體積”會(huì)變大。
舉例說(shuō)明:
<script> function fn(){ this.style.color='red'; } function fn(){ this.style.fontSize='px'; } window.onload=function(){ document.getElementById('btn').onclick=function(){ var div = document.getElementById('div'); fn.call(div); fn.apply(div); }; }; </script> <div id='div'>hello javascript</div> <input type='button' id='btn' value='確定'>
6.繼承的三種實(shí)現(xiàn)方法
概念:在有些面向?qū)ο笳Z(yǔ)言中,可以使用一個(gè)類(lèi)(子類(lèi))繼承另一個(gè)類(lèi)(父類(lèi)),子類(lèi)可以擁有父類(lèi)的屬性和方法,這個(gè)功能可以在js中進(jìn)行模擬。
三種方法:
第一種:擴(kuò)展Object方法
Object.prototype.方法=function(父類(lèi)對(duì)象){ for(var i in 父類(lèi)對(duì)象){ this[i] = 父類(lèi)對(duì)象[i]; } };
舉例說(shuō)明:
Object.prototype.ext=function(parObject){ //循環(huán)遍歷父類(lèi)對(duì)象所有屬性 for(var i in parObject){ //為子類(lèi)對(duì)象添加這個(gè)遍歷到的屬性 //它的值是父類(lèi)對(duì)象這個(gè)屬性的屬性值 this[i] = parObject[i]; } } function Person(p_name,p_age){ this.name=p_name; this.age=p_age; this.speak=function(){ alert(this.name+this.age); } } function Student(p_no){ this.no=p_no; this.say=function(){ alert(this.no+this.name_this.age); } } var stu = new Student(); stu.ext(new Person('xiaoqiang',)); stu.speak(); stu.say();
第二種:使用call和apply方法
語(yǔ)法:
父類(lèi)構(gòu)造器.call(this,.......);
function Person(p_name,p_age){ this.name=p_name; this.age=p_age; this.speak=function(){ alert(this.name+this.age); } } function Student(p_no,p_name,p_age){ this.no=p_no; this.say=function(){ alert(this.name+this.age+this.no); } Person.call(this,p_name,p_age); } var stu = new Student(,'zhagsan',); stu.speak(); stu.say();
第三種:原型繼承
語(yǔ)法:
子類(lèi).prototype = new 父類(lèi)();
function Person(p_name,p_age){ this.name=p_name; this.age=p_age; this.speak=function(){ alert(this.name+this.age); } } function Student(p_no){ this.no=p_no; this.say=function(){ alert(this.name+this.age+this.no); } } Student.prototype = new Person('wangwu',); var stu = new Student(); stu.speak(); stu.say();
以上內(nèi)容給大家介紹了JS面向?qū)ο螅?)之Object類(lèi),靜態(tài)屬性,閉包,私有屬性, call和apply的使用,繼承的三種實(shí)現(xiàn)方法,希望對(duì)大家有所幫助!
相關(guān)文章
ES6 Generator函數(shù)的應(yīng)用實(shí)例分析
這篇文章主要介紹了ES6 Generator函數(shù)的應(yīng)用,結(jié)合實(shí)例形式分析了ES6 Generator函數(shù)異步操作與異常捕獲相關(guān)使用技巧,需要的朋友可以參考下2019-06-06javascript鼠標(biāo)跟隨運(yùn)動(dòng)3種效果(眼球效果,蘋(píng)果菜單,方向跟隨)
在很多網(wǎng)站上能看到圖片跟隨鼠標(biāo)移動(dòng)的JS特效,其實(shí)做法很簡(jiǎn)單,本文就介紹了很多javascript鼠標(biāo)跟隨運(yùn)動(dòng),在這里與大家分享下。2016-10-10JavaScript 關(guān)鍵字屏蔽實(shí)現(xiàn)函數(shù)
JavaScript屏蔽關(guān)鍵字,大概的思路就是去用javascript去替換已有的文本,達(dá)到替換的目的2009-08-08JavaScript中使用typeof運(yùn)算符需要注意的幾個(gè)坑
這篇文章主要介紹了JavaScript中使用typeof運(yùn)算符需要注意的幾個(gè)坑,本文總結(jié)了4個(gè)使用typeof運(yùn)算符要注意的問(wèn)題,需要的朋友可以參考下2014-11-11get post jsonp三種數(shù)據(jù)交互形式實(shí)例詳解
本文通過(guò)實(shí)例給大家詳細(xì)介紹了get post jsonp三種數(shù)據(jù)交互形式,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-08-08JS實(shí)現(xiàn)的左側(cè)豎向滑動(dòng)菜單效果代碼
這篇文章主要介紹了JS實(shí)現(xiàn)的左側(cè)豎向滑動(dòng)菜單效果代碼,涉及JavaScript響應(yīng)鼠標(biāo)點(diǎn)擊事件操作頁(yè)面元素樣式的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10JS將光標(biāo)聚焦在文本最后的實(shí)現(xiàn)代碼
這篇文章主要介紹了JS將光標(biāo)聚焦在文本最后的方法,需要的朋友可以參考下2014-03-03隨鼠標(biāo)移動(dòng)的時(shí)鐘非常漂亮遺憾的是只支持IE
這篇文章主要介紹了隨鼠標(biāo)移動(dòng)的時(shí)鐘非常漂亮遺憾的是只支持IE,需要的朋友可以參考下2014-08-08