极客

JavaScript复习——this

2019-02-19  本文已影响9人  极客传

this

this 在面向对象编程中十分常见。JavaScript 中的 thisJava 中的 this 有所不同,Java 中的 this 依赖于函数的声明,而在 JavaScriptthis 则依赖于函数的执行,因此 JavaScript中的 this 常被称为调用上下文

看下面代码,问函数里面的 this等于什么?

function jikezhuan () {
    console.log(this);
}

这里的 this 现在并不等于 window ,因为它可能等于包括 window 在内的许多值。如开头所述,this 依赖于函数的执行,目前函数并未执行 this 的值是未知的。

那么,接下来看看它有哪几种执行方式:

// 作为函数进行调用

function jikezhuan () {
    console.log( this );
}
jikezhuan();

jikezhuan1 = jikezhuan;
jikezhuan1();

两次输出都是 Window 对象。因为这两函数在执行时,其上下文是全局。

.

// 作为方法进行调用

var jike = {name: "jikezhuan"};

jike.skill = function () {
   console.log(this.name);
}

jike.skill(); // jikezhuan

通过 jike 对象的 skill 属性来调用函数,此时是作为 jike 的一个方法来调用的,该函数的上下文是 jike, 即 this 指向 jike 对象。

.

//作为构造器进行调用

function Jike() {
   this.skill = function() { return this }; 
}

var jike1 = new Jike();
var jike2 = new Jike();

if (jike1.skill() === jike1) {
   console.log("this指向jike1");
}

if (jike2.skill() === jike2) {
   console.log("this指向jike2");
}

执行以上代码,在控制台会输出 this指向jike1this指向jike2 。 构造器 Jike 在函数的上下文对象上创建了一个 skill属性,该属性方法又返回了上下文自身。 在使用 new 关键字进行调用时,会创建一个空对象实例,并把该对象作为 this 参数传递给 new 后面的函数—— jike2

.

apply() 、call()

函数调用方式之间的主要差异是:作为 this 参数传递给执行函数的上下文对象之间的区别。作为方法进行调用,上下文是该方法的拥有者;作为全局函数进行调用,其上下文是 window(也即该函数是 window 的一个方法);作为构造函数进行调用,其上下文对象是新创建的对象实例。当一个事件处理程序被调用时,该函数的上下文将被设置为绑定事件的对象。

有时会出现这样的需求,需要自由地指定函数的上下文,而 apply() 、call() 方法就能实现这样的功能。Javascript 的每个函数都有 apply() 和 call() 方法。

apply() 方法接收两个参数,一个是作为函数上下文的对象,另一个是作为函数参数所组成的数组。call() 方法使用方式的不同点在于,给函数传入的参数是一个参数列表,而不是单个数组。

//定义一个求和函数
function sum() {
    var result = 0;
    for (var i = 0; i < arguments.length; i++) { //arguments参数数组
        result += arguments[i];
    }
    this.result = result;
}

//创建两个测试对象
var test1 = {},
    test2 = {};

//使用apply()、call()方法调用函数
sum.apply(test1, [1,2,3,4]);
sum.call(test2, 5, 6, 7);

console.log("test1.result", test1.result); //10
console.log("test2.result", test2.result); //18

arguments 对象

arguments 保存着函数的参数。

arguments 是一个对应于传递给函数的参数的类数组对象。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。

// 求和函数
function add () {
    let sum = 0
    for (let i = 0; i < arguments.length; i++) {
        sum = sum + arguments[i]
    }
    return sum
}
add(1,2,3,4,5)

arguments.callee

arguments 对象上有一个名为 callee 的属性,其属性值为正在被执行的函数。先看一个例子,就知道 arguments.callee 的应用场景了。

现需用递归求1到n的和:

// 递归求和
// 求1~100的和
function sum (n) {
    if (n > 1) {
        return n + sum(n-1)
    } else {
        return 1
    }
}
sum(100)

增加难度,用匿名函数递归求1到n的和:

// 匿名函数 递归求和
// 求1~100的和
(function (n) {
    if (n > 1) {
        return n + arguments.callee(n-1)
    } else {
        return 1
    }
}) (100)
上一篇 下一篇

猜你喜欢

热点阅读