前端基础知识:this 指向问题,和 bind、call、apply之区分

2021-02-0209:50:54WEB前端开发Comments1,384 views字数 2379阅读模式

this 就是一个指针,指向我们调用函数的对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

执行上下文: 是语言规范中的一个概念,用通俗的话讲,大致等同于函数的执行“环境”。具体的有:变量作用域(和 作用域链条,闭包里面来自外部作用域的变量),函数参数,以及 this 对象的值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

找出 this 的指向文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

this 的值并不是由函数定义放在哪个对象里面决定,而是函数执行时由谁来唤起决定。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

var name = "Jay Global";
var person = {
    name: 'Jay Person',
    details: {
        name: 'Jay Details',
        print: function() {
            return this.name;
        }
    },
    print: function() {
        return this.name;
    }
};

console.log(person.details.print());  // 【details对象调用的print】Jay Details
console.log(person.print());          // 【person对象调用的print】Jay Person

var name1 = person.print;
var name2 = person.details;

console.log(name1()); // 【name1前面没有调用对象,所以是window】Jay Global
console.log(name2.print()) // 【name2对象调用的print】Jay Details

this和箭头函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

箭头函数按词法作用域来绑定它的上下文,所以 this 实际上会引用到原来的上下文。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

箭头函数保持它当前执行上下文的词法作用域不变,而普通函数则不会。换句话说,箭头函数从包含它的词法作用域中继承到了 this 的值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

匿名函数,它不会作为某个对象的方法被调用, 因此,this 关键词指向了全局 window 对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

var object = {
    data: [1,2,3],
    dataDouble: [1,2,3],
    double: function() {
        console.log(this); // object
        return this.data.map(function(item) { // this是当前object,object调用的double
            console.log(this);   // 传给map()的那个匿名函数没有被任一对象调用,所以是window
            return item * 2;
        });
    },
    doubleArrow: function() {
        console.log(this); // object
        return this.dataDouble.map(item => { // this是当前object,object调用的doubleArrow
            console.log(this);      // doubleArrow是object调用的,这就是上下文,所以是window
            return item * 2;
        });
    }
};
object.double();
object.doubleArrow();

明确设置执行上下文文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

在 JavaScript 中通过使用内置的特性开发者就可以直接操作执行上下文了。这些特性包括:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

  • bind():不需要执行函数就可以将 this 的值准确设置到你选择的一个对象上。通过逗号隔开传递多个参数。 设置好 this 关键词后不会立刻执行函数。
  • apply():将 this 的值准确设置到你选择的一个对象上。apply(thisObj, argArray)接收两个参数,thisObj是函数运行的作用域(this),argArray是参数数组,数组的每一项是你希望传递给函数的参数。如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。最后,会立刻执行函数。
  • call():将 this 的值准确设置到你选择的一个对象上。然后像bind 一样通过逗号分隔传递多个参数给函数。语法:call(thisObj,arg1,arg2,..., argn);,如果没有提供thisObj参数,那么Global对象被用于thisObj。最后,会立刻执行函数。

this 和 bind文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

var bobObj = {
    name: "Bob"
};
function print() {
    return this.name;
}
var printNameBob = print.bind(bobObj);
console.log(printNameBob()); // Bob

this 和 call文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

function add(a, b) { 
    return a + b; 
}
function sum() {
    return Array.prototype.reduce.call(arguments, add);
}
console.log(sum(1,2,3,4)); // 10

this 和 apply文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

apply 就是接受数组版本的call。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

Math.min(1,2,3,4); // 返回 1
Math.min([1,2,3,4]); // 返回 NaN。只接受数字
Math.min.apply(null, [1,2,3,4]); // 返回 1

function Person(name, age){  
  this.name = name;  
  this.age = age;  
}  

function Student(name, age, grade) {  
  Person.apply(this, arguments);  //Person.call(this, name, age);
  this.grade = grade;  
}
var student = new Student("sansan", 21, "一年级");  
 
console.log("student:", student); // {name: 'sansan'; age: '21', grade: '一年级'}

如果你的参数本来就存在一个数组中,那自然就用 apply,如果参数比较散乱相互之间没什么关联,就用 call。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/20918.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/20918.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定