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] }