今天把前段时间看的Js总结了一下,可能时间的原因,毕竟在公司上班~
所以会持续更新。说说自己为什么学js,4个月前毕业的时候,面试的公司很多都会用Js.当时最擅长的就是document.getElement*,虽然感觉用js还行吧,简单开发还是可以的。总体希望自己可以得到很好的提升,
于是买了一本js高级程序设计,目前再翻第二遍,个人喜欢extjs,无意中看到ext江湖中Js部分讲的不错,就总结出来了。
希望我的总结能帮助刚刚接触js的朋友,同时方便以后自己复习。
js特性总结:
1.使用var 定义变量和不使用var的区别
不使用默认是全局的变量,使用var在定义的块中有效,拓展除外。
2. ==表示值相等,===表示除了值相等,类型必须也相同
3.|| 的特殊用法:穿越操作
var a=0;
var b=false;
var c={s:0};
var d=a||b||c.s||150;
alert(d);
//150
4.判断一个值的方式:!!两次使用!号,如果原值为一个非空,返回一个true,如果原值是一个空,false。
5.类型转换技巧:
+号,拼接
var a=[1,2,3];
alert(a+"");
//输出 1,2,3
6.delete运算符
var o={name:'zzg'}
alert(o.name);//zzg
delete o.name;
alert(o.name);//undefined
7.获取对象的值
var o={age:25};
alert(o.age);
alert(o[age]);
8.()运算符
(function(){alert('auto')})();//auto
一个让函数可以运行起来的运算符。
还可以:
(a=3,b=4,c=5);
上面的表达式是从左向右依次运算的,并且最后返回最右面的结果。
alert((a=3,b=4,c=5));//5
9.eval()
不多解释,学js基本都知道的函数,不是一般强大。
eval('var a=function (){alert("sss");}');
a();//sss
将字符串转换成一个函数,也可以将字符串转换成对象a={name:'zzg'}等,反正就是强大
10.三目运算符
代码简洁
11.for(var t in obj){} //可以列举一个对象所有的属性
12.with() 提升作用域 //少用
13.js中获取标签的方法:
document.getElementById();
document.getElementByName();//返回的是一个数组
document.getElementByTagName();//返回的是一个数组
obj.appendChild();//添加到obj末尾
obj.insertBefore();//插入到obj前面
obj.parentNode().removeChild(obj);//删掉自己
14.修改样式
obj.style.height=10;
15.记得js中获取一个函数的参数除了可以显示的定义使用,还可以如下:
var fun=function(){
alert(arguments[0]);
}
fun('zzg');//zzg
知道内部有一个属性arguments参数数组
15.使用函数提升作用域
var out=function(){
var name='zzg';
function getName(){
return name;
}
return getName;
}
var gName=out();//返回一个函数的地址
var na=gName();//调用函数,函数返回name
alert(na);//输出
特点:name属性是定义在out中的局部变量,也就是说执行完out()的时候就应该销毁了,是吗?
16 函数调用call(),apply()
var name='张三丰';
var fun=function(age){
alert(this.name+'---'+age);
}
fun.call({name:'zzg'},24);//zzg
fun.apply({name:'wqq'},[22]);//wqq
fun.call(this,100);//输出多少?自己演示
两个函数都接收2个参数,一个是该函数要作用的域,
第二个call传入的是一个....的参数,apply传入的是一个数组
17 js函数
①是一个数据
var fun=function(age){
alert("zzg");
}
alert(fun);//输出就是函数体
②是对象
var fun=new Function('alert("sss");');
alert(fun instanceof Object);//true
fun();//sss
18 函数实例中的属性
arguments,length,caller,callee,prototype
var fun=function(var1,var2){}
alert(fun.length);//2
//别心里不愿意接受现实,它就是可以这样()调用,然后就是一个对象,有它自己的属性
var fun=function(var1,var2){
var str="";
for(var i=0;i<arguments.length;i++){
str+=arguments[i];
}
alert(str);
}
fun(1,2);//12
var str="";
var fun=function(n){
str+=n;
if(n>0){
arguments.callee(n-1);//fun(n-1);
}
}
fun(3);
alert(str);//3210 calle指向函数本身,这里是一个递归调用
caller主要是用来展示调用者
function a(){
alert(a.caller);
}
function b(){
a();
}
b();
19.setTimeout,setIntervel (函数,时间)
setTimeout:等待规定的时间执行然后退出
setIntervel:等待规定的时间执行然后继续等待规定的时间执行...
20.prototype属性
函数的的属性prototype指向函数原型,函数原型的构造函数执行函数(不明白去看js高级程序设计-原型链)
默认是按上面的指向的,如果你fn.prototype={};
后面new出的对象就无法访问到函数原型的数据了,此时的prototype指向{}
关于它的使用:
function A(){
}
A.prototype.name="zzg";
var a=new A();
alert(a.name);//zzg
var b=new A();
alert(b.name);//zzg
下面是给name赋值
function A(name){
this.name=name;
}
A.prototype.name="zzg";
var a=new A("hsh");
alert(a.name);//hsh
var b=new A("wqq");
alert(b.name);//wqq
这里的情况就是因为prototype属性指向的原型对象对所有的对象是共享的
如果你想让自己的属性不共享,可以用上面的方式,函数也类似
当然你使用继承组合方式的化,就可以实现,将父类的方法继承,属性用自己的,
具体自己查一下,这里只是提到然后总结。
当使用继承的时候,对于同一个属性,它的查找方式就是:首先从自己的对象中找该属性,
然后从父类找,最后从Prototype中找(当然这就是你最倒霉的情况下在自己和父类中都找不到)。
利用prototype就可以对原生的js对象进行扩展和扩从。比如extjs,jquery easyui
21.垃圾回收
1.标记清除(使用的去掉标记,删除有标记的)
2.引用计数
总结:
1.离开作用域的变量和函数会标记为可回收,垃圾收集期间会收集。
2.标记清除是目前最主流才垃圾回收机制的算法。
3.引用计数作为另一种垃圾回收机制,存在对象相互引用的情况无法回收,所以非主流了。
4.为了有效的回收垃圾,对于全局变量和函数和循环引用,使用完最好=null;
22执行环境的总结:
1.执行环境分为全局执行环境和函数执行环境
2.每次进入一个执行环境都会创建一个用于搜索变量和函数的作用域链
3.函数的局部环境不仅可以访问函数作用域中的变量和函数,还可以访问父(上层)环境的作用域,一致到全局作用域
4.全局环境只能访问全局作用域中的函数和变量
5.执行环境对垃圾回收机制非常有帮助。
23.数组的一些方法:
var arr=['1','2','3'];
var arr2=arr.concat(['2232','12121212']);
alert(arr2);//1,2,3,2232,12121212
var arr=['1','2','3'];
var arr2=arr.slice(1,3);
alert(arr2);//2,3
//splice充当删除
var arr=['1','2','3'];
var arr3=arr.splice(1,1);//从1开始删除1项
alert(arr);//1,3 原数组剩下的项
alert(arr3);//2删除的项
//splice充当插入
var arr=['1','2','3'];
var arr3=arr.splice(1,0,'55','66');//从1开始插入2项 1表示插入的位置,0表示从插入的位置开始删除几项这里是替换删除0项
alert(arr);//1,55,66,2,3
alert(arr3);//空白
//splice充当替换
var arr3=arr.splice(1,2,'55','66');//从1开始替换1项 1表示插入的位置,2表示要替换的位置开始删除几项这里是替换删除2项
alert(arr);//1,55,66
alert(arr3)//2,3
//every()方法 迭代数组 每一项返回true,才会返回true
var arr=['1','2','3','4'];
arr.every(function(item,index,arr){
alert(item);
alert(index);
alert(arr);
});
//some()和every方法极为相似,区别就是some方法只要有一个返回ture就是true
var arr=['1','2','3','4'];
var bool=arr.some(function(item,index,arr){
return item>=4;
});
alert(bool);//ture
//filter() 返回给定条件的数组
var arr=['1','2','3','4'];
var bool=arr.filter(function(item,index,arr){
return item>2;
});
alert(bool);//3,4
//map 返回一个计算结果 比如item*2 就会返回一个[2,4,6,8]
var arr=['1','2','3','4'];
var bool=arr.map(function(item,index,arr){
return item>2;
});
alert(bool);//false,false,true,true
//reduce 接收4个参数的函数,上一个值,本次值,索引和数组对象
var arr=['1','2','3','4'];
var result=arr.reduce(function(prev,cur,index,arr){
return prev+cur;//第一次的时候返回prev=1,cur=2
});
alert(result);//10
//reduceRight 接收4个参数的函数,上一个值,本次值,索引和数组对象,与reduce区别就是数组的遍历是从后向前的
var arr=['1','2','3','4'];
var result=arr.reduce(function(prev,cur,index,arr){
return prev+cur;//第一次的时候返回prev=4,cur=3
});
alert(result);//10
24.Date
Date.now();
25.正则表达式
//找到 bat 或者cat不区分大小写,找到第一个结束
new RegExp("[bc]at","i");
var reg=/[bc]at/i;
//i 不区分大小写
//g 全局环境
26.函数的caller属性
function out(){
inner();
}
function inner(){
test=arguments.callee.caller;//arguments.callee等于inner,inner.caller的意思就是找到调用inner的函数的引用,也就是out的引用
//inner.caller;//效果同上
alert(test);//输出out的函数体
test();//这样会调用out方法,需要注意的是,这样做需要适当的判断,,不然一致循环了,归了。
}
out();
27.函数的call()和apply方法
var age=56;
var local={age:12};
function getAge(arg){
alert(this.age);
alert(arg);
}
getAge("arg");//56,arg
getAge.call(this,"arg");//56,arg
getAge.apply(this,["arg"]);//56,arg
getAge.call(local,"arg");//12,arg
//不多解释
28.Boolean对象实例
var boole1=new Boolean(false);
alert(boole1&&true)//boole1是一个对象,转换成一个boolean值的时候只有在为null的时候才会转换成false,所以为true
var boole2=false;
alert(boole2&&true)//这个不用解释
29.编码
var uri='www.baidu.com/嘉禾.thml#123';
alert(encodeURI(uri));//www.baidu.com/%E5%98%89%E7%A6%BE.thml#123
alert(encodeURIComponent(uri));//www.baidu.com%2F%E5%98%89%E7%A6%BE.thml%23123
//一般第二个方法用比较多,因为像#这样的字符也会编码的。
//相对解码方法 decodeURI(uri),decodeURIComponent(uri)
30.Math对象
alert(Math.max(3,55,232,2323232,1));//直接用来比较
var arr=[3,7,32,56,11];//如何比较一个数组?
alert(Math.max.apply(Math,arr));//这样
//为什么这样可以?注意灵活运用特性
//调用max的apply方法,因为它是可以传入数组的,并且指定的对象是Math,所以就是可以了
Math.ceil(28.1);//29
Math.floor(27.6);//27
Math.round();//正常的四舍五入
31. prototype
function Person(){
this.age=23;
};
Person.prototype.age=12;
Person.prototype.name="zzg";
var person1=new Person();
alert(Person.prototype.constructor==Person);//true Person.prototype.constructor指向的的是Person
//alert(person1.prototype.constructor==Person);//这样是错误的,实例是获取不到的。
alert(Object.getPrototypeOf(person1).age);//12 通过Object.getPrototypeOf()方法可以获取一个实例的原型对象
alert(Object.keys(person1));//age
alert(Object.keys(Person.prototype));//age name 获取一个对象中可枚举的属性和方法
alert("name" in person1);//true in用来判断实例中是否存在该属性,包括实例本身的属性和原型中的属性
alert("run" in Person.prototype);//true
alert(person1.hasOwnProperty("name"));//false hasOwnProperty()实例方法,用来判断某个实例中是否存在某对象
//Person.prototype.age=12;
//Person.prototype.name="zzg";
上面这种一个属性一个属性的赋值,对于属性少的倒是还可以,但是对于属性多的,一次性赋值更为方便如下
Person.prototype={
age:12,
name:"zzg",
run:function(){
alert(this.name+"running");
}
}//这样做的结果就是Person.prototype.constructor==Person 为flase因为我们此时将prototype属性重新定义了,所以他的constructor不在执向原函数,指向Object
//如果真的很需要这个值,可以像下面这样赋值
Person.prototype={
constructor:Person
age:12,
name:"zzg",
run:function(){
alert(this.name+"running");
}
} //现在可以了~不过此时的constructor属性是可以被枚举到的,也就是你调用Object.keys()这样的属性是可见的,如果想让他和原始的一样可以像下面这样:
Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
});//如果你这样做了,就不用在上面的constructor:Person显示的设置了,而且Object.defineProperty()方法在低版本的浏览器可能不支持。
32组合继承
//组合继承
//特点 既能继承父类的方法,又可以实现函数的共享
function Person(){
this.name="zzg";
this.age=12;
}
Person.prototype.say=function(){
alert("Chinaese");
}
function Man(){
Person.call(this);
this.type="man";
}
Man.prototype=new Person();
Man.prototype.like=function(){
alert(this.name+"->"+this.type+" like it");
}
var man=new Man();
alert(man.name);//zzg
man.say();//Chinaese
man.like();//zzg->man like it
var man2=new Man();
man2.name="wxzhangzg";
man2.like();//wxzhangzg->man like it
javascript:
arguments :函数中传入的参数对象
window.onload 浏览器加载页面时加载
functionname.call({"":""})
functionname.apply({"":""});
如何把arguments转换成一个数组:
var arr=Array.prototype.slice.call(arguments);
setTimeout();
setInterval();
document.write("");
window.location=
this.location.reload() 页面刷新
后退<INPUT TYPE="button" οnclick=window.history.back() value=back>
前进<INPUT TYPE="button" οnclick=window.history.forward() value=forward>
刷新<INPUT TYPE="button" οnclick=document.location.reload() value=reload>
因为 document.all 是 IE 的特有属性,所以通常用这个方法来判断客户端是否是IE浏览器 ,document.all?1:0;
1例子:
var $=function(args){
return document.getElementById(args);}
function testthis(){
alert(this==window);
}
window.οnlοad=function(){
$("mybtton2").οnclick=testthis;
}
<button id="mybtton" οnclick="testthis();" >testthis</button>//true
<button id="mybtton2" >testthis</button>//false
第一种方式直接调用的是testthis()这个方法,所有this指向的就是this所在的对象,因为它的上级就是window,所有为true
第二种方式:通过获取button这个节点,然后调用节点的onclick事件,理所应当this属于buttion这个触发事件的对象
2.自定义事件:
var win=new Ext.Window({
title:"test",
width:100,
height:100,
listeners:{"show":function(){
this.fireEvent("test");//触发事件
}}
});
win.addEvents("test");//添加事件
win.on("test",function(){
alert("l love you");//监听事件
});
win.show();
ext事件的高级用法:
1.自定义事件
var win=new Ext.Window({
title:"test",
width:100,
height:100,
listeners:{"show":function(){
this.fireEvent("test");
}}
});
win.addEvents("test");
win.on("test",function(){
alert("l love you");
});
win.show();
添加一个自定义事件test,当win出现的时候show被触发,注册的test事件也就被触发了。
2.继承事件基类,完成自定义类
Ext.define('MyClass', {
extend: 'Ext.util.Observable',
constructor: function (config) {
this.codeName=config.name||"default";
this.codetitle=config.title||'no';
this.addEvents('test1','test2');
this.listeners=config.listeners;
this.callParent([config]); // 调用Ext.util.Observable的构造
//this.fireEvent('test1');
},
mymethod:function(){
alert("dddd");
}
});
var cla=new MyClass({
name:"testsafsadfa",
title:"ddddd",
listeners:{
'test1':function(){
this.mymethod();
}
}
});
alert(cla.codeName);
alert(cla.title);
cla.fireEvent('test1');
ext中数组操作工具:
1.clear(arr);核心思路:两次去非,对于 0,false,null,NaN,undefinde,空白字符都会过滤掉
2.var arr=['1','3','2'];
alert(arr.sort());
var s=arr.splice(0,2);//切割,0开始切割2个 输出 1,2 改变原数组的数据
//alert(s);
var s=arr.slice(0,1);//切割 0开始 输出 3 不改变原数组的数据
// alert(s);
json和js对象的相互转化
1.将一个js对象转换成一个字符串:Ext.encode(obj); 完整形式:Ext.JSON.encode()
var obj ={name:"aa",age:12};
var o=Ext.encode(obj);
alert(o);
});
2.将一个字符串转换成一个js对象 Ext.decode(str);完整形式:Ext.JSON.decode()
var str="{name:'zzg',age:25}";
var obj= Ext.decode(str);
alert(obj.name);
就像java中的深度拷贝 ,完全可以利用这两个方法完成,先把一个Js对象变成一个字符串,然后再把字符变成一个对象,就完成拷贝,需要注意的是如果js对象中存在相互包含的情况,需要注意,不要进行深度拷贝,否则就如死循环,就像java中利用bean转换json的情况,相互包含,需注意。