JavaScript之call,bind,apply方法及 this 的用法辨析

栏目: JavaScript · 发布时间: 6年前

内容简介:JavaScript函数中的三个方法例如:

概述

JavaScript函数中的三个方法 .call() , .apply() , .bind() ,总体来说主要功能就是改变函数中 this 关键字的指向,因为 this 默认指向 当前环境的对象

例如:

var obj = {
    name: 'Knight',
    getName: function() {
        // this 指向 obj 对象
        console.log(this.name);
    }
}
obj.getName(); // 'Knight'

call()

.call() 可以用于改变 this 值的指向,例如:

this.name = 'Knight'; // 此处 this 指向全局对象 window;
var obj = {
    name: 'Cloud'
}
function fn() {
    console.log(this.name);
}

fn();         // 'Knight'
fn.call(obj); // 'Cloud'
// 此处指向了 obj 对象,所以 name 变了

也可以传递函数参数,平常调用函数的形式可能是这样:

function fn(a, b) {
    console.log(a + b);
}

fn(2 + 3); // 5

现在也可以这样调用:

function fn(a, b) {
    console.log(a + n);
}

fn.call(null, 2, 3); // 5
// 因为函数里没有用到 this,
// 所以可以设置为 null

apply()

.apply().call() 类似,第一个参数也是用于改变 this 指向,区别就是 apply() 接受的函数参数是一个 数组 ,例如:

function fn(a, b) {
    console.log('Mu name is ' +
    this.name + (a + b) +
    ' years old.');
}
var obj = {
    name: 'Knight'
}
var arr = [2, 3];

fn.apply(obj, arr);
// My name is Knight, 5 years old.

// 使用 call() 的情况:
fn.call(obj, 2, 3);
// My name is Knight, 5 years old.

bind()

.bind() 也与 .call() 类似,改变 this 指向,传递函数参数,区别在于 .bind() 方法结果是创建一个新的 绑定函数 ,而之前的 .call().apply() 结果都是 立即执行函数 ,举例来理解:

var obj = {
    name: 'Knight'
}
function fn(a, b) {
    console.log('My name is ' +
    this.name + (a + b) +
    ' years old.');
}

var fnn = fn.bind(obj, 2, 3);
// fn.bind() 是一个函数,不会立即执行
fnn();
// My name is Knight, 5 years old.

fn.bind(obj, 2, 3)();
// 这种写法就是立即执行函数了,
// 结果与上面一样;

this 的困境

考虑以下情况:

function fn1() {
    function fn2() {
        console.log('fn2: ' +
        this);
    }
    fn2();
    console.log('fn1: ' + this);
}

fn1.call('here'); // 'fn1: here'

结果不会输出 fn2: here ,因为函数定义 fn2 里的 this 是一个新的指向,并且未定义,与外部函数 fn1 中的 this 不同;

所以我们通常会进行一下处理:

function fn1() {
    function fn2() {
        console.log('fn2: ' +
        this);
    }
    
    // 对 this 进行转存
    var that = this;
    fn2.call(that);
    
    console.log('fn1: ' +
    this);
}

fn1.call('here');
/*
fn2: here
fn1: here
*/

当然,ES6中的 箭头函数 解决了上述问题:

function fn1() {
    var fn2 = () => {
        console.log('fn2: ' + this);
    }
    fn2();
    fn2.call('there');
    console.log('fn1: ' + this);
}

fn1.call('here');
/*
fn2: here
fn2: here
fn1: here
*/

由于 .call() 方法对箭头函数不起作用,所以上面的第二行输出与第一行相同;


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Definitive Guide to HTML5 WebSocket

The Definitive Guide to HTML5 WebSocket

Vanessa Wang、Frank Salim、Peter Moskovits / Apress / 2013-3 / USD 26.30

The browser is, hands down, the most popular and ubiquitous deployment platform available to us today: virtually every computer, smartphone, tablet, and just about every other form factor imaginable c......一起来看看 《The Definitive Guide to HTML5 WebSocket》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试