Function范例
Function范例是JS的援用范例之一 经由历程Function范例建立Function对象
在JS中 函数也以对象的情势存在
每一个函数都是一个Function对象
console.log(Function instanceof Function) //true
console.log(Function instanceof Object) //true
console.log(Object instanceof Function) //true
组织函数
函数除了用函数定义语句和字面量表达式两种体式格局定义以外 还能够经由历程Funcion范例举行定义
函数的参数和函数体都是以字符串情势传递给Function的
var fun = new Function ('num','console.log(num)');
fun(100); //100
经由历程Function范例定义函数的效力远不如函数定义语句和字面量表达式的定义
定义函数的三种体式格局之间存在肯定差异
- 函数定义语句:实行时函数名被提早声明 不存在效力题目
- 字面量表达式:函数体牢固 没法动态实行 不存在效力题目
- Function范例定义 函数体是字符串 能够动态实行 效力较低
Function的apply()要领
apply要领能够挟制别的一个对象的要领,继续别的一个对象的属性.
Function.apply(obj,arguments)要领能吸收两个参数(可选):
obj:这个对象将替代Function类里this对象
arguments:这个参数是数组,它将作为参数传给Function
假如没有obj参数 那末Global对象被用作obj
//定义一个人类
function Person(name,age) {
this.name=name;
this.age=age;
}
//定义一个男子
function Man(name,age,hobby) {
Person.apply(this,arguments); //this代表的是man arguments是一个数组 也就是['Sicong',30,'撕逼']
this.hobby=hobby;
}
var man=new Man('Sicong',30,'撕逼');
console.log("name:"+man.name +"\n"+ "age:"+man.age +"\n"+"hobby:"+man.hobby); //name:SicongWang age:30 hobby:撕逼
//用Man去实行Person这个类内里的内容,在Person这个类内里存在this.name等语句,如许就将属性建立到了student对象内里
Function的call()要领
call要领与apply相似 只是第二个参数不是数组
//定义一个人类
function Person(name,age) {
this.name=name;
this.age=age;
}
//定义一个woman
function Woman(name,age,hobby) {
Person.call(this,name,age); //this代表的是woman
this.hobby=hobby;
}
var woman=new Woman('TimoFeng',18,'唱歌');
console.log("name:"+woman.name +"\n"+ "age:"+woman.age +"\n"+"hobby:"+woman.hobby); //name:TimoFeng age:18 hobby:唱歌
Function的bind()要领
bind要领与call和apply相似 第一个参数都是this要指向的对象 应用后续参数传参数
差别的是bind是返回对应的函数 能够稍后挪用;call和apply是立时挪用
var fn=function () {
console.log(this.x)
};
var foo={
x:3
};
fn(); //undefined
console.log(fn.bind(foo)); //ƒ () {
// console.log(this.x) }
// 此时this已指向了foo,然则用bind()要领并不会立时实行,而是建立一个函
// 数 假如要直接挪用的话 能够 bar.bind(foo)()
var result=fn.bind(foo);
result(); //3
递归
在函数内部,能够挪用其他函数。假如一个函数在内部挪用自身自身,这个函数就是递归函数
递归函数的长处是定义简朴,逻辑清楚 一切的递归函数都能够写成轮回的体式格局,但轮回的逻辑不如递归清楚
递归挪用的次数过量,会致使栈溢出 运用过深会构成死轮回
var num=function(x){
if(x == 1){
return 1;
} else{
return x*num(x-1);
}
}
console.log(num(5)) //120
/* 盘算历程为:
---> num(5)
---> 5 * num(4)
---> 5 * (4 * num(3))
---> 5 * (4 * (3 * num(2)))
---> 5 * (4 * (3 * (2 * num(1))))
---> 5 * (4 * (3 * (2 * 1))) 只要n=1时才特别处置惩罚
---> 5 * (4 * (3 * 2))
---> 5 * (4 * 6)
---> 5 * 24
---> 120
*/
回调函数
一个函数作为参数传给另一个函数 我们把另一个函数称为回调函数
浅显的说回调函数有3个特性: 1).你定义的 2).你没有挪用 3).但末了实行了
回调函数的长处:
- 能够在未定名的情况下传递函数 节约全局变量
- 将另一个函数挪用操纵托付给另一个函数
- 有助于提拔机能
$('btn').click(function(){ //click要领就是一个回调函数
alert('我是一个按钮')
})
自挪用函数
自挪用函数 声明完了,立时举行挪用,只能运用一次
(function(num1,num2){
console.log(num1+num2)
})(10,20) //30
作用域和作用域链
作用域: 一块代码地区, 在编写时就肯定, 不会再变化
作用域链: 多个嵌套的作用域构成的由内向外的构造, 用于查找变量
分为全局作用域和函数(部分)作用域
作用:
作用域: 断绝变量, 能够在差别作用域定义同名的变量不争执
作用域链: 查找变量
var num1=10; //全局变量
function fn1(){
var num2=20; //fn1作用域的部分变量
function fn2(){
var num3=30; //fn2作用域的部分变量
function fn3(){
var num4=40; //fn3作用域的部分变量
console.log(num1); //10
console.log(num2); //20
console.log(num3); //30
console.log(num4); //40
}
fn3();
console.log(num1); //10
console.log(num2); //20
console.log(num3); //30
console.log(num4); //num4 is not defined
}
fn2();
console.log(num1); //10
console.log(num2); //20
console.log(num3); //num3 is not defined
console.log(num4); //num4 is not defined
}
fn1()
闭包函数
当嵌套的内部函数援用了外部函数的变量时就产生了闭包
闭包实质是内部函数中的一个对象, 这个对象中包括援用的变量属性
作用:
延伸部分变量的生命周期
让函数外部能操纵内部的部分变量
防止污染全局定名空间
瑕玷:
变量占用内存的时候能够会太长
能够致使内存泄漏(占用的内存没有实时开释
内存泄漏积聚多了就轻易致使内存溢出)
function fn1() {
var a = 2;
function fn2() {
a++;
console.log(a); //3 4
}
return fn2;
}
var f = fn1();
f();
f();