JavaScript学习笔记深究JavaScript

js高三精炼 —— 引用类型(下)

2016-11-08  本文已影响33人  Angeladaddy

Function

函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针 函数是对象,函数名是指针。

crazy javascript
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对象其实是不存在的,但又无所不在

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
var code = "console.log('hi there')";
eval(code);

eval就像一个功能完备的javascript解释器,运行里面的字符串代码

上一篇 下一篇

猜你喜欢

热点阅读