Function
函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针。
function sum (num1,num2){
return num1+num2;
}
console.log(sum(2,3));//5
var anotherSum = sum;//注意没有圆括号,此时是指针!
console.log(anotherSum(2,3));//5
sum = null ;//即使sum为空,anotherSum依然指向sum所表示的函数,也就是说,函数一直在那
console.log(anotherSum(2,3));//5
函数声明和函数表达式的区别:
//这是函数声明,不会报错,因为有个东西叫“函数声明提升(function declaration hoisting)”
console.log(sum(1,2));
function sum (a,b){
return a+b;
};
//这是函数表达式,会报错
console.log(sum(1,2));
var sum = function (a,b){
return a+b;
};
函数名可以作为参数传递
function callFunction(func, argu) {
return func(argu);
}
function sayHello(name){
console.log('hello,'+name);
}
callFunction(sayHello,'monodev');//注意,是将函数名作为参数传递
函数也可以作为返回值:
考虑以下题目:对一个列表中所有对象的某个字段排序,
var data = [{'name':'z','age':18},{'name':'a','age':30}];
以下程序能得到正常结果,但如果要对age字段排序呢?
function compair(a,b){
return a.name > b.name;
}
data.sort(compair);
console.log(data);
解决办法:使用函数作为返回值:
function compair(propertyName){
return function(obj1,obj2){
let val1 = obj1[propertyName];
let val2 = obj2[propertyName];
return val1>val2;
}
}
data.sort(compair('age')); //[ { name: 'z', age: 18 }, { name: 'a', age: 30 } ]
data.sort(compair('name'));//[ { name: 'a', age: 30 }, { name: 'z', age: 18 } ]
函数内部的 arguments属性
函数内部的arguments对象保存着传入函数的所有参数,此对象还有一个重要属性是callee,callee是一个指针,指向拥有这个arguments对象的函数:
function test(aaa){
console.log(arguments.callee);
}
test(1);//[Function: test]
ES5加入的caller属性,保存着调用当前函数的函数的引用
function outer(){
inner();
}
function inner(){
console.log(arguments.callee);//[Function: inner]
console.log(inner.caller);//[Function: outer]
console.log(arguments.callee.caller);//[Function: outer]
}
outer();
函数的length属性表示参数个数
function test(arg1,arg2,arg3){
}
console.log(test.length);//3
以下是有关this作用域BUG及解决办法(call, apply,bind)
函数的apply和call方法都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值
apply方法接受两个参数,一个是在其中运行函数的作用域,另一个是参数数组
call方法和apply方法一样,区别在于,call的参数必须逐个传入
function sum (num1,num2){
return num1+num2;
}
function callSum1(num1,num2){
return sum.apply(this,arguments);//apply调用时可以直接传入arguments对象
}
function callSum2(num1,num2){
return sum.apply(this,[num1,num2]);
}
function callSum3(num1,num2){
return sum.call(this,10,10);//call调用时必须将参数逐个传入
}
console.log(callSum1(10,10));//20
console.log(callSum2(10,10));//20
console.log(callSum3(10,10));//20
<u>然而,apply和call的最强大之处,在于可以实时的改变函数赖于运行的作用域:</u>
global.color = 'red';
function sayColor(){
console.log(this.color);
}
sayColor();
//以global作为sayColor的作用域,sayColor里的this指向global
sayColor.call(global);//red
var obj = {color:'green'};
//以obj作为sayColor的作用域,sayColor里的this指向obj
sayColor.call(obj);//green
使用call或者apply扩充函数作用域的最大好处,就是对象不再需要与方法有任何耦合关系
ES5新增的bind()方法,这个方法会创建一个函数的实例,其this会被绑定到传递给bind的值
global.color = 'red';
function sayColor(){
console.log(this.color);
}
var obj = {color:'green'};
//改变sayColor的作用域,使其绑定到obj
sayColor.bind(obj)();//green
//或者
var bindedSayColor = sayColor.bind(obj);
bindedSayColor();//green
Global对象
Global对象其实是不存在的,但又无所不在
- encodeURI和encodeURIComponent方法,规范uri字符串
var url = "http://www.baidu.com/te st.html#1";
var encodedURI = encodeURI(url);//http://www.baidu.com/te%20%20st.html#1
var encodedURI = encodeURIComponent(url);//http%3A%2F%2Fwww.baidu.com%2Fte%20%20st.html%231
- 强大的eval
var code = "console.log('hi there')";
eval(code);
eval就像一个功能完备的javascript解释器,运行里面的字符串代码