JavaScript Tips - Vol.2 引用类型

2018-06-16  本文已影响0人  张羽辰

ECMAScript 中,引用类型只是一种数据结构,用于数据与功能的组装,常被称为类,但并不妥当。虽然引用类型与类看起来相似,但它们并不是相同的概念。

每个函数都是 Function 类型的实例,而且都与其他引用类型一样具有属性和方法。

function sum(num1, num2) {
    return num1 + num2;
}

console.log(sum(10, 10));        //20

var anotherSum = sum;
console.log(anotherSum(10, 10)); //20

sum = null;
console.log(anotherSum(10, 10)); //20

函数名有点类似于指针,按照变量的方式参考,就变成这样,所以 ECMAScript 并没有重载这一说法,因为被覆盖了。

function addSomeNumber(num, anotherNum){
    return num + 100 + anotherNum;
}
function addSomeNumber(num) {
    return num + 200;
}
console.log(addSomeNumber(100)); //300

而实际上,解析器在向执行环 境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行 9 任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。请看下面的例子。

console.log(sum(10,10));
function sum(num1, num2){
    return num1 + num2;
}

// error
console.log(sum(10,10));
var sum = function(num1, num2){
    return num1 + num2;
};

因为解释器会在执行时,找不到 sum 对应的函数引用。

函数可以传递,并且也可以被返回(废话)。

函数 arguments 是一个挺有意思的东西,使用 arguments.callee 会避免耦合问题。

function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1)
        // return num * factorial(num - 1)
    }
}

var trueFactorial = factorial;
factorial = function(){
    return 0;
};
console.log(trueFactorial(5));     //120
console.log(factorial(5));         //0

函数内部的另一个特殊对象是 this,其行为与 Java 和 C#中的 this 大致类似。换句话说,this 引用的是函数据以执行的环境对象——或者也可以说是 this 值(当在网页的全局作用域中调用函数时, this 对象引用的就是 window)。

每个函数都包含两个非继承而来的方法:apply()和 call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内 this 对象的值。

apply() 与 call() 真正的意义是扩充函数的作用域。参考下面这个有意思的例子:

window.color = "red";

var o = { color: "blue" };
function sayColor(){
    var color = "black";
    console.log(color);
}
sayColor(); // red
sayColor.call(this); // red
sayColor.call(o); // blue

o = null;
sayColor.call(o); // red
function sayColor(){
    var color = "black";
    console.log(this.color);
    // this 引用的是函数据以执行的环境对象
    // same as before
}

function sayColor(){
    var color = "black";
    console.log(color);
    // all black
}

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    console.log(this.color);
}

var myColor = sayColor.bind(o);

myColor();

使用 .bind() 当你希望获得一个函数,并且可以在合适的时机调用(例如 lazy load 等场景),或者可以作为事件,当你使用 .call().apply() 当你想立刻调用该函数,并且修改其上下文。

上一篇下一篇

猜你喜欢

热点阅读