函数是原生对象
- 可以使用new完成对象的实例化。
- 此方式效率低下,不建议使用。
函数是一等公民
- 可以完成功能(C中的函数)
- 可以做为实参和返回值(当成数据,并轻松实现回调模式)
- 可以成为对象的成员(“方法”的概念)
- 可以使用new操作(自定义类型的概念,class的替代品)
- 有prototye的引用,并影响所有实例的原型引用
更灵活的方式
no overload
- 函数名称自身就是“指针”,重新定义仅为“覆盖”
- 未能匹配上的形参将以“undefined”形式出现
- 利用arguments可以实现’”重载”
Function is Data
- 函数可以作为实参传入
- 函数内部可以有函数,并且可以将这个内部函数返回
- 一次性函数
函数借用
- “Function对象”有两个方法(非继承得到),apply和call
- 可以实现Function对象调用时“指定this”的作用。
apply和call可以改变this的指向。
现在我们来看如下例子,了解一下this的指向,当我们在全局直接调用方法的时候,this其实指向的是global,如下:
global.name = "cc";
function fn1(age) {
console.log(this.name +'...'+ age);
}
fn1(12);
我们可以发现this.name打印的其实是global中的name。
然后我们再来看下面的例子:
global.name = "cc";
function fn1(age) {
console.log(this.name +'...'+ age);
}
let obj = {name : "aaa",say : fn1};
obj.say(12);
我们可以发现this指向的是调用该function的对象obj,打印的是obj中的name.
如果我们现在有一个新对象obj1,我们也想调用say这个function,但是在obj1中却没有这个function,该怎么做。
global.name = "cc";
function fn1(age) {
console.log(this.name +'...'+ age);
}
let obj = {name : "aaa",say : fn1};
obj.say(12);
let obj1 = {name: "bbb"};
如上所示,obj1中只有name,并没有say这个function,但如果我们obj1想调用say(),该怎么做。这个时候我们就可以使用call来改变this的指向。
global.name = "cc";
function fn1(age) {
console.log(this.name +'...'+ age);
}
let obj = {name : "aaa",say : fn1};
obj.say(12);
let obj1 = {name: "bbb"};
fn1.call(obj1,100);//fn1的this指向obj1
通过call(),我们可以将fn1中的this指向obj1,call()方法的第一个参数就是this指向的对象,后面的是调用的实参。
而apply()与call不同的则是第二个参数中,apply是一个数组。
fn1.call(obj1,100);//fn1的this指向obj1
fn1.apply(obj1,[100]);
我们还可以使用bind方法,永久改变this的指向。
let fn2 = fn1.bind(obj1);//fn2的this永远是obj1
fn2(30);
函数的内部属性(调用时产生)
- arguments, “类数组形式”的引用类型,表明传入的参数
- this,表示函数执行的“环境对象”
- arguments.callee,表示函数的“调用者”(注意:不同于this)
递归
- arguments.callee,指向当前函数的指针,在递归场合下,可以实现“函数名称与实现的解藕”
- 注意:“use strict”不能使用
函数的“静态”属性(编译期确定)
- length,形参表长度
- prototype,原型“指针”
- apply&call,“反射”调用方法,可以调用时改变“this”
- bind,生成“反射”调用方法,使用时传入”this”
闭包
- 概念:能访问其它函数作用域的“函数”
关于作用域链
有趣的“闭包”
- var compare=createComparisonFunction(“name”);
- compare指向的内部匿名函数,是一个可以访问其外部函数的函数!!!
- 它可在外部函数返回时,仍然访问外部函数的作用域!!!
- 这才是我们所关心的闭包!!
- compare=null,释放!
let os = [{id : 1,name : "aaa",age : 100},{id : 2,name : "bbb",age : 99}];
function compareatorFactory(pn) {
return function(a,b){
return (a[pn] > b[pn]) ? 1 : (a[pn] == b[pn]) ? 0 : -1;
}
}
let ss1 = os.sort(compareatorFactory("id"));
console.log(ss1);
let ss2 = os.sort(compareatorFactory("age"));
console.log(ss2);
打造有状态的“对象”
闭包只保留外部函数的最一个值
块级作用域
私有变量
- javascript没有私有成员概念