定义
匿名函数
匿名函数的基本形式为(function(){...})();
前面的括号包含函数体,后面的括号就是给匿名函数传递参数并立即执行。匿名函数将函数声明并直接赋值给一个事件或一个变量。
window.onload = function() { return 1 }
var fn = function(){ return 1 }
var fn2 = fn;
fn2.name; // fn
fn.name; // fn
上述fn记录的是函数的地址,而不是函数本身。同理,fn2 赋值的是 fn 的地址;虽是匿名函数,但是有 name。
具名函数
字面意思,具有名字的函数。
function f3(){ return 3; } // fn3的作用域是整个域
var fn5 = function fn4(){} // fn5的作用域只有在fn4这个函数本身中
箭头函数
var fn6 = i => i+1 // fn6(7)则返回7
var fn7 = (i, j) => i+j
var fn8 = (i, j) => {
console.log(1);
return i+j;
} // 若箭头函数加了{},则需要显式的return出来
词法作用域
var global1 = 1;
function fn1(param1) {
var local1 = 'local1';
var local2 = 'local2';
function fn2(param2) {
var local2 = 'inner local2';
console.log(local1); // local1 是 fn1 中的 local1
console.log(local2); // local2 是 fn2 本身的 local2
}
function fn3() {
var local2 = 'fn3 local2';
fn2(local2)
}
}
抽象语法树确定的是两个变量之间的关系,跟变量的值没有关系。上述 fn2
中的 local1
是 fn1
中的 local1
,但是值不一定是 local1
的值。比如:
var a = 1;
function b(){
console.log(a);
}
a=2; b(); // 此时打印出来的应该是2,但是b中的a是外面的a
call stack
call stack
是函数调用堆栈,就是程序运行时函数的调用过程,例如 A
函数调用了 B
函数,那么程序执行到 B
函数的时候,call stack
里就会有A函数,因为函数调用时需要把当前函数入栈,在 B
函数执行完毕后再从堆栈里将 A
函数取出,以让程序指针回到A函数继续运行。
调用堆栈是一个方法列表,按照调用顺序保存所有在运行期被调用的方法。
this & arguments
进入函数后,第一个要记录的是函数的地址,放到 call stack
中,第二个记录的是传入函数的参数(this,arguments
)。
chrome浏览器显示 window 为 Window。
function f() {
console.log(this); // window
console.log(arguments);
}
f.call(); // this: window; arguments: []
f.call({name: 'John'}); // this: {name: 'John'}; arguments: []
f.call({name: 'John'}, 1); // this: {name: 'John'}; arguments: [1]
f.call({name: 'John'}, 1, 2); // this: {name: 'John'}; arguments: [1,2]
综上,this
就是 call
的第一个参数,不传的话,this
为 window
(严格模式下,为 undefined
);后面的所有参数,都会放入 arguments
中包裹成一个数组。
f()
是阉割版的 f.call()
, f()
无法指定 this
,传入的参数都放入 arguments
。
person.sayHi()
等价于 person.sayHi.call(person)
。 fn()
等价于 fn.call()
call / apply
call
的第一个参数永远是 this
。 call
的第二个参数是1,2,3,4。 apply
的第二个参数是[1,2,3,4]。
因此,在 arguments
的长度不确定或太长的时候,使用 apply
。
bind
call
和 apply
直接调用函数,而 bind
则是返回一个新函数(并没有调用原来的函数),这个新函数会 call
原来的函数,call
的参数由你指定。
var view = {
element: $("#div1"),
bindEvents: function() {
var _this = this;
this.element.onclick = function() {
_this.onClick.call(_this)
}
},
onClick: function() {
this.element.addClass('active')
}
}
var view = {
element: $("#div1"),
bindEvents: function() {
this.element.onclick = this.onClick.bind(this)
},
onClick: function() {
this.element.addClass('active')
}
}
var view = {
element: $("#div1"),
bindEvents: function() {
this.onClick.bind = function(x, y, z) {
var oldFn = this // 也就是外面的 this.onClick
return function(){
oldFn.call(x, y, z)
}
}
this.element.onclick = this.onClick.bind(this)
},
onClick: function() {
this.element.addClass('active')
}
}
柯里化
把一个含有多个参数的函数中的其中一部分参数固定下来的叫做柯里化函数。
function sum(x, y) {
return x+y
}
// addOne 为 sum 的一个柯里化函数
function addOne(y) {
return sum(1, y)
}
高阶函数
在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
接受一个或多个函数作为输入 输出一个函数 不过它常常同时满足上述两个条件
array.sort(function(a, b){a-b}); // array.sort.call(array, fn)
array.forEach(function(){}); // array.forEach.call(array, fn)
array.map(function(){}); // array.map.call(array, fn)
array.filter(function(){}); // array.filter.call(array, fn)
array.reduce(function(){}); // array.reduce.call(array, fn)
标准的高阶函数可以将函数任意的组合。
// 求数组中偶数的和
var array = [3, 2, 1, 4, 5, 6, 7, 8];
var sum = 0;
for(var i=0; i<array.length; i++) {
if(array[i] % 2 === 0) {
sum += array[i]
}
}
// 可以使用如下高阶函数实现上述的功能
array.filter(function(n){return n%2===0}) // 2,4,6,8
.reduce(function(prev, next){return prev+next}, 0)
/** 函数形式做如下改造
* 其中 array为要过滤的数组;function(n){return n%2===0}为传入filter中的函数
* filter(array, function(n){return n%2===0})得到的结果为一个数组[2,4,6,8]
* 将上述filter得到的数组作为reduce的数组
* function(prev, next){return prev+next} 作为传入reduce中的函数
* reduce的初始值为0
**/
reduce(filter(array, function(n){return n%2===0}), function(prev, next){return prev+next}, 0)
// 同理,对数组中的奇数进行排序可以写成如下形式
sort(filter(array, function(n){n%2===1}), function(a, b){return a-b})
回调 callback
一个函数被当做参数就可以称这个函数为回调函数。
名词解释被当成参数的函数就是回调。 动词解释:调用这个回调。
回调跟异步没有任何关系。
构造函数
返回对象的函数就是构造函数。一般首字母大写。与普通函数相比,构造函数有如下特点:
- 用
new
关键字调用; - 函数内部可以使用
this
关键字,this
指向的是构造出的新对象; - 默认不用
return
返回值,默认会返回this
,也就是新的实例对象; - 函数命名一般首字母大写,与一般函数做区分。
箭头函数
箭头函数是没有 this
的,若希望函数内外的 this
相同时可以使用箭头函数
箭头函数不绑定 this
,绑定 arguments
。 箭头函数中的 this
永远没办法指定,可以将外面的 this
当做里面的 this
。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!