js学习笔记(一)
(一)函数
1.函数基本声明
function fun([参数1],[参数2],...){ 函数体; };
2.函数表达式,又叫函数字面量
var 变量=function([参数1],[参数2],...){ 函数体; };
3.函数构造法,需要new关键字词
var 变量=new function("参数1","参数2",...,函数体);
(二)对象、属性、数组等
1.
var o={ init:function(){ this.bind(); this.popup(); }, bind:function(){ return "你好"; }, popup:function(){ } }; //调用 o.init();
2.
var obj={}; obj.name="yaoyao"; obj['age']=23; console.log(obj['name']); console.log(obj['age']);
运行结果:yaoyao
23
ps: obj['name']等同于obj.name;两者区别:其中.是取自身属性,[]的里面可以是变量
3.
var obj={}; obj.name="yaoyao"; var nameN='name'; console.log(obj.nameN); console.log(obj.['nameN']); console.log(obj.[nameN]);//obj.[nameN]==obj.'name'
运行结果: undefined
undefined
yaoyao
4.删除属性;delete
//创建对象 var obj={}; obj.name="yaoyao"; //删除属性 delete obj.name; console.log(obj['name']);
运行结果:undefined
5.检测属性:in\hasOwnProperty
//创建对象 var obj={}; obj.name="yaoyao"; obj.age="undefined"; console.log(name in o);//检测属性是否属于当前对象,运算符in console.log(obj.hasOwnProperty('name'));//检测属性,运算符hasOwnProperty console.log(obj.name!=undefined);//检测属性 console.log(obj.age!=undefined);
运行结果: true
true
true
false
6.对象遍历、枚举属性
var o={//对象 x:1, y:2, z:3 }; //数组对象 var arr=[{x:1},{y:2},{z:3}]; for(a in o){ //a是变量,for in遍历出key console.log(a); } for(a in o){ //a是变量,for in遍历出value console.log(o[a]); } for(a in arr){ //a是变量,for in遍历出数组的索引 console.log(a); }
运行结果: x
y
z
1
2
3
0
1
2
7.数组循环
var arr=new Array(); arr=[1.6,5,3,5,33]; for(var i=0;i<arr.length;i++){//方法一,同步 } $.each(arr,function(index,item){//方法二,异步 })
8.序列化对象
ps: 深拷贝和浅拷贝的区别:深拷贝--类似双胞胎是两个独立的个体;浅拷贝--也就是引用,类似人和自己的影子对象数组都是浅拷贝。
ps: 数据交互的数据类型是json\xml字符串等,不能是对象,所以要想传送对象给服务器,需要序列化对象
var o={//对象 x:1, y:2, z:3 }; console.log(JSON.stringify(o));//对象转换成字符串--stringify console.log(typeof(JSON.stringify(o));//检测数据类型 var str=JSON.stringify(o);//把字符串转换成对象--parse console.log(typeof(JSON.parse(str));//JSON.parse(str)是深拷贝,类似双胞胎是两个独立的个体 (浅拷贝,也就是引用,类似人和自己的影子) var 02={ x:1, y:2, z:3 } var p=02; o2.x='111';//浅拷贝--引用,随之改变 console.log(p);
运行结果:
{"x":1,"y":2,"z":3}
string
object
{x:"111",y:2,z:3}
9.jq的ajax实例
$().ready(function () { $('#Login').click(function () { if ($('#username').val() == "" || $('#password').val() == "") { alert("用户名或密码不能为空!"); } else { $.ajax({ type: "POST", url: "Ajax/LoginHandler.ashx", data: "username=" + escape($('#username').val()) + "&password=" + escape($('#password').val()), beforeSend: function () { $("#loading").css("display", "block"); //点击登录后显示loading,隐藏输入框 $("#login").css("display", "none"); }, success: function (msg) { $("#loading").hide(); //隐藏loading if (msg == "success") { //parent.tb_remove(); parent.document.location.href = "admin.htm"; //如果登录成功则跳到管理界面 parent.tb_remove(); } if (msg == "fail") { alert("登录失败!"); } }, complete: function (data) { $("#loading").css("display", "none"); //点击登录后显示loading,隐藏输入框 $("#login").css("display", "block"); }, error: function (XMLHttpRequest, textStatus, thrownError) { } }); } }); });
10.判断arr数组对象里面是否有a---hasOwnProperty()
var arr=[{a:1,q:2,w:3},{d:1,r:2,c:3},{t:1,v:2,z:3}]; for(var i=0;i<arr.length;i++){ if(arr[i].hasOwnProperty('a')){//hasOwnProperty检测arr里main是否存在a console.log('yes'); break;//跳出当前循环 }else{ console.log('no'); } } $.each(arr.function(index,item){//此时的item是对象 if(item.hasOwnProperty('a')){ console.log('yes'); }else{ console.log('no'); } }) $.each(arr.function(index,item){//index是索引,此时的item是对象 if(item.a!=undefined){ console.log('yes'); }else{ console.log('no'); } })
运行结果: yes
yes
yes
(三)
1.原型--prototype(原型属性)
ps: 每个函数都有一个原型属性,在此原型属性中都有一个构造(constructor)函数,原型里面所共有的属性对象实例化也有。
function Person(){ }; Person.prototype.name='yaoyao'; Person.prototype.age=22; Person.prototype.action=function(){ console.log(this.name);//该this指当前实例化的对象,并不是原型 }; var person1=new Person(); person1.name='ben';//局部改变 var person2=new Person(); console.log(person2.age);//输出22 person1.__proto__.age=30;//通过__proto__改变age属性值,全局发生了变化,全局age就等于30 console.log(person1.name);//输出ben console.log(person2.name);//输出yaoyao console.log(person2.age);//输出30 console.log(person2);//输出:Person {} //__proto__: //action:?() //age:30 //name:"yaoyao" //constructor:? Person() //__proto__:Object console.log(Person.prototype.isPrototypeOf(person2));//输出true--检测当前实例person2是否属于该原型
2.构造函数和原型混合使用
(1)单纯使用构造函数时(当需要多个实例时就得new多个,会导致性能变差,内存溢出,所以需要使用原型)
//构造函数 function Aa(name,age){ this.name=name; this.age=age; this.action=function(){ return this.name; } }; var aa=new Aa('yaoyao',24); var bb=new Aa('sushan',24); console.log(aa.name);//输出yaoyao
(2)结合原型使用
//构造函数 function Aa(name,age,hobby){ this.name=name; this.age=age; this.hobby=hobby; }; //原型--不会因为实例化多个而变化 Aa.prototype.action=function(){ return '名字:'+this.name+',年龄:'+this.age+',爱好:'+this.hobby; }; var aa=new Aa('yaoyao',22,'唱歌'); var bb=new Aa('sushan',22,'跳舞'); console.log(bb.action());//输出--名字:sushan,年龄:22,爱好:跳舞
3.继承(先继承代沟最小的,依次往后)
(1)
function Anima(){} Anima.prototype.canDo=function(){ console.log("吃饭睡觉"); } function Cat(){} Cat.prototype=new Anima();//Cat继承Anima var cat=new Cat();//cat不仅拥有Anima里面的也拥有Cat里面的。 cat.canDo();//输出:吃饭睡觉 function Dog(){ this.canDo=function(){ console.log("吃狗粮"); } } Dog.prototype=new Anima();//Dog继承Anima var dog=new Dog(); dog.canDo();//输出:吃狗粮 cat1.canDo=function(){ console.log("猫吃鱼"); }; cat1.canDo();//输出:猫吃鱼
(2)
function Fa(){} Fa.prototype.name="fa"; Fa.prototype.age=23; function Fb(){}; Fb.prototype=new Fa(); Fb.prototype.name="fb"; Fb.prototype.age=24; function Fc(){}; Fc.prototype=new Fb(); Fc.prototype.name="fc"; var fc=new Fc(); console.log(fc.name);//输出fc fc.__proto__.name="fcc";//当前有name,改变当前 console.log(fc.name);//输出fcc console.log(fc.age);//输出24,改变前 fc.__proto__.age=25;//当前没有age,改变有age且代沟最小的父类Fb console.log(fc.age);//输出25 var fa=new Fa(); console.log(fa.age);//输出23,未被改变
4.有参数时的构造函数、原型、继承
function ParentType(name,age){ this.name=name; this.age=age; }; ParentType.prototype.getParentName=function(){ return this.name; } function SonType(){ ParentType.call(this,"yaoyao",23);//子类调用父类并传参,也可以使用apply(),作用都是在一个对象中调用另一个对象,区别在于所传参数call(this,name,age) apply(this,数组)。 this.name='yy'; }; SonType.prototype=new ParentType(); SonType.prototype.getSonName=function(){ return this.name; }; var aa=new SonType(); console.log(aa.name);//输出yy,如果实例化里有name先取实例化的 console.log(aa.age);//输出23
(四)作用域、闭包、递归、this关键字
1.作用域---当前所在区域,大可分为全局作用域、局部作用域
var x="123"; function aa(){ var a='1'; } function bb(){ var b='2'; console.log(b);//局部 console.log(x); //全局 } bb();//输出2 //123
2.闭包--内部和外部的函数联系桥梁
(1)
var x="s1"; function aa(){ var x="s2"; function son(){ var x="s3"; return x; }; return son(); }; console.log(aa());//输出:s3
(2)
var x="s1"; function aa(){ var x="s2"; return function son(){ var x="s3"; return x; }; }; console.log(aa());//输出: ? son(){ // var x="s3"; // return x; } console.log(aa()());//输出:s3
(3)
var fun=(function aa(){ var x="s2"; return function son(){ var x="s3"; return x; }; }()); console.log(fun());//输出s3
3.递归
(1)
function setup(x){ var i=0; return function(){ return x[i++]; } } var next=setup(['a','b','c']); console.log(next());//输出a console.log(next());//输出b console.log(next());//输出c
(2)
var fun= (function setup(x){ var i=0; return function(){ return x[i++]; } }(['a','b','c'])); console.log(fun());//输出a console.log(fun());//输出b console.log(fun());//输出c
4.this关键字---指当前调用函数的对象(函数的拥有者)
(1)函数中引用
var x=1; function test(){ this.x;//指向window.x }; test(); console.log(x);//输出1 ----------------- var x=1; function test(){ this.x=0;//指向window.x }; test(); console.log(x);//输出0 ----------------- var x=1; function test(){ this.x=0;//指向window.x }; function test1(){ this.x=1;//指向window.x }; test(); test1(); console.log(x);//输出1,根据执行顺序
(2)对象中调用
var o={};//创建对象 o.a=1; o.action=function(){ return this.a;//this指向o对象 } console.log(o.action());//输出1
对象中调用外部函数
function test(){ return this.a;//this指向o对象 } var o={};//创建对象 o.a=1; o.action=test; console.log(o.action());//输出1
--------------------
ps: 改变this指向,可以用call(),appy(),用于在当前对象中调用其他对象,两者区别在于传参不同,appy(this,[])传的是数组;call(this,age,name);
var a="111"; function test(){ return this.a;//this指向o对象 } var o={};//创建对象 o.a=1; o.b=test; console.log(o.b.call());//输出111,call()未传参,此时this指向window中的a console.log(o.b.call(o));//输出1,call()传o对象,此时this指向o中的a
(3)构造函数调用
function Fun(name,age){ this.name=name; this.age=age; } var fun=new Fun("yaoyao",24); console.log(fun.name);//输出yaoyao
(4)this指向----面试题
ps: 函数自执行 this指向window
var a=1; var o={ a:2, showA:function(){ this.a=3; (function(){//闭包,自调 console.log(this.a);//指向window中的a,输出1 })(); console.log(this.a);//指向当前对象的a,输出3 } } o.showA();
未完待续~~