zoukankan      html  css  js  c++  java
  • 你不知道的JS系列 ( 20 ) - this绑定规则(默认绑定,隐式绑定)

    默认绑定
    最常用的调用类型,独立函数调用,默认规则
    function foo() {
      console.log(this.a);
    }
    var a = 2
    foo(); // 2
    如果使用严格模式,全局对象将无法使用默认绑定,this 会绑定到 undefined
    function foo() {
      'use strict';
      console.log(this.a);
    }
    var a = 2
    foo(); // TypeError: Cannot read property 'a' of undefined
    但是这里有个非常重要的细节,只有 foo() 运行在非严格模式下,就能绑定到全局对象;严格模式与 foo() 的调用位置无关
    function foo() {
      console.log(this.a);
    }
    var a = 2;
    (function(){
      'use strict';
      foo(); //2
    })()

    通常代码中不应该混用严格模式和非严格模式,整个程序要么严格,要么非严格。

    隐式绑定
    另一条需要考虑的规则是调用位置是否有上下文对象
    function foo() {
      console.log(this.a);
    }
    var obj = {
      a: 2,
      foo: foo
    }
    obj.foo(); // 2
    无论是直接在 obj 中定义还是先定义再添加为引用属性,这个函数严格来说都不属于 obj 对象。可以说函数被调用时,obj 对象包含它。当 foo() 被调用时,它当落脚点指向 obj 对象。因此 this.a 和 obj.a 是一样的。
    对象属性引用链中只有最顶层或者说最后一层会影响调用位置。举例来说:
    function foo() {
      console.log(this.a);
    }
    var obj2 = {
      a: 42,
      foo: foo
    }
    var obj1 = {
      a: 2,
      obj2: obj2
    }
    obj1.obj2.foo(); // 42

    一个最常见的 this 绑定问题是被隐式绑定的函数会丢失绑定对象,从而绑定到全局对象,严格模式下绑定到 undefined

    function foo() {
      console.log(this.a);
    }
    var obj = {
      a: 2,
      foo: foo
    }
    var bar = obj.foo; // 函数别名!
    var a = 'oops, global'; // a 是全局变量
    bar(); // 'oops, global'

    虽然 bar 是 obj.foo 的一个引用,但是实际下,它引用的是 foo 本身。因此应用了默认绑定

    一种更微妙,更常见并且出乎意料的情况发生在回调函数时:
    function foo() {
      console.log(this.a);
    }
    function doFoo(fn){
      fn(); // 调用位置
    }
    var obj = {
      a: 2,
      foo: foo
    }
    var a = 'oops, global'; // a 是全局变量
    doFoo(obj.foo); // 'oops, global'

    参数传递是隐式赋值,因此我们传入函数也会被隐式赋值。

    function foo() {
      console.log(this.a);
    }
    var obj = {
      a: 2,
      foo: foo
    }
    var a = 'oops, global'; // a 是全局变量
    setTimeout(obj.foo, 100) // 'oops, global'

    传入语言内置的函数也是一样的,没有区别

  • 相关阅读:
    [色彩校正] Gamma Correction
    需要齐次坐标的原因之二 所有的变换运算(平移、旋转、缩放)都可以用矩阵乘法来搞定
    需要齐次坐标的原因之一
    数据库连接类
    简单的数组排序
    OfficePage封装代码
    新闻管理数据模板
    最新page页码生成控件代码
    新闻管理cs页面
    快速收录新域名网站
  • 原文地址:https://www.cnblogs.com/wzndkj/p/12418175.html
Copyright © 2011-2022 走看看