1.函数的产生方式:
1.自定义函数
function fn(){}; fn();
2.函数表达式
var fn=function(){}; fn();
3.new Function
var f1=new Function("num","for(var i=0;i<100;i++){sum+=i}return sum;");
2.函数的调用方式
1.自定义函数调用
function fn(){}; fn();
2.函数表达式
var fn=function(){}; fn();
3.构造函数调用
function Foo(){};
var fn=new Foo();
4.call,apply调用
function foo(){};
foo.call();
foo.apply();
函数的三种角色
1.普通函数
function (){};
2.构造函数
funtion To(){}; var t1=new To();
3.对象
function fo () {};
fo.info="蜘蛛";
fo.num=123;
fo.showName=function(){console.log(112)};
console.log(fo.info);
fo.showName();
function Person(name,age){
this.name=name;
this.age=age;
console.log(123);
};
Person();<普通函数>
Person.showAge=function(){
console.log(456);
}<函数作为对象>
Person.showAge();
var p1=new Person('Jerry',23);<作为构造函数>
3.函数作为参数
function fn(f){
var obj={
info:'Jerry';
};
f(obj);
};
var fo=function(date){
console.log(date.info);
}
fn(fo);
function foo(obj){
var data={
name:'kitty',
fn2:function(o){
console.log(o.info);
}
};
obj.fn(data);
};
var fn1=function(data){
console.log(data.name);
data.fn2(o);
};
var o={
info:'Jerry',
fn:fn1
};
foo(o);
function fn(o){
console.log(o.info);
var data={
name:''Kitty'
}
o.fn(data);
}
fn({
info:'Jerry',
fn:function(data){
console.log(data.name);
}
});
函数作为返回值;
最主要用于,排序问题上面;
var arr=[12,31,43,54];
var fn=function(a,b){
return a-b;
}
console.log(arr.sort(fn));
var arr0 = [{name:'a',age:12,salary:111},{name:'c',age:16,salary:123},{name:'g',age:13,salary:123},{name:'v',age:15,salary:345},{name:'p',age:19,salary:456}];<那么对象怎么排序:>
function fn(sortName){
return function(o1,o2){
var v1=o1[sortName];
var v2=o2[sortName];
if(v1>v2){return 1}else if(v1<v2){return -1}else{return 0};
}
}
var c1=arr0.sort(fn('age'));
(好好的理解一下上面,用函数字做返回值的案例);
作用域
作用域:全局作用域,函数作用域;
全局作用域
abc=123;
var info=456;
this.name="Jerry";
delete abc;
function foo(){
console.log(abc);
console.log(info);
console.log(name);
}
foo();
用var声明的关键字不能被delete删除,没有用var声明的全局变量可以被delete删除;
delete 删除对象的属性;
函数作用域
函数作用域中的属性只能在函数内部访问;
function fo(){
var abc=123;
console.log(abc);
}
fo();//123;
console.log(abc);//underfind;
javaScript中没有块级作用域的概念;
预解析
1.预解析的优先级:函数>参数>变量;
function fo(){
console.log(a);//undefind;
var a=123;
console.log(a);//123;
}
fo();
function fo(){
console.log(a);
var a=123;
function a(){
console.log(a);
}
console.log(a);
}
fo();
function foo(a){
var a=123;
console.log(a);//456;
}
foo(456);
function foo(a){
console.log(a);
var a=123;
function a(){
console.log(a);
}
console.log(a);
}
foo(456);
执行流程:foo这个函数调用然后传参,但是函数内部有a这个函数,函数作用域内预解析的时候,函数的优先级最高,然后变量a=123;重新给参数赋值,然后第二个console.log(a)的值就是123;
作用域链条
作用域链条:其实就是函数的嵌套,访问变量的规则就是从里到外,逐一访问的;
var a = 10;
function foo(){
var b = 20;
function fn1(){
var d = 40;
b = 21;
function fn2(){
var e = 12;
console.log(d);
}
}
fn1();
function fn(){
var c = 30;
console.log(a + b + c);
}
fn();
}
foo();
闭包
闭包:简单的说就是可以访问到函数内部的变量;
作用:1.访问函数内部的变量;2.缓存中间状态值;
副作用:造成空间的浪费;
缓存中间状态值;
var arr=[];
for(var i=0;i<3;i++){
arr[i]=(function(n){
var k=n;
return function(){
console.log(k);
}
})(i);
}
arr[0]/()/0;
arr[1]/()/1;
arr[2]/()/2;
自执行函数
var fn=(function (){
var num=0;
return function (){
console.log(num++);
}
})();
fn();
访问函数内部的变量;
function foo(a){
var money=10000;
return money*a;
}
var f1=foo(0.01);
投票点赞功能
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>投票点赞</title>
</head>
<body>
<script>
window.onload=function () {
var adiv=document.getElementById("div1");
var oinput=document.getElementsByTagName('input');
for(var i=0;i<oinput.length;i++){
oinput[i].onclick=(function(){
var num=0;
return function(){
alert(num++);
}
})();
}
};
第二种方法:
var adiv=document.getElementById("div1");
var oinput=document.getElementsByTagName('input');
for(var i=0;i<oinput.length;i++){
oinput[i].num=0;
oinput[i].onclick=function(){
alert(this.num++);
}
}
};
</script>
<div id="div1">
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
<input type="button" value="点击"/>
</div>
</body>
</html>
事件队列机制
js运行是单线程的;如果遇见一下事件(定时函数<延时到期>,事件函数<事件触发>,ajax函数<服务端返回数据>),事件会被放到事件队列当中,当这两个条件都满足了,才会触发事件队列中的事件,1.主线程已经空闲;2.特定的条件已经完成;