JS中的函数也是对象,可以像普通的对象一样拥有属性和方法。函数的强大之处在于可以使用Function()构造函数创建新的函数对象。
属性
length属性
函数的length属性表示形参的个数。函数内部有一个arguments对象,arguments对象的length属性表示实参的个数。
function fn(a,b) {
console.log(arguments.length) // 3
console.log(fn.length) // 2
}
fn(1,2,3)
name属性
name属性很多浏览器很早就支持了,但到ES6中才被纳入标准,该属性返回函数的名字。IE浏览器不支持,返回undefined。
function fn(){}
console.log(fn.name) // 'fn'
var foo = function fn(){}
console.log(foo.name) // 'fn'
var foo = function (){}
console.log(foo.name) // 'foo'
Function()构造函数的实例,返回“anonymous”
(new Function).name // "anonymous"
bind()方法调用的函数,name属性值会加上“bound ”前缀
function foo() {};
foo.bind({}).name // "bound foo"
prototype属性
prototype属性指向一个原型对象的引用,每个函数都包含不同的原型对象。当函数作为构造函数调时,新创建的对象会从原型对象上继承属性。
function fn(){}
fn.prototype.name = 'hello'
var obj = new fn()
obj.name // 'hello'
方法
apply()和call()
apply()和call()这两个方法,它们的作用是一样的,都表示在特定的作用域中调用函数,它们都可以改变函数中this对象的值。
apply()方法接收来那两个参数:第一个表示函数运行的作用域(即函数中this指向谁);第二参数是一个数组,表示函数的参数,可以是arguments对象。
call()方法和apply()方法类似,唯一区别就是参数的形式不一样,call()接收的是参数列表,apply()接收的是数组。
把函数fn作为对象o的方法调用
fn.call(o)
fn.apply(o)
// 等价于
o.foo = fn // 将fn存储为o的临时方法
o.foo() // 调用方法
delete o.foo // 删除临时方法
示例1
window.color = 'red' // 全局变量
var o = {color: 'blue'}
function fn(){
console.log(this.color)
}
fn() // 'red'
fn.call(this) // 'red'
fn.call(window) // 'red'
fn.call(o) // 'blue'
示例2
function fn(color, name){
this.color = color
this.name = name
console.log(this.color, this.name)
}
fn.call({}, 'red', 'hello') // 'red' 'hello'
fn.apply({}, ['red', 'hello']) // 'red' 'hello'
严格模式下使用call()或apply()方法时,函数的this值始终指向第一个参数。非严格模式下如果第一个参数为null或undefined,this值会指向全局对象。
// 示例1
window.color = 'red'
function fn(){
'use strict'
console.log(this.color) // Cannot read property 'color' of null
}
fn.call(null)
// 示例2
window.color = 'red'
function fn(){
console.log(this.color) // 'red'
}
fn.call(null)
【应用一】 找出数组中最大元素
var arr = [1,10,3]
Math.max.apply(this, arr) // 10
【应用二】 类数组对象转换为数组
Array.prototype.slice.apply({0:1,length:1}) // [1]
bind()
bind()方法的作用和上面提到的call()方法类似,第一个参数都是改变函数中this的值,后续参数用列表形式表示。不同的是bind()方法调用后会返回一个新函数,call()方法没有返回值。以函数调用的方式调用这个新函数,会把原始函数当做对象的方法调用,传入新函数的参数会传给原始函数。
// 示例1
function fn(sex, age){ // 原始函数
return this.name + sex + age
}
var people = {name: 'li'}
var foo = fn.bind(people) //新函数
foo('男', 10) // 'li男10'
// 示例2
function fn(sex, age){
return this.name + sex + age
}
var people = {name: 'li'}
var foo = fn.bind(people,'男')
foo(10) // 'li男10'
// 示例3
function fn(sex, age, name){
return sex + age + name
}
var foo = fn.bind(this, '男', 10)
foo('小王') // '男10小王'
foo('小李') // '男10小李'
toString()
函数实例的toString()方法返回函数代码的字符串,静态toString()方法返回类似“[native code]”的字符串
function fn(){
return 1
}
fn.toString() // "function fn(){ return 1 }"
Function.toString() // "function Function() { [native code] }"
toLocaleString()
toLocaleString()方法和toString()方法的返回结果一样
valueOf()
valueOf()方法返回函数本身
function fn(){
return 1
}
fn.valueOf() // function fn(){ return 1 }
Function.valueOf() // Function() { [native code] }