1. Function类型特性
- 没有重载,同名覆盖。
function addSomeNumber(num){
return num +100;
}
function addSomeNumber(num){
return num +200;
}
var num = addSomeNumber(100);//300
- 函数声明和函数表达式。
console.log(sum(1,2)); // 3
function sum(a,b){
return a + b;
}
上面就是所谓的函数提升了,不多说了哈
2. 函数内部属性
在函数内部,有两个特殊的对象,arguments
和 this
,也规范化了一个属性caller
.
-
arguments
:它是一个类数组对象,包含函数中所有的参数,还有一个名叫callee
的指针属性,该指针属性指向拥有这个arguments
对象的函数。通常在递归算法中会用上它。
function factorial(num){
if(num<=-1){
return 1;
} else{
return num*factorial(num-1)
}
}
以上函数写法没有问题,但函数的执行与函数名factorial 紧紧耦合在了一起,为了消除这种耦合现象,可以如下写法:
function factorial(num){
if(num<=-1){
return 1;
} else{
return num*arguments.callee(num-1)
}
}
这样就可以避免函数名字的耦合带来的如下问题:
var trueFactorial = factorial;
factorial = function(){
return 0
};
trueFactorial(5); // 120
factorial(5); // 0
上面的情况如果没有用到arguments.callee()
,就不能完成递归调用。
还有匿名函数的自调用。
-
this
引用的是函数据以执行的环境对象,在全局作用域中它指向的是window对象。
window.color = "red";
function sayColor(){
console.log(this.color)
};
var o = { color:" blue " };
sayColor() //red
o.sayColor = sayColor;
o.sayColor() // blue
-
caller
:这个属性中保存着调用当前函数的函数的引用。如果在全局中调用的当前函数,那么caller
的值为null。
function outer(){
inner();
}
function inner(){
console.log(inner.caller) //arguments.callee.caller也是可以的。
}
outer();
//ƒ outer(){....}
3. 函数属性和方法
函数既然是对象,那么函数也有属性和方法。
每个函数都包含两个属性:length
和prototype
.
-
length
:属性表示函数希望接收的命名参数的个数。
function sayName (name){
console.log(name);
}
function sum (num1,num2){
return num1 + num2;
}
function sayHi (){
console.log("hi");
}
console.log(sayName.length) // 1
console.log(sum.length) // 2
console.log(sayHi.length) // 0
-
prototype
:javaScript中的所有引用类型,prototype是保存它们所有实例方法的真正所在。诸如toString() valueOf()
等方法实际上都保存在prototype
名下,它的详细介绍请《理解原型对象》
每个函数都包含两个非继承而来的方法,apply()
和call()
,它们能够在特定的作用域中调用函数,也就是设置函数内部this的指向。
apply()
function sum (num1,num2){
return num1 + num2;
}
function callSum1(num1,num2){
sum.apply(this , arguments)
}
function callSum2(num1,num2){
sum.apply(this ,[num1 , num2])
}
console.log(callSum1(10,10)) // 20
console.log(callSum2(10,10)) // 20
上面的apply()
方法接收两个参数,一个是在其运行环境中的作用域,另一个是参数数组,数组可以是arguments
,也可以是Array的实例。
call()
function sum (num1,num2){
return num1 + num2;
}
function callSum2(num1,num2){
sum.call(this , num1 , num2)
}
console.log(callSum1(10,10)) // 20
call()
方法和apply()
方法的作用相同,他们的区别仅在于接收的参数不同。
而它们真正的用武之地是能够扩充函数赖以运行的作用域。
window.color = "red";
var o = {color:"blue"}
function sayColor(){
console.log(this.color)
}
sayColor() //red
sayColor.call(this) //red
sayColor.call(window) //red
sayColor.call(o) //blue
扩展
我们还可以调用Object的toString方法来判断任何类型
Object.prototype.toString.call()
Object.prototype.toString.call("你好呀")
//"[object String]"
Object.prototype.toString.call(null)
//"[object Null]"
Object.prototype.toString.call([])
//"[object Array]"
Object.prototype.toString.call(NaN)
//"[object Number]"
Object.prototype.toString.call(false)
//"[object Boolean]"
网友评论