美文网首页
JS中的this

JS中的this

作者: JasonQiao | 来源:发表于2017-03-22 19:13 被阅读23次

参考
English
中文

先导知识:

call, apply, bind

两个概念:

调用点(call-site):代码中函数被调用的地方而不是函数被定义的地方。
调用栈(call-stack):代码执行时到达当前位置的函数栈。我们care的是当前函数环境的调用位置。
举个栗子:

function a(){
  //调用栈为'a'
  //调用点在全局作用域中
  console.log('a');
  //b的调用点
  b();
}
function b(){
  //调用栈为'a' ->'b'
  //调用点在a中
  console.log('b');
  //c的调用点
  c();
}
function c(){
  //调用栈为'a' ->'b'->'c'
  //调用点在b中
  console.log('c');
}

//a的调用点
a();

四种绑定:

默认绑定(Default Binding)

被直接(plain, un-decorated)调用的函数在非严格(non-strict)模式下绑定的是全局对象;在严格(strict)模式下undefined,报错。
栗子:

  1. 非严格模式直接调用函数
function foo() {
    console.log( this.a );
}
var a = 2;
foo(); // 2
  1. 严格模式直接调用函数(只和函数内部是不是严格模式有关,而和调用点是不是严格模式无关)
function foo() {
    "use strict";

    console.log( this.a );
}
var a = 2;
foo(); // TypeError: `this` is `undefined`

隐式绑定(Implicit Binding)

调用点函数引用是否有一个环境对象(如果有多级引用,则取离函数最近的对象)
栗子:

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo
};

obj.foo(); // 2

番栗子:

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo
};

var bar = obj.foo; // function reference/alias!

var a = "oops, global"; // `a` also property on global object
//此处调用bar依然是对foo函数的直接引用,所以是默认绑定
bar(); // "oops, global"

如果不想像调用对象上的属性函数这样来绑定this,请看下面的显示绑定

显示绑定(Explicit Binding)

使用call方法和bind方法
栗子:foo.call(obj),此时foo函数中的this引用的就是obj

  1. 强绑定(Hard Binding)
    栗子:
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2
};
var bar = function() {
    foo.call( obj );
};
bar(); // 2
setTimeout( bar, 100 ); // 2
// bar是一个将this强绑定为obj的函数,他已经不是foo了
//所以bar中的this不能被重载了
bar.call( window ); // 2

个人觉得You don't know JS作者将强绑定归入显示绑定而不是划等号应该是因为显示绑定中可能就是直接以foo.call(obj)形式调用一次,而强绑定则将这个强绑定的函数保留多次调用。如有其它建议,欢迎讨论。

  1. API调用环境(API call context)
    许多库函数都可以接受一个环境参数
    栗子:
function foo(el) {
    console.log( el, this.id );
}
var obj = {
    id: "awesome"
};
// 每次调用foo函数都把obj作为this引用
[1, 2, 3].forEach( foo, obj ); // 1 awesome  2 awesome  3 awesome

new绑定(new Binding):

在JS中,构造器(constructor)仅仅是使用new操作符调用的函数而已。它不附属于类,没有实例化一个类,甚至不是特殊类型的函数。它只是因为new的用法而被误解的普通函数。
在JS中没有构造函数,只有对函数的构造调用。当一个函数被new操作符调用时,发生了下列操作

  1. 生成一个新对象
  2. 新对象被[[Prototype]]-linked
  3. 新对象被绑定到这次函数调用的this
  4. 除非函数返回其他对象,否则默认就返回这个新创建的对象的了
    栗子:
function foo(a) {
    this.a = a;
}
var bar = new foo( 2 );//this绑定到了新创建的对象,即bar
console.log( bar.a ); // 2

绑定例外(Binding Exceptions)

词法this(Lexical this)

ES6的箭头函数

相关文章

  • JavaScript 04 (do...while循环/for

    js循环,js循环嵌套,js do...while循环,js的for循环,js中的break,js中的contin...

  • iOS原生&JS交互

    OC 获取js中的key OC调用js方法 JS调用OC中不带参数的block JS调用OC中带参数的block ...

  • JS 对象

    JS对象 JS对象的意义和声明 在JS中,对象(OBJECT)是JS语言的核心概念,也是最重要的数据类型。在JS中...

  • 单引号和双引号

    JS中 js中单引号和双引号的区别(html中属性规范是用双引号,js中字符串规定是用单引号)(js中单引号区别和...

  • js中的this

    一句话,call的第一个参数 看几个例子例1. 这里的this是什么?不要靠猜,是call的第一个参数,不知道去看...

  • js 中的this

    首先js中函数的this在函数被调用时总是指向一个对象(this对象是在运行时基于函数的执行环境绑定的) 然后 它...

  • JS中的this

    JS中的this 众所周知,JS中this的代表的是当前函数调用者的上下文。JS是解释性的动态类型语言,函数在调用...

  • js中的!!

    !!一般用来将后面的表达式强制转换为布尔类型的数据(boolean),也就是只能是true或者false。 var...

  • js中的this

    目标:js中this的指向? 问题的引出 指出this指向什么 js中函数的三种调用形式 func(p1, p2)...

  • JS中的this

    初学JavaScript经常被this绕晕,所以我总结一下JavaScript中的this。首先声明本文讨论的是非...

网友评论

      本文标题:JS中的this

      本文链接:https://www.haomeiwen.com/subject/gkqanttx.html