函数
函数是这样的一段javascript代码,它只定义一次,点可能被执行或调用任意次。
关键词解释
- 参数(行参:函数中定义的变量;实参:调用函数时传入的参数);
- 调用上下文:普通函数——this(对象调用,this则为方法上级的对象;直接调用,为window);箭头函数——this为当前作用域的顶级对象。
//exam 1
var obj ={
a:1,
fn:function(){
console.log(this.a)
}
}
var a = 2;
obj.fn() // 1
var m = obj.fn
m() // 2
//exam 2
var obj={
a:1,
b:2,
c:{
a:3,
fn:()=>{
console.log(this.a)
},
fn2:function(){
console.log(this.a)
}
}
}
var a =4
obj.c.fn() //4
obj.c.fn2() //3
浏览器解析的时候,二者都会发生变量提升(hoisting),会将a变量提升为undefined,aaa会被当成函数提升,当代码从第一行开始执行之后,a被覆盖成console.log(1);
PS:变量提升是浏览器编译器的行为。
- 函数表达式/函数声明式
//函数表达式
var a = function(){console.log(1)};
//函数声明式
function a(){console.log(2)};
a() // 1
- arguments(实参对象):是一个类数组对象,具有数字下标这样可通过数字访问他(数字下标),具有length属性,但并不是数组,不具备数组方法,例如pop,push;
//argument转换成数组
function arg2arr(){
//第一种
let arr = Array.prototype.slice.call(arguments)
//第二种
let arr2 = Array.from(arguments)
//第三种
let arr3 = [...arguments]
console.log(arr,arr2,arr3);
}
测试截图:
- 闭包:函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为“闭包”。
阮一峰老师的解释,恰当的形容了这句晦涩难懂的定义:获取函数内部变量的函数,称为闭包。
特点:
- 变量存贮在内存中,不会被浏览器垃圾策略清除;
- 获取内部变量;
- 存在内存泄漏的问题;
-
prototype属性:这个属性是指向一个对象的引用,这个对象称作“原型对象”。每一个函数都包含不同的原型对象。当将函数用作构造函数的时候,新创建的对象会从对象上继承属性。
-
call/aplly方法:看做是某个对象的方法,通过调用方法的形式来间接调用函数。
f.call(thisObj,arg1,arg2,arg3...)
f.apply(thisObj,[arg1,arg2,arg3...])
- bind方法:(ES5方法)将函数绑定至某个对象;
function add (x,y,z){
return x+y+z
}
var succ = add.bind({x:1},2)
succ(3);//6
//重写一个bind方法
Function.prototype.bind = function(thisTarget){
this.apply(thisTarget,[...arguments])
}
PS:犀牛书晦涩难懂的一段