1、RegExp對象 javascript
一、建立正則表達式:html
var patt=new RegExp('javascript'); var res=patt.test('this is a javascript course'); console.log(res);
pattr='/javascript/i';//表示忽略大小寫 res=patt.test('this is a javascript course') console.log(res)
二、[]表達式java
var res= /[abc]/.test('blue');
res=/[^abc]/.test('lue')
三、元字符 正則表達式
var res=/./.test('\n'); // 元字符. 匹配不換行
var res=/\w/.test('this is a blue') \w 是0-9 a-z A-Z \W是除了前面的這些
// \s表示空白字符 \S 非空白字符 var res=/\s/.test('hello world!')
// \b表明單詞的邊界 var res=/\bgood\b/.test('this is good one');
四、量詞數組
// +表示至少出現一次 var res=/o+/.test('good'); console.log(res)
// *表示0 1或者屢次 var res=/o*/.test('goodle'); // ?表示0或者1次 var res=/o?/.test('goodle');
// {}指定多少次 var res=/o{2}/.test('goodle')
// ^開頭 $結尾 var res=/^good$/.test('good);
var res=/o(?=w)/.test('helloworld'); //o後面緊跟着w
var res=/o(?!w)/.test('helloworld'); //o後面不緊跟着w
// d表示數字 D表示非數字 var res=/\d/.test('1032')
五、exec能夠返回一個數組形式的結果瀏覽器
var res=/is/ig.exec('this is a test'); console.log(res)
console.log(res[0])
六、matchapp
結果爲一個數組
var str='this is a test' res=str.match(/IS/ig) console.log(res)
七、searchdom
結果表示有2個
var str='this is a test!!!' res=str.search(/is/ig) console.log(res)
八、replaceiphone
var str='this is a test!!!' res=str.replace(/is/ig,'!!!') console.log(res)
九、分組匹配ide
var str='2017-09-27' res=str.replace(/(\d{4})-(\d{2})-(\d{2})/,'$2/$3/$1'); console.log(res)
十、split拆分
var str='this is a test'; var res=str.split(/\s+/); console.log(res);
2、Error對象
Error與try catch一塊兒調用
try{ var n=0; if(n==0){ throw new Error('0不能被當作除數');//主動彈出一個錯誤信息 }else{ alert(4/n); } }catch (e){ alert(e.name+':'+e.message); }finally { alert('我老是被調用') }
區分不一樣的錯誤類型
try{ }catch (e){ if(e instanceof EvalError){ alert(e.message) }else if(e instanceof RangeError){ alert(e.message) }else if(e instanceof ReferenceError){ alert(e.message) }else{ alert('其餘錯誤') } }
自定義錯誤
function MyError(msg) { this.name='MyError' this.message=msg||'默認的自定義錯誤信息' } MyError.prototype=Object.create(Error.prototype); MyError.prototype.constructor=MyError; try{ throw new MyError(); }catch (e){ console.log(e.name+":"+e.message); } try{ throw new MyError('測試自定義的錯誤信息') }catch (e){ console.log(e.name+":"+e.message); }
3、數組對象
一、建立數組
var arr=[] var arr1=new Array(); var arr2=new Array(5);
二、操做數組
var arr=[1,2,3,4,5,6] arr[0]='king'//修改數組
三、經常使用方法
//join將數組轉換成指定字符連接符 var arr=['a','b','c','d']; var res=arr.join('--'); console.log(res);
//反轉 var arr=['a','b','c','d']; console.log(arr.reverse())
var arr=[1,3,23,112,351,31,33]; console.log(arr.sort(function (a,b) { return a-b;//表示從小到大 若是return b-a表示從大到小 }))
var arr=[ {name:'king', age:23}, {name:'kkblue', age:59}, {name:'gavin', age:64}, {name:'tom', age:3} ]; arr.sort(function (a,b) { if(a.name>b.name) return 1; if(a.name<b.name) return -1; return 0; }); for(var i in arr){ console.log(arr[i]); }
//合併數組 var arr=[1,2,3]; console.log(arr.concat([4,5,6,7]))
// 切割 var arr=['a','b','c','d','e','g','h','i']; res=arr.slice(0,3); console.log(res); res=arr.slice(0,-3); console.log(res);
var arr=['a','b','c','d','e','g','h','i']; res=arr.splice(0,1);//從0開始到1刪除 console.log(res); console.log(arr); res=arr.splice(5);//從index 5開始刪除 console.log(res); console.log(arr); res=arr.splice(0,2,'!','?','#')//從index 0開始到index 2替換爲 !? # console.log(res); console.log(arr);
var arr=['a!','b!','c!','D','E']; var res= arr.map(function (t) { return t.replace(/!/g,'?').toUpperCase(); }); console.log(res)
var arr=[1,2,3,4,32,314,null,undefined,false,'',true]; res=arr.filter(function (t) { return t<=10; }) console.log(res); res=arr.filter(function (t) { return t%2==0; }); console.log(res); res=arr.filter(function (t) { return t!==undefined && t!=null; }); console.log(res);
map、filter 、reduce、every、some概念對比:
map:
主意對數組內元素進行操做,舉例說明:
var attr=[1,2,3,4,5,6,7] var res=attr.map(function (t) { return t*2; }) console.log(res)
filter:
filter操做是對數組內元素進行過濾操做,符合條件的能夠被過濾出來
var attr=[1,2,3,4,5,6,7] var res=attr.filter(function (t) { return t>3; }) console.log(res)
reduce:
reduce是個累加器,會接收兩個元素,而後將結果與第三個元素再進行操做,一直到數組結束爲止
res=attr.reduce(function (p1,p2) { return p1*p2+1 })
every和some:
every和some都會返回true或false,其中every須要數組元素都知足才返回true,而some只要有一個元素知足條件就返回true
var res=attr.every(function (t) { return t>1; }) console.log(res)
var attr=[1,2,3,4,5,6,7] var res=attr.some(function (t) { return t>1; }) console.log(res)
indexOf與lastIndexOf:
能夠查找是否在數組中,若是找到會返回index值,若是沒有找到會返回 -1,經過這個能夠判斷元素是否在數組中,裏面包括兩個參數,第一個是要查找的元素,第二個是從哪一個位置開始查找
Array.isArray():
判斷是不是一個數組
toString():
toString和join同樣都是鏈接字符串,可是和join不同的地方在於它只能經過,來鏈接
3、事件
JS是經過事件來與網頁進行交互的。
事件包括如下幾部分:
一、事件類型:是一個用來講明發生什麼類型事件的字符串,像鼠標懸停,按下鍵盤等,也能夠把事件類型叫作事件名字,用特定的名字來標識所討論的特定類型的事件
二、事件目標:事件目標是發生事件或者與之相關的對象,當講事件時,咱們必須同時指定類型和目標,像window的load事件或者連接的click事件,在客戶端js應用程序中,window,document,和Element對象是最多見的事件目標,可是某些事件也是右其餘類型的對象觸發的
三、事件處理程序:用戶在頁面中進行點擊這個動做、鼠標移動的動做,網頁頁面加載完成的動做等,均可以稱爲事件名稱即click mousemove load等都是事件的名稱,響應某個事件的函數稱之爲事件處理程序,或者事件偵聽器
四、事件對象:是與特定事件相關且包含有關事件詳細信息的對象、事件對象做爲參數傳遞給事件處理程序函數,全部事件對象都有用來指定事件類型的type屬性和指定事件目標target屬性,每一個事件類型都爲其相關事件對象定義一組屬性
五、事件傳播:瀏覽器決定那個對象觸發⑦某個事件處理程序
事件類型:
一、內聯模型
<input type="button" onclick="alert('hello ')" value="點擊">
二、腳本模型
腳本模型是爲了解決html與js無法分離的問題,可是腳本模型無法執行多個事件處理程序,這個須要DOM2的事件來完成
<input type="button" value="腳本模型1" id="btn1"> <script> btn1=document.getElementById('btn1'); btn1.onclick=function () { alert('hello2') } </script>
//直接賦值不須要加括號 function test2() { alert('hello3') } btn2=document.getElementById('btn2'); btn2.onclick=test2
var btn3=document.getElementById('btn3'); var count=0; btn3.onclick=function () { alert(count++); if(count===3){ btn3.onclick=null;//dom取消須要將它從新複製爲Null就能夠了 } }
三、DOM2模型
addEventLisnter()與removeEventLisnter()W3C與IE9之後支持
attathEvent() detachEvent() IE8支持
須要注意的是:
IE中經過e獲取不到,須要window.event來獲取事件
<body> <input type="button" value="dianji" id="btn1"> <script> var btn1=document.getElementById('btn1'); btn1.onclick=function (e) { e=e||window.evnet;//IE中經過e獲取不到,須要window.event來獲取事件 } </script> </body>
事件流:
從頁面中接收事件的順序
冒泡:從裏往外 大部分瀏覽器都支持冒泡
捕獲:從外往裏
<div id="div1" style="background:#ABCDEF;width:300px;height:100px;"> <input type="button" value="dianji" id="btn1"> </div> <script> var btn1=document.getElementById('btn1'); var box1=document.getElementById('div1'); btn1.onclick=function () { alert('btn1 ') } box1.onclick=function () { alert('box1') } document.body.onclick=function () { alert('body') } document.documentElement.onclick=function () { alert('html') } document.onclick=function () { alert('document') } </script>
取消冒泡:
btn1.onclick=function () {
alert('btn1 ');
var e = e||window.event;
if(typeof e.cancelBubble ==undefined){
e.stopPropagation();//取消冒泡
}else{
e.cancelBubble=true;//IE取消
}
}
addEventListener(x,x,x)和removeEvenetListener(x,x,x)
addEventListener包括三個參數,第一個是事件名,第二個是函數,第三個是false或者true,其中false表示冒泡
var btn1=document.getElementById('btn1'); var box1=document.getElementById('div1'); btn1.addEventListener('click',function () { alert('button clicked') },false)//addEventListener包括三個參數,第一個是事件類型,第二個是函數,第三個是false或者true,其中false表示冒泡 box1.addEventListener('click',function () { alert('div clicked') },false) document.body.addEventListener('click',function () { alert('body clicked') },false) document.documentElement.addEventListener('click',function () { alert('html') },false) document.addEventListener('click',function () { alert('document click') },false)
var btn2=document.getElementById('btn2'); var count=0; var handler1=function () { alert(count++); if(count==3){ alert('事件被取消') btn2.removeEventListener('click',handler1,false);//若是想取消必須定義函數不能使用匿名函數 } }; btn2.addEventListener('click',handler1,false)
attachEvent(x,x)和detachEvent(x,x)
只包含兩個參數,事件名與函數名,其中click須要寫成onclick
在IE8中須要使用window.event.cancelBubble=true來取消事件冒泡
誇瀏覽器的處理事件函數
var EventUtil={ addHandler:function (element,type,handler) { if(element.addEventListener){ element.addEventListener(type,handler,false) }else if(element.attachEvent){ element.attachEvent('on'+type,handler) }else{ element['on'+type]=handler } }, removehandler:function (element,type,handler) { if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent('on'+type,handler); }else{ element['on'+type]=null; } } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./EventUtil.js"></script> </head> <body> <input type="button" id="btn1" value="bangding"> <input type="button" id="btn2" value="yichu"> <script> // 綁定 var btn1=document.getElementById('btn1'); function test() { alert('hello king!'); } EventUtil.addHandler(btn1,'click',test); // 移除綁定 var btn2=document.getElementById('btn2'); function test1() { EventUtil.removehandler(btn1,'click',test) } EventUtil.addHandler(btn2,'click',test1); </script> </body> </html>
判斷行爲類型與取消默認行爲
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="button" value="tijiao" id="btn1"> <br> <a href="https://wwww.baidu.com" id="btn2">點擊</a> <script> var btn1=document.getElementById('btn1'); btn1.addEventListener('click',function () { alert('click') },false); btn1.addEventListener('mouseover',function (e) { e.target.style.backgroundColor='red'; },false); btn1.addEventListener('mouseout',function (e) { e.target.style.backgroundColor='' }); btn2.addEventListener('click',function (e) { e.preventDefault();//取消默認行爲
//若是是在IE8中,須要使用window.event.returnValue=false 來取消默認行爲
}) </script> </body> </html>
eventPhase屬性:
W3C中
捕獲階段調用事件處理程序:eventPhase=1
處於目標對象上:eventPhase=2
冒泡階段調用事件處理程序:eventPhase=3
IE8中
使用window.event.srcElement來獲取行爲階段
統一行爲處理函數:
var EventUtil={ addHandler:function (element,type,handler) { // 添加事件 if(element.addEventListener){ element.addEventListener(type,handler,false) }else if(element.attachEvent){ element.attachEvent('on'+type,handler) }else{ element['on'+type]=handler } }, removehandler:function (element,type,handler) { // 取消事件 if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent('on'+type,handler); }else{ element['on'+type]=null; } }, getEvent:function (event) { // 獲取事件 return event?event:window.event; }, getTarget:function (event) { return event.target || event.srcElement; }, preventDefault:function (event) { // 取消默認行爲 if(event.preventDefault){ event.preventDefault() }else{ event.returnValue=false; } }, stopPropagation:function (event) { // 取消冒泡 if(event.stopPropagation){ event.stopPropagation(); }else{ event.cancelBubble=true; } } };
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./EventUtil.js"></script> </head> <body> <input type="button" value="tijiao" id="btn1"> <br> <a href="https://www.baidu.com" id="btn2">dianji</a> <div id="div1" style="width:300px;height:300px;background:#ABCDEF"><input type="button" value="冒泡" id="btn3"></div> <script> var btn1=document.getElementById('btn1'); EventUtil.addHandler(btn1,'click',function (event) { event=EventUtil.getEvent(event); var target=EventUtil.getTarget(event); alert(target.tagName); }); var btn2=document.getElementById('btn2'); EventUtil.addHandler(btn2,'click',function (event) { event=EventUtil.getEvent(event); EventUtil.preventDefault(event);//阻止默認行爲 }) var btn3=document.getElementById('btn3'); EventUtil.addHandler(btn3,'click',function (event) { event=EventUtil.getEvent(event); alert('click'); EventUtil.stopPropagation(event);//阻止冒泡 }) </script> </body> </html>
5、表單驗證
6、特殊函數
一、私有函數
爲了防止某些變量泄漏採用私有函數方式,外界沒法看到函數的值
<script> function a(p) { var b=function (e) { return e+10 }; return b(p); } console.log('私有函數:',a(14)) </script>
二、返回函數的函數
function a() {
alert('aaaa');
return function () {
alert('bbbb')
}
}
var func=a();
func()
三、擴展性
全部的內置對象和自定義對象都是顯示可擴展的,宿主對象的可擴展性由JS引擎定義的
Object.isExtensible()檢測是否可擴展的,也能夠經過Object.preventExtensitions()變爲不可擴展,同時注意,變爲不可擴展的話,不能再變爲可擴展的
var obj={};
console.log(Object.isExtensible(obj));
變爲不可擴展的
var d={};
d.x=2;
Object.preventExtensions(d);
d.y=3;
console.log(d);
Object.seal()能將對象設置爲不可擴展外,還能將對象的全部自身屬性都變爲不可配置,也就是說不能給這個對象添加新的屬性,而且它已有屬性也不能添加和配置,不過他的已有屬性可讀屬性依然能夠配置,經過Object.isSealed()檢測對象是否封閉
var obj={
x:1,
y:2,
username:'gavin'
};
obj.age=22;
delete obj.x;
console.log(obj);
var o=Object.seal(obj);
console.log(Object.isExtensible(obj));
obj.y=55;//原有的屬性仍然能夠修改
console.log(obj.y);
Object.defineProperty(obj,'username',{
get:function () {
return 'this is a test'
}
});//會報錯:不能從新定義username,由於它已經seal了
console.log(obj.username);
o.z=77;//無法添加成功
console.log(o.z);
Object.defineProperties(obj,'username',{
value:'queen'
});//無法修改
console.log(Object.isSealed(o))
===========================================================
console.log(Object.getOwnPropertyDescriptor(obj,'username'));//檢測username屬性
Object.freeze():
除了對象設置爲不可擴展和將其屬性設置爲不可配置外,還能夠將他自身全部數據屬性設置爲只讀,若是對象存儲器屬性具備setter方法,存儲器屬性不受影響,仍然能夠經過屬性賦值賦值給他們,Object.isFroze()檢查是否凍結
數據封裝對象包括:
Object對象
Object.prototype
Number
Boolean
String
Array
Function
7、Object對象
定義:Object是js中全部對象的父級對象,咱們建立的全部對象都繼承於此,包括內建對象
語法:new Object()或者{name:value}
屬性:
Object.create()
Object.defineProperty()
Object.definProperties() 在一個對象上添加或修改一個或多個自有屬性,並返回對象
Object.keys()
Object.getOwnPropertyNames()返回一個由指定對象的全部自身屬性的屬性名組成的數組,這其中包括不可枚舉的
Object.getOwnPropertyDescriptor(obj, prop)返回指定對象上一個自有屬性對應的屬性描述符,兩個參數,第一個是哪一個對象,第二個是這個對象的哪一個屬性
var obj={get foo() {
return 123
}};
console.log(Object.getOwnPropertyDescriptor(obj,'foo'));
obj={
name:'gavin',
age:18
};
console.log(Object.getOwnPropertyDescriptor(obj,'name'));
obj={} Object.defineProperty(obj,'test',{ value:'this is a test', writable: false, enumerable:false, configurable:true }); console.log(Object.getOwnPropertyDescriptor(obj,'test'))
var obj1={x:1} var obj2=Object.create(obj1); console.log(Object.getOwnPropertyDescriptor(obj2,'x'));//無法查找,由於這個命令只能查看到它自身的屬性,而不是繼承過來的屬性
能夠經過下面的命令來獲得obj2的屬性與值:
console.log(Object.getPrototypeOf(obj2)==obj1);
Object.getPrototypeOf():返回指定對象的原型,也就是該對象內部屬性[Prototype]的值
Object.prototype:
全部對象都繼承了Object.prototype的方法和屬性,儘管他們可能被覆蓋
屬性:
Object.prototype.constructor返回一個指向建立了該對象原型的函數引用
var obj3=new Object(); console.log(Object.constructor==Object);
Object.prototype.hasOwnProperty()檢測某個對象是否含有指定的自身屬性
Object.prototype.isPrototypeOf() 檢測一個對象是否存在於另外一個對象的原型鏈上
Object.prototype.propertyIsEnumerable():檢測指定的屬性是不是當前對象可枚舉的自身屬性
Object.prototype.toString()返回一個表明該對象的字符串
//能夠簡寫 var toString=Object.prototype.toString; console.log(toString.call(new Date)); console.log(toString.call(Math));
Object.prototype.valueOf()返回的是this值,即對象自己
var obj={x:1}; console.log(obj.valueOf());
8、Number對象
語法:new Number()
console.log(Number.MAX_VALUE);
console.log(Number.MIN_VALUE)
console.log(Number.NaN);
console.log(Number.NEGATIVE_INFINITY);
console.log(Number.POSITIVE_INFINITY);
console.log(Number.isNaN(NaN));
console.log(Number.isNaN(Number.NaN));
console.log(Number.isNaN('NaN'));
toFixed()返回一個字符串,以定點數的形式來表達某個數字,並進行四捨五入
var n = 12345.5665; console.log(n.toFixed(2));//保留2位小數 console.log(n.toFixed(12));//會不夠位數補零
toExponential()返回要給字符串,以指數形式來表達某一個數字
var x1=77.1234; console.log(x1.toExponential()); console.log(x1.toExponential(2));
toPrecision()返回一個字符串,便可以是指數型,也能夠是小數型
9、Boolean對象
語法new Boolean()
var b=new Boolean(); console.log(typeof b); console.log(b.valueOf()); console.log(typeof b.valueOf()); var c=new Boolean(0); console.log(c);
10、String對象
new String(s) 構造函數
function String(s)轉換函數
// 第一個表示字符串 var n='gavin'; console.log(typeof n); // 第二個是string函數 var n=String('gavin'); console.log(typeof n); // 第三個是string對象 var n=new String('gavin'); console.log(typeof n);
string對象和string函數是有區別的
方法:
String.charAt(n) n表明索引值,表示取得一個字符串的第n個字符,但願返回的字符在字符串string中的索引,返回值是字符串string的第n個字符
注意:返回字符串的起始點爲0,若是不在該字符串長度返回內會返回空字符串
var k=new String('gavin'); console.log(k.charAt(0)); console.log(k.charAt(1)); console.log(k.charAt(2)); console.log(k.charAt(3)); console.log(k.charAt(10));
String.charCodeAt()返回指定字符的ASCII值
var a=new String("this is a test"); console.log(a.charCodeAt(0)) console.log(a.charCodeAt(2)) console.log(a.charCodeAt(5)) console.log(a.charCodeAt(10));
String.fromCharCode()根據指定ASCII返回對應的字符
console.log(String.fromCharCode(117));
console.log(String.fromCharCode(65,69,73));
String.concat()連接字符串
var str='hello'; console.log(str.concat(' world'))
console.log(str.concat(' world','kkkkkk','!!!'))
String.indexOf()查找的字符串位置,返回的字符串首次所在位置,沒有的話返回-1
var atr='this is a test!'; console.log(atr.indexOf('!'));
//查看a出現的次數 var str='aslajfaldfefalfajfelafelafe'; var pos=str.indexOf('a') var count=0; while(pos!=-1){ count++; pos=str.indexOf('a',pos+1); } console.log(count);
String.localCompare()比較字符串
console.log('k'.localeCompare('z'));
String.math():找到一個或多個正則表達式的結果
var str='this is a test!'; var re=/is/ig; console.log(str.match(re)); var str='QWEQWQW!#O!#@E!@#O!JEJ!#@E!@#jafdewiaeefqwefoeqer'; console.log(str.match(/[a-f]/ig))
String.search()根據正則表達式進行搜索
var str='this is a seaisrch!'; console.log(str.search(/is/i));
String.replace()替換
var str1="this is a test"; var res=str.replace(/is/ig,'KKK'); console.log(res)
String.slice()截取
var str='abcedf'; var res=str.slice(2) console.log(res);//從2開始截取所有 console.log(str.slice(0,2));//從0開始截取到2爲止
String.split()將字符串拆分紅數組,其中包括兩個參數,第一個是以誰來差分,第二個是取幾部分
var str='2017-09-12'; var arr=str.split('-') console.log(arr)
String.toUperCase() String.toLowerCase()
console.log('KING'.toLowerCase());
console.log('king'.toUpperCase());
11、Function對象
JS中全部函數都是以對象形式存在的
屬性:
一、construtor返回建立該對象的構造函數
二、length 返回調用當前函數的參數個數
三、caller 返回調用當前函數的函數
function A() { return A.caller; } function B() { return A() } console.log(B()); console.log(A());
四、arugments返回該函數執行時內置的arguments對象
function Test() { return arguments } console.log(Test(1,2,3,4,'a'))
arguments.callee是調用函數自己,能夠經過這種方式實現遞歸,舉例說明,匿名函數的遞歸:
function (count) { if(count<=3){ console.log(count); arguments.callee(++count); } } )(0);
方法:
一、call()調用當前Function對象,可同時改變函數內的this指針引用,函數參數一個個分別傳入
var obj={ name:'gavin', say:function (somebody) { return 'hello '+somebody+' this is '+ this.name; } } var obj1={ name:'kkblue' } // 若是obj1想引用obj中的say方法,可使用call() console.log(obj.say.call(obj1,'tom'));
12、Function對象
三、apply()調用當前Function對象,可同時改變函數內this指針引用,函數參數以數組或者arguments方式傳入
三、toString()返回定義該Function對象的字符串
四、valueOf()返回Function對象自己
工具類對象:
一、Math對象
二、Date對象
十3、Math對象
console.log(Math.E); console.log(Math.PI); console.log(Math.abs(-12)); console.log(Math.ceil(12.3323)); console.log(Math.floor(14.8)); console.log(Math.round(12345.52387,2)); console.log(Math.pow(2,3)); console.log(Math.sqrt(4)); console.log(Math.random()); console.log(Math.max(12,3,23,2323,5234,234232,3223432,)); console.log(Math.min(123,3234,2324,123,3,32));
十4、對象的屬性
對象自身的屬性優先於對象的原型屬性,舉例說明:
function Product(name) { this.name=name; } Product.prototype.name='gaivn'; var p1=new Product('kkblue') console.log(p1.name);//自身屬性高於原型屬性 delete p1.name;//刪除自身屬性,會去查找原型屬性 console.log(p1.name);
若是隻顯示自身屬性,可使用hasOwnProperty()來進行判斷:
function pro(name,color){ this.name = name; this.color = color; this.someMethod = function () { return 'this is a test!!!' } } pro.prototype.price = 123454; pro.prototype.memory = 32; var p1 = new pro('蘋果手機','白色'); for(var i in p1){ console.log(i); } // 若是隻想顯示自身的屬性而不是原型屬性使用hasOwnProperty for(var j in p1){ if(p1.hasOwnProperty(j)){ console.log(j) } }
十5、prototype屬性
prototype能夠給原型添加屬性,這樣作的好處在於,即便實例已經引用了對象,可是仍然能夠經過對象原型添加屬性,這是實例仍然能夠繼承這些原型屬性,能夠任意調用並修改
只有函數纔有prototype屬性,並且prototype對應的是一個對象,這個對象裏的construtor指回的是這個函數自己
注意:
在經過prototype進行原型添加的時候,便可以一個一個添加也能夠經過對象的方式一塊兒添加,例如:
function Product(name,color){ this.name = name; this.color = color; this.WhatAreYou = function () { return 'this is a '+this.color + ' '+ this.name; } } Product.prototype={ price:6888, memory: 64, getInfo:function () { return "內存: "+ this.memory +"--價格: "+ Product.prototype.price;//在進行屬性調用的時候,便可以使用this方式也可使用prototype方式調用 } }; var p1 = new Product('iphone6','玫瑰金'); console.log(p1.name); console.log(p1.color); console.log(p1.WhatAreYou()); console.log(p1.price); console.log(p1.memory);//這些都是在原型上獲得的, console.log(p1.getInfo());
function Product(name,color){ this.name = name; this.color = color; this.WhatAreYou = function () { return 'this is a '+this.color + ' '+ this.name; } } Product.prototype={ price:6888, memory: 64, getInfo:function () { return "內存: "+ this.memory +"--價格: "+ Product.prototype.price;//在進行屬性調用的時候,便可以使用this方式也可使用prototype方式調用 } }; var p1 = new Product('iphone6','玫瑰金'); console.log(p1.name); console.log(p1.color); console.log(p1.WhatAreYou()); console.log(p1.price); console.log(p1.memory); console.log(p1.getInfo()); 在實例化之後,又經過prototype添加了新的屬性或者方法,可是實例仍然能夠引用 Product.prototype.get=function (what) { return this[what]; } console.log(p1.get('name')); console.log(p1.get('price'))
__proto__屬性:對象專有,函數是沒有的
每一個函數在實例化後,產生的新的對象都會有一個__proto__隱含的屬性指向源函數的prototype屬性產生的原型對象,這個__proto__也叫作僞類屬性,它是新產生的對象跟函數的原型對象之間的直接紐帶關係,能夠不經過函數就直接訪問
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> function Person() { var age=30; this.age=22; this.name='gavin'; } Person.prototype.headcount=3; var p1=new Person(); var p2=new Person(); Person.prototype.headcount=4; p1.constructor={name:33};//修改了p1的constructor後,p1的原型就不是Person了,可是仍然能夠經過p1.headcout訪問到 //說明p1獲得原型對象不是經過p1.constructor.prototype.headcount來獲得的,而是經過__proto__直接從原型對象中獲得的 console.log(p1.headcount); console.log(p1.__proto__.headcount); Person.prototype.xx='aaaa'; console.log(p1.xx); Person.prototype={yy:44}; console.log(p1.yy);//訪問不到,可是若是new一個對象,能夠訪問到 var p3=new Person(); console.log(p3.yy); </script> </body> </html>
十6、JS解析與執行過程
全局:
預處理階段:
在全局層面,JS解析器有一個Exectue Context(執行上下文),這裏有兩種類型:
一、var定義的變量,會直接定義爲 變量名: undefined
二、函數:會直接將整個函數引用調用
順序爲先掃描函數聲明後掃描變量(var聲明的變量)在這裏有兩個原則:
一、處理函數聲明有衝突,會覆蓋原有的函數
二、處理變量聲明有衝突,會忽略新的變量聲明
執行階段
函數:
預處理階段
執行階段
十7、this
this表示運行時的調用,而不是定義時的調用,只有當運行時才能知道this表明的是誰
繼承與多態的例子:
其中繼承經過Object.create(父類的.prototype)來完成,可是記住須要將子類的constructor修改成本身的類名,同時實現多態,須要子類的super=父類的prototype,同時在子類定義時須要調用子類.super.和父類同名的函數名稱