函数
函数
函数:一个对象
函数声明
function sum(num1, num2){
return num1 + num2;
}
函数表达式定义函数
var sum = function(num1, num2){
return num1 + num2;
};
使用Function函数构造器时,可以接受收仍以数量的参数,但最后一个参数被看作函数体。
var sum=new Function('a','b','c=a+b;return c')
console.log(sum(1,2));// 3
函数名:指向函数对象的指针(引用)
var sum=function(a,b){
return a+b
}
var a=sum
console.log(a(1,2));//3
arguments 参数
函数定义时,规定的参数只是为了使用的时候方便一些,不是必须的
本质上是通过arguments对象访问参数的,它与数组类似(但不是Array的实例) 可以用[ ]访问元素
function def(a,b){
console.log(a);
console.log(arguments[3]);
}
def(1,2,3,4,5)
利用arguments.length遍历参数
function def(a,b){
for(let i =0;i<arguments.length;i++){
console.log(arguments[i]);
}
}
def(1,2,3,4,5)
函数命名参数和arguments的同步关系
修改对应的arguments,命名参数会被同步修改
function change(a,b){
arguments[1]=123
console.log(b);//123
}
change(1,2)
修改命名参数时,arguments也会被对应修改
function change(a,b){
b=123
console.log(arguments[1]);//123
}
change(1,2)
参数不存在时 ,赋值arguments,命名参数仍然是undefined
function change(a,b){
arguments[1]=123
console.log(b);//undefined
}
change(1)
利用arguments的callee属性 获取当前函数指针
var p=null;
function def(){
p=arguments.callee;
console.log('run');
}
def();//run
p();//run
配合递归使用,可以在不使用函数名调用自身
function def(now){
console.log(now);
if(now==10){
return
}
arguments.callee(now+1);//0 1 2 3 4 5 6 7 8 9 10
}
def(0)
caller属性
返回调用当前函数的对象
this 函数内部的特殊对象
在哪调用函数,this属于哪个域
window.ss=123
function def(){
console.log(this.ss);//123 this=window
}
function def2(){
function def3(){
this.name='zhangsan'//this仍然是window
console.log('def2',this.ss);
}
def3();
}
def();//123
def2();//def2 123
console.log(window.name)//张三
function Person(name,age){
this.name=name;
this.age=age
}
function getAge(){
return this.age;
}
var p=new Person('zhangsan',12)//一个新的域 this属于对象p
console.log(window.getAge());//undefined
console.log(getAge());//undefined
p.getAge=getAge//不能直接调用 p.getAge() 不存在该方法
console.log(p.getAge());//12
apply(),call()和bind()方法
使得在不同的域环境下调用函数
域环境取决于 xxx.function() 中的xxx 。
var p1={
fullName: function(){
return this.firstName+this.lastName;
},
getInf: function(city,flag){
return 'name:'+this.firstName+this.lastName+';city:'+city;
}
}
var p2={
firstName:'zhang',
lastName:'san',
city:'shanghai'
}
var res=p1.fullName.apply(p2)
console.log(res);//zhangsan
p2.fullName=p1.fullName;//引用的p1的函数fullName 但是作用域不同
res=p2.fullName();//作用域是p2
console.log(res);//zhangsan
var res2=p1.getInf.apply(p2,[p2.city,'1']);//必须将参数放到列表里
console.log(res2);//name:zhangsan;city:shanghai
var res3=p1.getInf.call(p2,p2.city,'1');//必须将参数放到列表里
console.log(res3);//name:zhangsan;city:shanghai
apply()
两个参数:
- 作用域
- 参数 数组或者 arguments
var p1={
funllNmae: function(){
return this.firstName+this.lastName;
},
getInf: function(city,flag){
console.log(flag);
return 'name:'+this.firstName+this.lastName+';city:'+city;
}
}
var p2={
firstName:'zhang',
lastName:'san',
city:'shanghai'
}
var res=p1.funllNmae.apply(p2)
console.log(res);//zhangsan
p2.funllNmae=p1.funlllNmae;
p2.funllNmae();//zhangsan
var res2=p1.getInf.apply(p2,[p2.city,'1']);//必须将参数放到列表里
console.log(res2);//name:zhangsan;city:shanghai
console.log(res3);//name:zhangsan;city:shanghai
call()
与apply不同点:参数需要逐个列出,不能放到数组里
var res3=p1.getInf.call(p2,p2.city,'2');//必须逐个列出所有参数
bind()
给函数绑定对象域 也能传递参数 (不能用数组传)
function Person(name,age,job){
console.log('test');
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
console.log(this.name);
}
}
var obj={};
var bindTest=Person.bind(obj,'lisi',18,'c');
bindTest()
console.log(obj);
//obj={name: 'lisi',age:18,job:'c',sayName:[Function (anonymous)]}
实现函数作用域的扩充
window.color='red'
var obj={color:'blue'}
function sayColor(){
console.log(this.color);
}
sayColor()//red
sayColor.apply(obj)//blue
按值传递
例1:
function change(a){
a+=1
}
let a=1;
change(a);
console.log(a);//a的值仍是1
例2:
function Person(name,age){
this.name=name;
this.age=age;
}
//构造函数
function change(person){
person.name="美丽传说";
person=new Person('阿甘正传',10);//此处开辟了新空间
}
var p=new Person("西西里",20);
console.log(p.name);//此处输出为西西里
change(p);
console.log(p.name);//此处输出为美丽传说 不是 阿甘正传
当参数是对象时,传递的时对象的地址
person.name='美丽传说'
- 这是在原先对象的地址上修改属性值
person=new Person('阿甘正传',10)
- 此时person变量的地址发生了改变 指向了新的一个Person对象,与原先的对象没有关系了
函数重复声明
js不存在重载,不会动态匹配参数选择合适的函数,而是直接覆盖之前的同名函数
function def(a){
console.log(a);
}
function def(a,b){
console.log(a);
console.log(b);
}
def(1)
函数作用域
var a=0
function def1(){
var b=1;
function def2(){
var temp=b;//使用的是def1的b
b=a;//使用的是全局的a
a=temp;//使用的是def2的temp
}
def2()
//不可以使用def2的temp
}
def1()
//不可以使用b,temp
console.log(a);
不存在块级作用域
{}内的代码(代码块)不存在自己的作用域 ,作用域属于就近的函数或者全局
if(true){
var a=123; //属于全局变量
}
console.log(a);//123
函数表达式
函数名是引用(指针)

浙公网安备 33010602011771号