函数进阶
定义函数的三种方式
函数声明
1 | fn();// 函数声明可以先调用,在声明 |
函数表达式
1 | var fn = function() { |
构造函数Function
1 | //函数也是对象,可以使用Function构造函数new出来 |
eval函数
eval的可以和new Function一样,执行字符串代码
注意:eval函数的功能非常的强大,但是实际使用的情况并不多。
eval形式的代码难以阅读
eval形式的代码无法打断点,因为本质还是还是一个字符串
在浏览器端执行任意的 JavaScript会带来潜在的安全风险,恶意的JavaScript代码可能会破坏应用,特别是在用它执行用户输入数据的情况下。否则,可能会有恶意用户输入威胁你的站点或应用程序安全的代码(即所谓的代码注入)
了解: xss攻击
函数的四种调用模式
根据函数内部this的指向不同,可以将函数的调用模式分成4种
- 函数调用模式
- 方法调用模式
- 构造函数调用模式
- 上下文调用模式(借用方法模式)
1 | 函数:当一个函数不是一个对象的属性时,称之为函数。 |
函数调用模式
如果一个函数不是一个对象的属性时,就是被当做一个函数来进行调用的。此时this指向了window
1 | function fn(){ |
方法调用模式
当一个函数被保存为对象的一个属性时,称之为一个方法。当一个方法被调用时,this被绑定到当前对象上。
1 | var obj = { |
构造函数调用模式
如果函数是通过new关键字进行调用的,此时this被绑定到创建出来的新对象上。
1 | function Person(){ |
总结:分析this的问题,主要就是区分函数的调用模式,看函数是怎么被调用的。
几种特殊的this指向
- 定时器中的this指向了window,因为定时器的function最终是由window来调用的。**可以使用箭头函数来避免这一问题 **
- 事件中的this指向的是当前的元素,在事件触发的时候,浏览器让当前元素调用了function。多数情况不能使用箭头函数
上下文调用模式
上下文调用模式也叫方法借用模式,分为apply与call
使用方法: 函数.call() 或者 函数.apply()
call方法
call方法可以调用一个函数,并且可以指定这个函数的this指向
1 | // 所有的函数都可以使用call进行调用 |
- 借用对象的方法
伪数组与数组
伪数组也叫类数组
- 伪数组其实就是一个对象,但是跟数组一样,伪数组也会有
length属性,也有0,1,2,3等属性。 - 伪数组并没有数组的方法,不能使用
push/pop等方法 - 伪数组可以跟数组一样进行遍历,通过下标操作。
- 常见的伪数组:
arguments、document.getElementsByTagName的返回值、jQuery对象
1 | var arrayLike = { |
- 伪数组借用数组的方法
1 | Array.prototype.push.call(arrLike, "赵六"); |
- 将伪数组转换成真数组
1 | var arr = Array.prototype.slice.call(arrLike); |
apply方法
apply()方法的作用和 call()方法类似,只有一个区别,就是apply()方法接受的是一个包含多个参数的数组。而call()方法接受的是若干个参数的列表
call和apply的使用场景:
- 如果参数比较少,使用call会更加简洁
- 如果参数存放在数组中,此时需要使用apply
bind方法
**bind()**方法创建一个新的函数, 可以绑定新的函数的this指向
1 | // 语法:函数.bind(thisArg) |