JS高级
函数的概念:
实际开发中,有的时候我们需要多次执行相同代码,或者在特定的时机执行某段代码,函数就可以解决这些问题。
函数可以包装一段代码,并且可以为这段代码取名,通过这个函数名可以达到多次调用效果。
函数的好处:
1.代码重复
2.降低变量的作用域
函数的执行时机:
函数中定义的内容是延迟执行的;
函数中的内容在函数调用的时候才执行;
函数的执行在页面加载前后执行是有顺序的;
在页面加载完之后执行:
使用jquery的方式:
$(function(){
})
使用js的方式:
window.onload = function(){
}
函数语法:
function 函数名([形参列表]){
函数体;
[return 返回值;]
}
函数的返回值:
1,如果函数中没有return语句,则函数的返回值为undefined;
2,如果函数中有return语句,函数的返回值为return语句返回的表达式值;
函数的形式和实参个数不同的问题:
1.形式个数=实参个数:函数是正常执行的;
2.形式个数>实参个数:函数是正常执行,没有被赋值的形参为undefined,所以执行的过程中可能会出现错误;
3.形式个数<实参个数:函数是正常执行,多余的实参会被忽略掉;
注意,在js中,变量的初始值都为undefined,不是null,JS中,null和undefined是不同的值;
问题:当形式个数<实参个数时,多余的实参是否传到了函数中?
arguments对象
1,不管函数是否申明了形参,在函数内部都可以直接使用arguments对象来直接引用当前调用函数传入的实参;
2,arguments只能在当前调用的函数内部使用;
3,arguments不是一个数组,是一个伪数组对象,类似jQuery对象,可以通过下标访问对象,并且有length属性;
问题:怎么证明arguments不是一个数组?
在java中判断对象的类型:
obj.getClass();
obj instanceof Type
在js中判断对象的类型:
obj instanceof Type
typeof obj
在js中,对象的类型分为两种:
基本类型/原生类型/简单类型:直接使用字面量赋值
var num = 1;
var str = "lucy";
对象类型:使用new关键字创建
var numObj = new Number(2);
var strObj = new String("will");
在java中判断对象的类型:
instanceof:只能判断引用类型,如果用在基本类型,拿到的结果都为false,无法获取需要的结果
typeof:只能作用在基本类型上,如果用在引用类型上,拿到的结果都为object,无法得知真实类型
函数的重载
在java中的重载:
两同一不同:两类中,方法名相同,参数列表不同
在js中没有重载的概念
最后声明的相同名称的函数会覆盖之前声明的函数
模拟jquery 的post方法
1,java中方法重载回顾:函数重载的目的就是用相同的函数名处理不同的业务;
1,不同的参数个数;
2,不同的参数类型;
2,JavaScript中的函数重载的例子:在jQuery中大量的函数使用了函数重载,通过传入不同的参数个数或者类型,达到不同的逻辑;
3,JavaScript中不直接支持重载,后面声明的方法会覆盖掉前面声明的方法;
4,JavaScript中可以使用代码的方式来模拟方法的重载(注意,模仿重载本质都是用一个方法来模拟多个方法)
1,不同的参数个数:可以直接使用arguments的长度来判断;
2,不同的参数类型:可以使用typeof或者instanceof来判断类型
1,Js中的函数为了更方便和灵活的使用,常常会很智能的去识别不同的实参组合类型,比如jQuery中大量的方法(post等);
2,解决参数的识别问题,就是在函数中主动的去识别和重新分配参数;
3,完成类似jQuery的post方法的参数使用
callee属性
1,在前台完成一个树状结构的匹配或者遍历;会使用到递归操作;
2,递归操作是需要在函数体中重新调用当前这个函数,如果直接写函数的名称,如果外层函数名修改了,内部的递归调用的函数名也要修改;
3,很多JS库,为了让函数体内部不需要依赖这个函数本身的名字,会使用arguments.callee引用当前的函数,使用argument.callee()来调用当前函数;
4,注意,因为arguments对象只能本函数体使用,所以callee也只在本函数体中有效;
需求:把如下的数据中的所有name替换成text属性
[
{
"id":1,
"name":"业务模块",
"children":[
{"id":11,"name":"品牌管理"},
{"id":12,"name":"仓库管理"}
]
},
{
"id":2,
"name":"系统模块",
"children":[
{"id":11,"name":"员工管理"},
{"id":12,"name":"部门管理"}
]
}
]
函数高级
回调函数:
1,在jQuery中经常会使用到回调函数,比如map函数,ajax相关函数,都有callback的存在;
2,什么是回调函数?回调函数就是在调用A函数的时候把B函数作为了参数传递给A函数,在A函数执行到某一个时机的时候,去调用B函数的方法,把B函数的业务加入到A函数的执行流程中,我们就说B函数是回调函数;
匿名函数:
1,如果一个function没有名字,那么这个function就叫做匿名函数;
2,匿名函数一般使用在两种模式里面;
1,和回调函数配合使用,直接把一个匿名函数作为回调函数传给主函数;
2,如果一个函数为了避免内容重复执行,只想执行一次,也可以使用匿名函数;
闭包的概念:在函数内部,使用函数外部声明的资源
js中的面向对象
1,在JavaScript中,一切都是对象;
2,在JavaScript中,包括两种类型,一种是基本类型,一种是引用类型;
1,相同点:两种类型都可以使用属性和调用方法;
2,不同点:
1,基本类型是直接通过赋值得到的,引用类型是通过new关键字创建的;;
2,基本类型使用typeof可以得到对应的基本类型,而对象通过typeof得到的都是object;
3,引用类型可以自己添加额外的属性和方法,但是基本类型不行;
操作对象的方式
创建对象的方式:
1,使用new关键字创建一个js对象:
var obj=new Object();
2,使用json的方式创建一个js对象;
var obj={};
添加属性的方式:
1,obj.attr=value;
2,obj['attrName']=value;
注意,第二种方式可以使用变量,第二种方式也可以添加一些特殊名字的属性;
给对象添加方法属性:
obj.someMethod=function(){
return this.attrName;
}
var attrName='attr';
obj[attrName]=value;//==obj['attr']=value;
访问属性的方式:
1,obj.attrName;
2,obj['attrName'];
同样,第二种也支持变量引用的方式访问属性;
调用对象的方法:
obj.someMethod();
删除属性:
1,obj.attr=undefined;obj['attr']=undefined;
注意,不是真正的删除属性;
2,使用delete关键字:
delete obj.attr;删除obj的attr属性;
同样,也可以使用delete obj['attr'];
对象的克隆
1,对象克隆就是创建一个新的对象,需要从一个目标对象中拷贝所有的属性;
2,在Js中,对象的本质是一堆属性的集合,可以使用for..in..关键字来遍历并拷贝属性值:
变量作用域
1,全局变量:在script中直接使用var声明的变量;所有的全局变量都是声明在window对象上的;
2,局部变量:在一个函数体内声明的变量;
3,变量的使用遵循就近原则;
this关键字
1,this关键字可以明确的指定作用域;
2,this关键字代表的是一个作用范围,谁调用这个函数,this指代的作用域就是谁;
call和apply都可以改变函数执行时候的this指向谁;
1,call(thisObject/scope,methodArguments);
2,apply(thisObject/scope,methodArgArray);
两个方法都可以临时的把一个方法的调用指派到指定的对象上,即把这个方法定义中所有的this指向thisObject;
两个方法的区别:call方法第二个参数是变参,代表方法调用的实参;apply方法第二个参数必须是实参的数组;
js中的类
创建类
为类添加方法
1,使用prototype为类添加方法
2,prototype是function上的一个特殊属性,在对象上没有,所以不可能使用this.prototype.showTime来为类添加方法;
3,prototype一般是用来给类添加统一的方法和属性的;
js对象的内部结构
1,__proto__:这个属性是Js对象上的隐藏属性,这个属性指向的是该对象对应类型的prototype对象;
2,js中对象分为两部分,
一部分是原生部分,原生部分是在构造函数中定义的,或者是直接通过对象.属性=value赋值的;
一部分是扩展部分,扩展部分的内容是通过类.prototype=value赋值的;
3,对于原生部分,直接使用obj.属性(方法)访问;
对于扩展部分,可以通过obj.__proto__.属性(方法)访问;
4,对于js的对象来说,在查询方法或者属性的时候,会沿着prototype链,按照就近原则访问,所以obj.__proto__.属性(方法)也可以直接通过obj.属性(方法)访问;
js的继承
1.简单继承
2.使用原型链继承的js对象内部结构
js中的跨域问题
js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同,都被当作是不同的域。
http://www.wolfcode.cn 自己的项目域名
发ajax请求另外一个项目的数据
http://www.wolfcode.cn:8080 端口不同
https://www.wolfcode.cn 协议不同
http://www.xxx.cn 域名不同
解决方案:
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不同域的服务器交互,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
1.创建<script>标签
2.定义好回调函数
3.后台返回的必须是js能解析的内容