首页 > 代码库 > 前端知识小总结4
前端知识小总结4
三:
1-数组:用于在单个的变量中存储多个值。
创建数组的方法:new Array(); new Array(size); new Array(e0,e1,…,en);
组属性:constructor(返回对创建此对象的数组函数的引用)、length(设置或返回数组中元素个数)、prototype(一种向对象中添加属性和方法的能力)
数组方法:
concat():将多个数组进行连接,不会改变现有数组,而仅返回连接后的数组。
arrayObject.concat(arrayX,arrayX,…); arrayX,必需参数,可以是具体的值,也可以是数组对象,可有任意多个。
var a=new Array(1,2,3);
var b=new Array(6,8);
var c=new Array(9,7);
console.log(a.concat(b));// [ 1, 2, 3, 6, 8]
console.log(a.concat(b,c));// [ 1, 2, 3, 6, 8, 9, 7 ]
join():把数组的所有元素放入一个字符串,元素通过指定的分隔符进行分隔。返回一个字符串,该字符串是通过把数组中的每个元素转换为字符串,然后把这些字符串连接起来,在两个元素之间插入分隔符。
arrayObject.join(separator); separator可选参数,指定要使用的分隔符,若该参数省略,则默认逗号作为分隔符。
var a=new Array("ahjsn","hadds","ans");
console.log(a.join(‘-‘));//ahjsn-hadds-ans
console.log(a.join(‘.‘));//ahjsn.hadds.ans
onsole.log(a.join());//ahjsn,hadds,ans
pop():删除并返回数组的最后一个元素(删除的元素),将数组长度减1。若数组已经为空,则pop()不改变数组并返回undefined值。arrayObject.pop();
var a=new Array("ahjsn","hadds","ans");
console.log(a.pop());//ans
console.log(a.pop());//hadds
console.log(a.pop());//ahjsn
console.log(a.pop());//undefined
push():向数组末尾添加元素,并返回数组新的长度,直接修改原数组。
arrayObject().push(e1,e2,…); e1必需参数,要参加到数组的第一个元素,e2可选参数,可添加多个元素。
var a=new Array("ads","asd");
console.log(a.push("sd"));//3
console.log(a.push("sd","ash"));//5
reverse():颠倒数组中元素的顺序,改变原来的数组,返回颠倒后的数组。
arrayObject.reverse();
var a=new Array("ahjsn","hadds","ans");
console.log(a.reverse());//[ ‘ans‘, ‘hadds‘, ‘ahjsn‘ ]
shift():删除数组的第一个元素,并返回其值。若数组为空,则不进行任何操作并返回undefined值。arrayObject.shift();
var a=new Array("ahjsn","hadds","ans"); console.log(a.shift());//ahjsn
slice():从某个已有的数组中返回从start到end选定的元素,该方法不会修改数组,而是返回一个子数组。arrayObject.slice(start,end);start必需参数,规定从何处开始选取,若为负数,则表示从尾部开始选取,-1表示最后一个元素。end可选参数,规定从何处结束选取,负数表示从尾部算起。
var a=new Array("ahjsn","hadds","ans","dgd","qws"); console.log(a.slice());//[ ‘ahjsn‘, ‘hadds‘, ‘ans‘, ‘dgd‘, ‘qws‘ ] console.log(a.slice(1,2));//[ ‘hadds‘ ] console.log(a.slice(0,1));//[ ‘ahjsn‘ ] console.log(a.slice(2));//[ ‘ans‘, ‘dgd‘, ‘qws‘ ]
console.log(a.slice(-1));//[ ‘qws‘ ]
sort():对数组进行排序,原先数组已经被改变,返回得到的新数组。
arrayObject().sort(sortby) ; 参数可选,必须是函数,默认顺序排序,字符编码的顺序,如果需要按照其他标准排序,则需要提供比较函数。
var a=new Array("ahjsn","hadds","ans","dgd","qws");
console.log(a.sort());//[ ‘ahjsn‘, ‘ans‘, ‘dgd‘, ‘hadds‘, ‘qws‘ ]
console.log(a);//[ ‘ahjsn‘, ‘ans‘, ‘dgd‘, ‘hadds‘, ‘qws‘ ]
var b=new Array("1","100","30","50");
console.log(b.sort());//[ ‘1‘, ‘100‘, ‘30‘, ‘50‘ ]
function sortNumber(a, b){
return a - b
}
console.log(b.sort(sortNumber));//[ ‘1‘, ‘30‘, ‘50‘, ‘100‘ ]
splice():向数组中添加或删除元素,会改变原数组,返回被删除的元素。
arrayObject.splice(index,howmany,item1,…itemx); index必需参数,规定添加或删除元素的位置,负数可从数组结尾处规定位置;howmany必需,要删除的元素个数,若为0则不会删除元素;item1可选参数,向数组添加的新元素。
var arr=new Array(‘as‘,‘sd‘,‘ss‘,‘we‘);
console.log(arr);//[ ‘as‘, ‘sd‘, ‘ss‘, ‘we‘ ]
arr.splice(2,0,‘wm‘);
console.log(arr);//[ ‘as‘, ‘sd‘, ‘wm‘, ‘ss‘, ‘we‘ ]
arr.splice(2,1,‘o‘);
console.log(arr);//[ ‘as‘, ‘sd‘, ‘o‘, ‘ss‘, ‘we‘ ]
arr.splice(3,2,‘t‘);
console.log(arr);//[ ‘as‘, ‘sd‘, ‘o‘, ‘t‘ ]
toSource():表示对象的源代码,只有 Gecko 核心的浏览器(比如 Firefox)支持该方法。
toString():把数组转换为字符串,并返回结果。arrayObject.toString();返回值与没有参数的join()方法返回的字符串相同。
var arr=new Array("adf","jkf","dksl","mnk"); console.log(arr.toString());//adf,jkf,dksl,mnk
toLocaleString():把数组转换为本地字符串表示。arrayObject.toLocaleString();
unshift():向数组的开头添加一个或更多元素,将已存在的元素顺序的往后移,原数组会改变,并返回新数组的长度。arrayObject.unshift(newelement1,newelement2,…,newelementx);第一个参数必需,向数组添加的第一个元素,后面参数可选。
var arr=new Array("adf","jkf","dksl","mnk");
console.log(arr.unshift("sd","jkfdn"));//6
valueOf():返回数组的原始值。arrayObject.valueOf();一般后台自动调用。
var arr=new Array("adf","jkf","dksl","mnk");
console.log(arr.unshift("sd","jkfdn"));//6
console.log(arr.valueOf());//[ ‘sd‘, ‘jkfdn‘, ‘adf‘, ‘jkf‘, ‘dksl‘, ‘mnk‘ ]
参考:http://www.w3school.com.cn/js/js_obj_array.asp
2-字符串:用于处理文本
创建字符串对象的方法:new String(s);或者String(s);其中,参数s是要存储在String对象中或转换成原始字符串的值。
返回值
当 String() 和运算符 new 一起作为构造函数使用时,它返回一个新创建的 String 对象,存放的是字符串 s 或 s 的字符串表示。
当不用 new 运算符调用 String() 时,它只把 s 转换成原始的字符串,并返回转换后的值。
String对象属性:constructor(对创建该对象的函数的引用)、length(字符串长度,该字符串中的字符数)、prototype(允许向对象添加属性和方法)、
String对象方法:
anchor():创建HTML锚。stringObject.anchor(name);参数必需,为锚定义名称。
big():将字符串显示为大号字体。stringObject.big();
var str="Hello world!";
document.write(str.big());
blink():用于显示闪动的字符串。stringObject.blink();(没看出来效果,爱哭脸)
bold():用于把字符串显示为粗体。stringObject.bold();
var str="Hello world!"
document.write(str.bold())
charAt():返回在指定位置的字符。stringObject.charAt(index);参数必需,表示字符串中某个位置的数字,即字符在字符串中的下标。
var str="Hello world!";
console.log(str.charAt(1));//e
charCodeAt():返回指定位置字符的Unicode编码。stringObject.charACodet(index);参数必需,表示字符串中某个位置的数字,即字符在字符串中的下标。
concat():连接字符串,返回连接后的字符串,但原先的字符串均未改变。stringObject.concat(stringX,…stringX);必需参数,连接一个或多个字符串对象。
var str1="hello";
var str2="world";
console.log(str1.concat(str2));//helloworld
console.log(str1);//hello
console.log(str2);//world
fontcolor():将字符串按照指定的颜色进行显示,返回指定颜色显示的字符串,但原字符串并未改变。stringObject.fontcolor(color);参数必需,颜色名、RGB值、或十六进制数。
fontsize():按照指定大小进行显示字符串,返回指定大小的字符串,但并未改变原字符串。stringObject.fontsize(size);参数必须是1到7的数字。
fromCharCode():将Unicode值转换为字符串。String.fromCharCode(numX,…numX);参数必需。
indexOf() :可返回某个指定的字符串值在字符串中首次出现的位置,对大小写敏感。stringObject.indexOf(searchvalue,fromindex);第一个参数必需,规定需检索的字符串;第二个参数可选,规定在字符串中开始检索的位置。
var str="dabaobao dahuaidaan"; console.log(str.indexOf("a"));//1 console.log(str.indexOf("dabaobao"));//0 console.log(str.indexOf("d"));//0 console.log(str);//dabaobao dahuaidaan
italics() :用于把字符串显示为斜体。stringObject.italics();
lastIndexOf():可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索,对大小写敏感。stringObject.lastIndexOf(searchvalue,fromindex);第一个参数必需,规定需检索的字符串值;第二个参数可选,规定在字符串中开始检索的位置。
var str="Hello world!"
console.log(str.lastIndexOf("Hello"));//0
link() :用于把字符串显示为超链接。stringObject.link (url);参数必需,规定需要链接的URL。
var str="Free Web Tutorials!"
document.write(str.link("http://www.w3school.com.cn"))
match():可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,返回指定的值。stringObject.match(searchvalue);参数必需,规定要检索的字符串值。stringObject.match(regexp);参数必需,规定要匹配的模式的regexp对象。
replace() :用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。stringObject.replace(regexp/substr,replacement);参数都必需,前者用来规定子字符串或要替换的模式的regexp对象;后者用来规定替换文本或生成替换文本的函数。
var str="Visit Microsoft!"
console.log(str.replace(/Microsoft/, "W3School"));//Visit W3School!
search():用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,返回stringObject中第一个与regexp相匹配的子串的起始位置。stringObject.search(regexp);参数为需要检索的子串。
var str="Visit W3School!";
document.write(str.search(/W3School/));//6
slice() :可提取字符串的某个部分,并以新的字符串返回被提取的部分。stringObject.slice(start,end); 参数表示截取子字符串的起始位置与结束位置。-1表示字符串的倒数最后一个字符。
var str="Hello happy world!"
document.write(str.slice(6))//happy world!
var str="Hello happy world!";
document.write(str.slice(6,11));//happy
small() :用于把字符串显示为小号字。stringObject.small();
split() :用于把一个字符串分割成字符串数组,原数组并未改变,返回分割后的。stringObject.split(separator, howmany);前者参数必需,字符串或正则表达式,从该参数指定的地方分割字符串对象。后者参数可选,该参数可指定返回的数组的最大长度。Ps:如果把空字符串用作separator,则stringObject中的每个字符之间都会被分割。
var str="How are you doing today?"
document.write(str.split("o") + "<br />")// H,w are y,u d,ing t,day?
document.write(str.split("") + "<br />")// H,o,w, ,a,r,e, ,y,o,u, ,d,o,i,n,g, ,t,o,d,a,y,?
document.write(str.split(" ",3))// How,are,you
strike() :用于显示加删除线的字符串,返回加删除线的字符串,但并未改变字符串本身。
var str="Hello world!";
document.write(str.strike());//Hello world!上有一删除线
document.write(str);//Hello world!
sub() :用于把字符串显示为下标。stringObject.sub();
var str="Hello world!";
document.write(str.sub()); //显示为下标形式
document.write(str);//原数组并未改变
substr() :可在字符串中抽取从 start 下标开始(包含start)的指定数目的字符,返回提取的字符串,但原字符串并未改变。
stringObject.substr(start,length);start参数必需,要提取的子串的开始下标;length可选参数,子串中的字符数。
var str="Hello world!";
document.write(str.substr(3));//lo world!
document.write(str);//Hello world!
document.write(str.substr(3,7))//lo worl
substring() :用于提取字符串中介于两个指定下标之间的字符,返回提取的子串,但原字符串并未改变。stringObject.substring(start,end);前者参数必需,规定提取的子串的第一个字符在stringObject中的位置;后者参数可选,比要提取的子串在stringObject中的位置多1,因为提取子串时,从start开始到end结束,但不包括end。
var str="Hello world!"; document.write(str.substring(3,7));//lo w
var str="Hello world!"; document.write(str.substring(3));//lo world!
sup():用于把字符串显示为上标。stringObject.sup();
toLocaleLowerCase() :用于把字符串转换为小写,返回小写字符串,但原字符串并未改变。stringObject.toLocaleLowerCase();
var str="Hello World!";//
document.write(str.toLocaleLowerCase());//hello world!
document.write(str);//Hello World!
toLocaleUpperCase() :用于把字符串转换为大写,返回大写的字符串,但原字符串本身没有改变。stringObject.toLocaleUpperCase();
toLowerCase() :用于把字符串转换为小写。stringObject.toLowerCase();
toUpperCase() :用于把字符串转换为大写。stringObject.toUpperCase();
toSource():代表对象的源代码
toString() :返回字符串。stringObject.toString();字符串对象的原始字符串,一般不会调用该方法。
valueOf() :可返回 String 对象的原始值。stringObject.valueof();
参考:http://www.w3school.com.cn/jsref/jsref_obj_string.asp
3-正则表达式方法
RegExp:正则表达式的缩写,当需要检索某个文本时,用来对文本进行匹配搜索内容的一种模式可理解为正则表达式。简单模式可能是一个单独字符,复杂模式可能包括了更多字符,并用于解析、格式检查、替换等。
Regexp对象用于存储检索模式。Regexp对象的定义方法:通过new关键词。
法1:var myregexp=/正则表达式/gi ;
法2:var myregexp=newRegExp(正则表达式,”gi”);
var pattern=new Regexp(”e”);//定义了名为pattern的regexp对象,其模式为e,即寻找的字符为e。
RegExp对象方法:test()、exec()、compile()
test():检索字符串中的指定值,返回true或false。
var patt1=new RegExp("e");
console.log(patt1.test("The best things in life are free"));//true
exec():检索字符串中的指定值,返回值为被找到的值,如找不到正则返回null。
var patt1=new RegExp("e");
console.log(patt1.exec("The best things in life are free"));
//[ ‘e‘, index: 2, input: ‘The best things in life are free‘ ]
compile():用于改变regexp,即可以改变检索模式,也可以添加或删除第二个参数。
var patt1=new RegExp("e");
console.log(patt1.test("The best things in life are free"));//true
patt1.compile("d");
console.log(patt1.test("The best things in life are free"));//false
参考:http://www.w3school.com.cn/js/js_obj_regexp.asp
4-对象
JavaScript中的所有事物都是对象,如字符串、数值、数组、函数、
JavaScript可以自定义对象
JavaScript提供多个内置对象,如String、Date、Array、Number、
对象可以理解为包含属性和方法的一种数据类型
访问对象的属性:
objectName.propertyName;如
var msg="ha shj";
var x=msg.length; console.log(x);//6
访问对象的方法:
objectName.methodName()如
var message="Hello world!";
var x=message.toUpperCase();
console.log(x);//HELLO WORLD!
创建JavaScript对象:
法1:定义并创建对象的实例
法2:使用函数来定义对象,然后创建新的对象实例
创建直接的实例:
person=new Object();
person.firstname="Bill";
person.lastname="Gates";
person={firstname:"John",lastname:"Doe"};
使用对象构造器:
function person(firstname,lastname,age,eyecolor){
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
}
创建JavaScript对象实例:
var myFather=new person("Bill","Gates",56,"blue");
var myMother=new person("Steve","Jobs",48,"green");
把属性添加到JavaScript对象:
person.firstname="Bill";
person.lastname="Gates";
x=person.firstname;
把方法添加到JavaScript对象:在构造器内部定义对象方法
function person(firstname,lastname,age,eyecolor){
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.changeName=changeName;
function changeName(name){
this.lastname=name;
}
}
http://www.w3school.com.cn/js/js_objects.asp
定义方法、原型、原型链、_proto_
5-事件
事件流:描述的是在页面中接收事件的顺序,包括捕获型事件和冒泡型事件,捕获型事件先发生。
捕获: 最不具体(父级元素)的元素节点先接收事件,而最具体(子级元素)的元素节点最后接收事件
冒泡:由最具体的元素接收,然后逐级向上传播至最不具体的元素节点
使用js的时候,当给子元素与父元素定义了相同的事件,如都定义了onclick事件,单击子元素时,父元素的onclick事件也会被触发。称这种事件连续发生的机制为事件冒泡或者事件捕获。这是不同浏览器对自己浏览器的事件采用了不同的发生机制。
如点击button按钮,则事件冒泡是由button这个具体的元素先接收,再是div-body-html;而捕获则是由html这个最不具体的节点先接收,然后再是body-div-button
IE只支持事件冒泡,Mozilla, Opera 7 和 Konqueror两种都支持,旧版本的Opera‘s 和 iCab两种都不支持 。
W3C规定:在W3C模型中,任何事件发生时,先从顶层(父级元素)开始进行事件捕获,直到事件触发到达了事件源元素(子级元素)。然后,再从事件源往上进行事件冒泡,直到到达document。
程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法为绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。例外,IE只支持事件冒泡,不支持事件捕获,它也不支持addEventListener函数,不会用第三个参数来表示是冒泡还是捕获,它提供了另一个函数attachEvent。
var div = document.getElementById("myDiv");
div.attachEvent("onclick", function(event) {
alert("1");
});
div.attachEvent("onclick", function(event) {
alert("2");
});
删除IE事件处理程序:
var div = document.getElementById("myDiv");
var handler = function(event) {
alert("delete");
};
div.attachEvent("onclick",handler);
div.detachEvent("onclick",handler);
删除IE事件处理程序,采用detachEvent(),删除时传入的参数必须和绑定时传入的参数相同,不能传入匿名函数。
addEventListener()接收三个参数:事件名称,事件处理函数和一个布尔值。布尔值为true,则表示在捕获阶段调用事件处理程序;如果为false,则表示在冒泡阶段调用事件处理程序。
<script type="text/javascript">
var div = document.getElementById("myDiv");
div.addEventListener("click", function(event) {
alert("event bubble");
}, false);
div.addEventListener("click", function(event) {
alert("event catch");
}, true);
</script>
删除DOM2级事件处理程序:
var div = document.getElementById("myDiv");
var handler=function(event){
alert("delete");
};
div.addEventListener("click",handler,false);
div.removeEventListener("click",handler,false);
删除时传入的参数必须和绑定时传入的参数相同,不能传入匿名函数。
attachEvent()采用冒泡方式,而addEventListener()可以采用冒泡或事件捕获方式。
事件的传播是可以阻止的:W3C中,使用event.stopPropagation()方法,阻止事件传播,包括捕获和冒泡;IE中设置event.cancelBubble=true,阻止冒泡;
事件默认行为的阻止:W3C中使用preventDefault()方法;IE下设置window.event.returnValue=http://www.mamicode.com/false;
先按由上往下的顺序执行事件捕获的执行程序,再执行目标元素的执行程序,最后按由下往上的顺序执行冒泡事件。
事件默认行为的阻止:
(1)return false;阻止通过on绑定的事件的默认行为
ele.onclick = function() {
…… //你的代码
return false; //通过返回false值阻止默认事件行为
};
(2)event.preventDefault();阻止通过addEventListener()添加的事件的默认行为
element.addEventListener("click", function(e){
var event = e || window.event;
……
event.preventDefault( ); //阻止默认事件
},false);
(3)event.returnValue=http://www.mamicode.com/false;阻止通过attachEvent()添加的事件的默认事件
element.attachEvent("onclick", function(e){
var event = e || window.event;
……
event.returnValue = http://www.mamicode.com/false; //阻止默认事件
},false);
将事件绑定及事件解绑封装成一个函数,兼容浏览器
// 事件绑定
function addEvent(element, eType, handle, bol) {
if(element.addEventListener){ //如果支持addEventListener
element.addEventListener(eType, handle, bol);
}else if(element.attachEvent){ //如果支持attachEvent
element.attachEvent("on"+eType, handle);
}else{ //否则使用兼容的onclick绑定
element["on"+eType] = handle;
}
}
// 事件解绑
function removeEvent(element, eType, handle, bol) {
if(element.addEventListener){
element.removeEventListener(eType, handle, bol);
}else if(element.attachEvent){
element.detachEvent("on"+eType, handle);
}else{
element["on"+eType] = null;
}
}
事件委托:利用事件冒泡特点,将内层事件委托为外层事件,根据event对象的属性进行事件委托,改善性能。
使用事件委托可以避免对特定元素节点添加事件监听器,事件监听器被添加到其父元素上,事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。
如果要单独点击table里面的td,普通做法是for循环给每个td绑定事件,td少的话性能什么差别,td如果多了,就不行了,我们使用事件委托:
<!-- HTML -->
<table id="out" border="1" style="cursor: pointer;">
<tr>
<td>table01</td>
<td>table02</td>
<td>table03</td>
<td>table04</td>
<td>table05</td>
<td>table06</td>
<td>table07</td>
<td>table08</td>
<td>table09</td>
<td>table10</td>
</tr>
</table>
var out = document.getElementById("out");
2 if(out.addEventListener){
3 out.addEventListener("click",function(e){
4 var e = e||window.event;
5 //IE没有e.target,有e.srcElement
6 var target = e.target||e.srcElement;
7 //判断事件目标是否是td,是的话target即为目标节点td
8 if(target.tagName.toLowerCase()=="td"){
9 changeStyle(target);
10 console.log(target.innerHTML);
11 }
12 },false);
13 }else{
14 out.attachEvent("onclick",function(e){
15 var e = e||window.event;
16 //IE没有e.target,有e.srcElement
17 var target = e.target||e.srcElement;
18 //判断事件目标是否是td,是的话target即为目标节点td
19 if(target.tagName.toLowerCase()=="td"){
20 changeStyle(target);
21 console.log(target.innerHTML);
22 }
23 });
24 };
25 };
26 function changeStyle(ele){
27 ele.innerHTML = "已点击"
28 ele.style.background="#900";
29 ele.style.color = "#fff"; }
http://www.cnblogs.com/zhangmingze/p/4864367.html
http://www.jb51.net/article/42492.htm
http://www.cnblogs.com/linxuehan/p/3623760.html
<!DOCTYPE html>
<html>
<head>
<title>冒泡事件</title>
<script type="text/javascript">
window.onload = function(){
window.onclick = function(){
alert("Window"); // 顶级
};
document.onclick = function(){
alert("Document"); // 次顶级
};
document.documentElement.onclick = function(){
alert("Html"); // 次次顶级
};
document.body.onclick = function(){
alert("Body"); // 次次次顶级
};
document.getElementById("myDiv").onclick = function(){
alert("Div"); // 最先执行,并且会传递到上一层。点击两次,则按顺序执行两次。如果上级也有点击事件的话
};
}
</script>
</head>
<body>
<div id="myDiv">点我</div>
</body>
</html>
点击之后,依次弹出div、body、html、document、window
n 点击myDiv。依次是Div-Body-Html-Document-Window
n 点击其他空白地方。依次是Html-Document-Window
n 连续点击两次,会按顺序执行两次
n 冒泡的前提是,父级也定义了相应的事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>事件捕捉</title>
<script type="text/javascript">
window.onload = function(){
window.addEventListener("click", function(){
alert("Window - true");
}, true); // true - 事件句柄在捕获阶段执行 ,false- false- 默认。事件句柄在冒泡阶段执行
document.addEventListener("click", function(){
alert("Document - true");
}, true);
document.documentElement.addEventListener("click", function(){
alert("Html - true");
}, true);
document.body.addEventListener("click", function(){
alert("Body - true");
}, true);
document.getElementById("myDiv").addEventListener("click", function(){
alert("Div - true");
}, true);
window.addEventListener("click", function(){
alert("Window - false");
}, false); // true - 事件句柄在捕获阶段执行 ,false- false- 默认。事件句柄在冒泡阶段执行
document.addEventListener("click", function(){
alert("Document - false");
}, false);
document.documentElement.addEventListener("click", function(){
alert("Html - false");
}, false);
document.body.addEventListener("click", function(){
alert("Body - false");
}, false);
document.getElementById("myDiv").addEventListener("click", function(){
alert("Div - false");
}, false);
window.onclick = function(){
alert("Window - click"); // 顶级
};
document.onclick = function(){
alert("Document - click"); // 次顶级
};
document.documentElement.onclick = function(){
alert("Html - click"); // 次次顶级
};
document.body.onclick = function(){
alert("Body - click"); // 次次次顶级
};
document.getElementById("myDiv").onclick = function(){
alert("Div - click"); // 最先执行,并且会传递到上一层。点击两次,则按顺序执行两次。如果上级也有点击事件的话
};
}
</script>
</head>
<body>
<div id="myDiv">点我</div>
</body>
</html>
1.点击的执行结果是
Window - true
Document - true
Html - true
Body - true
Div - true
Div - false
Div - click
Body - false
Body - click
Html - false
Html - click
Document - false
Document - click
Window - false
Window - click
2.顺序与js代码顺序无关
3.就算没有定义点击事件,一样可以捕获点击事件,只要点击到,就能捕获到
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>事件捕捉</title>
<script type="text/javascript">
window.onload = function(){
document.addEventListener("click", function(){
alert("Document - true");
}, true);
window.addEventListener("click", function(){
alert("Window - true");
}, true); // true - 事件句柄在捕获阶段执行 ,false- false- 默认。事件句柄在冒泡阶段执行
document.documentElement.addEventListener("click", function(){
alert("Html - true");
}, true);
document.body.addEventListener("click", function(){
alert("Body - true");
}, true);
document.getElementById("myDiv").addEventListener("click", function(){
alert("Div - true");
}, true);
window.addEventListener("click", function(){
alert("Window - false");
}, false); // true - 事件句柄在捕获阶段执行 ,false- false- 默认。事件句柄在冒泡阶段执行
document.addEventListener("click", function(){
alert("Document - false");
}, false);
document.documentElement.addEventListener("click", function(){
alert("Html - false");
}, false);
document.body.addEventListener("click", function(){
alert("Body - false");
}, false);
document.getElementById("myDiv").addEventListener("click", function(){
alert("Div - false");
}, false);
window.onclick = function(){
alert("Window - click"); // 顶级
};
document.onclick = function(){
alert("Document - click"); // 次顶级
};
document.documentElement.onclick = function(){
alert("Html - click"); // 次次顶级
};
document.body.onclick = function(){
alert("Body - click"); // 次次次顶级
};
document.getElementById("myDiv").onclick = function(){
alert("Div - click"); // 最先执行,并且会传递到上一层。点击两次,则按顺序执行两次。如果上级也有点击事件的话
event.stopPropagation(); // 阻止冒泡
};
}
</script>
</head>
<body>
<div id="myDiv">点我</div>
</body>
</html>
Window - true
Document - true
Html - true
Body - true
Div - true
Div - false
Div - click
6-闭包
闭包:简单理解为,函数中嵌套函数,可以访问其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包可理解成“定义在一个函数内部的函数”。 在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 现在是一个闭包
bar(10);
ps:当你return的是内部function时,就是一个闭包。内部function会close-over外部function的变量直到内部function结束。
function closureExample(objID, text, timedelay) { //非return闭包
setTimeout(function() {
document.getElementById(objID).innerHTML = text;
}, timedelay);
}
closureExample(‘myDiv’, ‘Closure is created’, 500);
ps:如果一个函数访问了它的外部变量,那么它就是一个闭包
父对象的所有变量,对子对象都是可见的,反之则不成立。f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了。
function f1(){
n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
接着,
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
console.log(n);
}
return f2;
}
var result=f1();
result(); // 999,证明函数外部可以读取函数内部的变量
nAdd();
result(); // 1000,证明变量始终保持在内存
函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。即所谓“闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量。这使得只要目标对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return name;
};
}
};
console.log(object.getNameFunc()()); //The Window
备注:下面这个并不是闭包:
function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp));
}
bar(10);
}
foo(2)
闭包的作用:可以读取函数内部的变量;同时让这些变量值始终保持在内存中。
通过保护变量的方式,实现js属性和方法的私有化。
简单来说,Javascript闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些键值对是不会随上一级函数的执行完成而销毁。周爱民说得更清楚,闭包就是“属性表”,闭包就是一个数据块,闭包就是一个存放着“Name=Value”的对照表。就这么简单。但是,必须强调,闭包是运行期概念,一个函数实例。Javascript闭包的实现,通常是在函数内部再定义函数,让该内部函数使用上一级函数的变量或全局变量。
with(obj){
//这里是对象闭包
}(function(){
//函数闭包
})()try{
//...
} catch(e) {
//catch闭包 但IE里不行
}
Ps:函数内部可以直接读取外部变量;而函数外部无法直接读取函数内部的局部变量,(JavaScript的链式作用域结构)但是借助闭包可以实现函数外部读取函数内部的变量。
http://kb.cnblogs.com/page/110782/
http://m.blog.csdn.net/article/details?id=7355794
7-作用域
变量的作用域有两种:全局变量和局部变量。
Ps:函数内部声明变量的时候需要使用var,否则就变成全局变量了。
最外层函数和在最外层函数外面定义的变量拥有全局作用域;所有末定义直接赋值的变量自动声明为拥有全局作用域;所有window对象的属性拥有全局作用域。
局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,
8-This
参考http://www.jianshu.com/p/d647aa6d1ae6
http://www.cnblogs.com/pssp/p/5216085.html
this的指向,是在函数被调用的时候确定的,即执行上下文被创建时候确定的。
- 全局对象中的this指向其本身;
- 函数中的this:
在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的th is指向该对象。如果函数独立调用,那么该函数内部的this,则指向undefined。但是在非严格模式中,当this指向undefined时,它会被自动指向全局对象。
//函数中this
/*
//demo
var a = 20;
function fn() {
console.log(this.a);
}
fn();//undefined
*/
/*
// demo02
var a = 20;
function fn() {
function foo() {
console.log(this.a);
}
foo();
}
fn();//undefined*/
// demo03
var a = 20;
var obj = {
a: 10,
c: this.a + 20,
fn: function () {
return this.a;
}
}
console.log(obj.c);//NaN
console.log(obj.fn());//10
当obj在全局声明时,无论obj.c
在什么地方调用,这里的this都指向全局对象,而当obj在函数环境中声明时,这个this指向undefined,在非严格模式下,会自动转向全局对象。
var a = 20;
var foo = {
a: 10,
getA: function () {
return this.a;
}
}
console.log(foo.getA()); // 10
var test = foo.getA;
console.log(test()); // undefined,非严格模式下为20
var a = 20;
function getA() {
return this.a;
}
var foo = {
a: 10,
getA: getA
}
console.log(foo.getA()); // 10
function foo() {
console.log(this.a)
}
function active(fn) {
fn(); // 真实调用者,为独立调用
}
var a = 20;
var obj = {
a: 10,
getA: foo
}
active(obj.getA);//undefined
- 使用call、apply显示指定this:
其第一个参数为this将要指定的对象。后面的参数,除了参数不同,功能相同,其中,call是一个参数一个参数的形式传递,而apply直接以数组形式传递。
function fn() {
console.log(this.a);
}
var obj = {
a: 20
}
fn.call(obj);//20
function fn(num1, num2) {
console.log(this.a + num1 + num2);
}
var obj = {
a: 20
}
fn.call(obj, 100, 10); // 130
fn.apply(obj, [20, 10]); // 50
构造函数与原型方法上的this
function Person(name, age) {
// 这里的this指向了谁? p1
this.name = name;
this.age = age;
}
Person.prototype.getName = function() {
// 这里的this又指向了谁? p1
return this.name;
}
var p1 = new Person(‘Nick‘, 20);
p1.getName();
- 通过new操作符调用构造函数,会经历以下4个阶段。
创建一个新的对象=》将构造函数的this指向这个新对象=》指向构造函数的代码,为这个对象添加属性,方法等=》返回新对象。
因此,当new操作符调用构造函数时,this其实指向的是这个新创建的对象,最后又将新的对象返回出来,被实例对象p1接收。因此,我们可以说,这个时候,构造函数的this,指向了新的实例对象,p1。而原型方法上的this,根据对函数中this的定义,p1.getName()中的getName为调用者,他被p1所拥有,因此getName中的this,也是指向了p1。
Ps:若一个函数中有this,且其没有被上一级的对象调用,则this指向window;若一个函数中存在this,且这个this被上一级对象调用,则this指向其上一级对象;若一个函数中存在this,且该函数中包含多个对象,即使该函数被最外层对象调用,this也指向其上一级对象。this指向最后调用它的对象。当方法碰到return时,若返回值是一个对象,则this指向那个返回的对象,否则仍指向其函数实例。
8-Js函数
由事件触发的或者当其被调用而执行的可重用的代码块。
函数调用方式:方法调用、正常函数调用、构造器函数调用、Apply/call
9-Js类型
基础数据类型:Undefined、Null、Boolean、Number、String
引用数据类型:Object、Array、
引用数据类型的值为保存在堆内存中的对象。
10-Call、apply、bind
将类数组对象转换为真实数组:
function exam(a, b, c, d, e) {
// 先看看函数的自带属性 arguments 什么是样子的
console.log(arguments);
// 使用call/apply将arguments转换为数组, 返回结果为数组,arguments自身不会改变
var arg = [].slice.call(arguments);
console.log(arg);
}
exam(2, 8, 9, 10, 3);
// result:
// { ‘0‘: 2, ‘1‘: 8, ‘2‘: 9, ‘3‘: 10, ‘4‘: 3 }
// [ 2, 8, 9, 10, 3 ]
// 也常常使用该方法将DOM中的nodelist转换为数组
// [].slice.call( document.getElementsByTagName(‘li‘) );
修改this指向:
var foo = {
name: ‘joker‘,
showName: function() {
console.log(this.name);
}
}
var bar = {
name: ‘rose‘
}
foo.showName.call(bar);//rose
实现继承:
// 定义父级的构造函数
var Person = function(name, age) {
this.name = name;
this.age = age;
this.gender = [‘man‘, ‘woman‘];
}
// 定义子类的构造函数
var Student = function(name, age, high) {
// use call
Person.call(this, name, age);
this.high = high;
}
Student.prototype.message = function() {
console.log(‘name:‘+this.name+‘, age:‘+this.age+‘, high:‘+this.high+‘, gender:‘+this.gender[0]+‘;‘);
}
new Student(‘xiaom‘, 12, ‘150cm‘).message();
// name:xiaom, age:12, high:150cm, gender:man;
在Student的构造函数中,借助call方法,将父级的构造函数执行了一次,相当于将Person中的代码,在Sudent中复制了一份,其中的this指向为从Student中new出来的实例对象。call方法保证了this的指向正确,因此就相当于实现了基层
在向其他执行上下文的传递中,确保this的指向保持不变
function bind(fn, obj) {
return function() {
return fn.apply(obj, arguments);
}
}
var obj = {
a: 20,
getA: function() {
setTimeout(bind(function() {
console.log(this.a)
}, this), 1000)
}
}
obj.getA();//20
var obj = {
a: 20,
getA: function() {
setTimeout(function() {
console.log(this.a)
}.bind(this), 1000)
}
}
obj.getA(); //20
var a = {
user:"哈哈",
fn:function(e,d,f){
console.log(this.user); //哈哈
console.log(e,d,f); //10 1 2
}
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
ps:call/apply可以改变this的指向对象,并立即执行该函数;bind会生成一个新的函数,让对应函数想什么时候调用就什么时候调用,且可以将函数在执行的时候添加。
参考:http://www.cnblogs.com/pssp/p/5215621.html
11-匿名函数、立即执行函数
匿名函数:没有名称标识符,通过匿名函数表达式自我执行
立即执行函数:函数被包含在一对()括号内部,成为一个表达式,通过在末尾加上另一个()括号可以立即执行该函数。如(function( ){ })( );还有一种方式是将最后用来调用的括号移到用来包装的括号中,如(function( ){ }( ))
12-Null、undefined、
Null表示无的对象,转化为数值时为0;undefined表示无的原始值,转化为数值时为NaN。
Null表示没有对象,即该处不应该有值。用法:作为函数的参数,表示该函数的参数不是对象;作为对象原型链的终点。
Undefined表示缺少值,就是此处应该有一个值,但是还没有给定该值。用法:已经声明的变量但是还没有赋值;调用函数时应该提供的参数没有提供;对象没有赋值的属性;函数没有返回值时,默认返回undefined。
13-coding
(1)var foo = 10 + ‘20‘;
console.log(foo);//1020
(2)console.log("i‘m a lasagna hog".split("").reverse().join(""));//goh angasal a m‘i
(3)
var foo = "Hello";
(function() {
var bar = " World";
console.log(foo + bar);Hello World
})();
console.log(foo + bar);//报错,bar为局部变量
(4)
var foo = [];
foo.push(1);
console.log(foo);[1]
foo.push(2);
console.log(foo);[1,2]
(5)
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
console.log(foo);//{n:2}
console.log(x);//报错
(6)
console.log(‘one‘);
setTimeout(function() {
console.log(‘two‘);
}, 0);
console.log(‘three‘);
//one
//Three
// two
(7)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>闭包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function() {
alert(i);
}
}
}
</script>
</head>
<body onload="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html>
上述代码,点击每一个p元素时,都弹出5.循环时响应函数未能保存对应的i值,而是最后一次i++的值。
更改1:将i保存在匿名函数自身
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>闭包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
(pAry[i].onclick=function(){
alert(arguments.callee.i);
}).i=i;
}
}
</script>
<body onl oad="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html> //点击哪一个元素对应弹出i的值
更改2:加一层闭包,i以函数参数形式传递给内层函数
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>闭包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
(function(arg) {
alert(arg);
})(i);//调用时参数
}
}
</script>
<body onl oad="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html>
更改3:加一层闭包,返回一个函数作为响应事件
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>闭包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick=function(arg){
return function(){
alert(arg);
}
}(i);
}
}
</script>
<body onl oad="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html>
更改4:用Function实现,每产生一个函数实例就会产生一个闭包
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>闭包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick=new Function("alert("+i+");");
//new一个函数实例
}
}
</script>
<body onl oad="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html>
更改5:用Function实现
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>闭包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick=Function(‘alert(‘+i+‘)‘);
}
}
</script>
<body onl oad="init();">
<p>产品 0</p>
<p>产品 1</p>
<p>产品 2</p>
<p>产品 3</p>
<p>产品 4</p>
</body>
</html>
http://m.blog.csdn.net/article/details?id=7355794
(8)
var timer = setTimeout(function() {
console.log(‘setTimeout actions.‘);
}, 0);
console.log(‘other actions.‘);
//输出 other actions.
// setTimeout actions.
(9)
14-Js map
Map对象:键/值对的集合
mapObj=new Map();
Map属性:构造函数(指定创建映射的函数)、Prototype-原型(为映射返回对原型的引用)、size(返回映射中的元素数)
Map对象方法:
clear:从映射中移除所有元素。mapObj.clear();
delete:从映射中移除指定的元素。mapObj.delete(key);key需要移除的元素的键
forEach:对映射中的每个元素执行指定操作. mapObj.forEach(callbackfn[, thisArg])
get:返回映射中的指定元素。 mapObj.get(key)
has:如果映射包含指定元素,则返回true。mapObj.has(key)
set:添加一个新建元素到映射。mapObj.set(key, value)
toString:返回映射的字符串表示形式。mapObj.toString()
valueOf:返回指定对象的原始值。mapObj.valueOf()
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。map() 方法按照原始数组元素顺序依次处理元素。
array.map(function(currentValue,index,arr), thisValue)
var numbers = [4, 9, 16, 25];
function myFunction() {
x = document.getElementById("demo")
x.innerHTML = numbers.map(Math.sqrt);
}
eg.
var m = new Map();
m.set(1, "black");
m.set(2, "red");
m.set("colors", 2);
m.set({x:1}, 3);
m.delete(1);
m.forEach(function (item, key, mapObj) {
document.write(item.toString() + "<br />");
});//forEach用来遍历数组中的每一项,无返回值
document.write("<br />");
document.write(m.get(2));
document.write(m.has(2));//true
// Output:
// black
// red
// 2
// 3
// red
map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。
var map = Array.prototype.map
var a = map.call("Hello World", function(x) { return x.charCodeAt(0); })
// a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
["1", "2", "3"].map(parseInt);
//Ouputs: 1
console.log(parseInt("1", 0));
//Ouputs: 1
console.log(parseInt("1", undefined));
//Ouputs: NaN
console.log(parseInt("2", 1));
//Ouputs: NaN
console.log(parseInt("3", 2));//2进制中不可能存在数字3
// 但实际的结果是 [1, NaN, NaN] // 通常使用parseInt时,只需要传递一个参数.但实际上,parseInt可以有两个参数.第二个参数是进制数. // map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素, 元素索引, 原数组本身.// 当我们使用map方法的时候,callback函数接收三个参数,而parseInt最多只能接收两个参数,以至于第三个参数被直接舍弃,第三个参数parseInt会忽视, 但第二个参数不会,也就是说,parseInt把传过来的索引值当成进制数来使用.从而返回了NaN.
更改1:
function returnInt(element){
return parseInt(element,10);
}
["1", "2", "3"].map(returnInt); // 返回[1,2,3]
更改2:
var result = ["1", "2", "3"].map(function(val) {
return parseInt(val, 10);
});
//Outputs: [1, 2, 3]
console.log(result);
map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。array.map(callback[, thisArg]); callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。如果 thisArg 参数有值,则每次 callback 函数被调用的时候,this 都会指向 thisArg 参数上的这个对象。如果省略了 thisArg 参数,或者赋值为 null 或 undefined,则 this 指向全局对象 。map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)。
Map和forEach,都是用来遍历数组中的每一项值,区别:map的回调函数支持rerurn返回值,return啥则相当于把数组中的这一项变为啥,但并不影响原数组,可以理解为克隆的这一份改变了;forEach和map都支持第二个参数,即把匿名回调函数中的this进行修改。
forEach:
var ary = [12,23,24,42,1];
var res = ary.forEach(function (item,index,input) {
input[index] = item*10;
})
console.log(res);//-->undefined;
console.log(ary);//-->会对原来的数组产生改变;
map:
var ary = [12,23,24,42,1];
var res = ary.map(function (item,index,input) {
return item*10;
})
console.log(res);//-->[120,230,240,420,10];
console.log(ary);//-->[12,23,24,42,1];
var str="How are you How doing today?"
// document.write(str.split("o") + "<br />")
var arr = str.split(" ")
document.write(arr+"<br />");
var map = Array.prototype.map
for (var val in arr){
map[arr[val]] = 0
}
var total = 0;
for (var val in arr){
//document.write( arr[val] + "<br />")
map[arr[val]]++
total ++
}
for( var val in map){
document.write(val + " " + map[val] + "<br />")
}
document.write(total)
输出:
How,are,you,How,doing,today?
How 2
are 1
you 1
doing 1
today? 1
6
参考:http://www.jb51.net/article/56554.htm
前端知识小总结4