zoukankan      html  css  js  c++  java
  • You Don't Know JS: this & Object Prototypes( 第一章 this or That?)

    Foreword

    this 关键字和prototypes

    他们是用JS编程的基础。没有他们创建复杂的JS程序是不可能的。

    我敢说大量的web developers从没有建立过JS Object,仅仅对待这门语言作为一个事件绑定胶水,在按钮和Ajax请求之间。

    我也曾是他们的一员,但是当我了解到如何掌握prototypes并创建JS对象,一个世界的可能性对我打开了。



    Chapter 1: this Or That?

    this作为一个识别符号关键字自动定义在每个函数的作用域中,但是它究竟涉及什么,甚至困扰着有经验的JS developer。


    Why this?

    既然很难理解,为什么还使用?它的麻烦大于它的价值吗?

    看案例:

    function identify() {
        return this.name.toUpperCase();
    }
    
    var me = {
        name: "Kyle"
    };

    var you = {
    	name: "Reader"
    }; 
    identify.call( me ); // KYLE
    identify.call( you ); // READER

    这段代码让identify函数被多次调用。

    如果不用this关键字,也可以通过传入一个context对象来实现:

    function identify(context) {
        return context.name.toUpperCase();
    }
    identify( you ); // READER

    由此可见,this机制提供了更优雅的方式,暗示传入了一个对象,这让API设计更清晰,复用更容易。


    Confusions

    首先,消除一些错误观念。常常有2个错误的假设:

    Itself

    假设this是函数自身。

    function foo(num) {
        console.log( "foo: " + num );
    
        // keep track of how many times `foo` is called
        this.count++;
    }
    
    foo.count = 0;
    
    var i;
    
    for (i=0; i<10; i++) {
        if (i > 5) {
            foo( i );
        }
    }
    // foo: 6
    // foo: 7
    // foo: 8
    // foo: 9
    
    // how many times was `foo` called?
    console.log( foo.count ); // 0 -- WTF?
    因为this指向了window对象。this指向的是调用函数的对象。
    //在call方法内加上函数对象的identifier名字
    for (var i=0; i<10; i++) {
        if (i > 5) {
            foo.call( foo, i );
        }
    }
    
    // how many times was `foo` called?
    console.log( foo.count ); // 4

    除此之外,还有规避this的方法。但都没有直面this到底是什么的问题。

    • 使用foo.count代替this.count.
    • 单独声明一个data对象{ count: 0},用于计数 data.count++

    Its Scope

    另一个常见的误区是关于this,它涉及了函数的作用域。这里有些诡计:

    在某些情况下是对的,但在其他情况下,这么理解是受到误导的!

    this关键字,在任何时候,都不涉及一个function的 Lexical scope

    function foo() {
        var a = 2;
        this.bar();
    }
    
    function bar() {
        console.log( this.a );
    }
    
    foo(); //undefined

    写 这段代码的人,试图通过this关键字,把变量a传递给bar函数。以为this是桥梁,能在两个函数的lexical scope之间传递内部变量a。 ❌。没有这个桥梁!!

    this不能得到foo函数的Lexical scope!!

    this和Lexical scope是不相关的!!!

     


    What's this?

    this机制到底是如何工作的?

    this和函数调用的方式相关!

    当一个函数被invoked,一条记录被创建。这条记录包含信息:

    • 函数从哪里调用(the call-stack)
    • 函数如何被invoked
    • 什么参数被传入。

    这条记录的属性之一就是 this 引用。它会在函数的执行期间被使用。

    下一章,我们会学习寻找一个函数的call-site(调用点),来决定它的执行如何绑定this关键字

     

    Review

    this既不是函数自身的引用也不是函数的lexical作用域的引用!!

    this实际是一个在函数被invoked时创建的绑定binding!!!

    this引用什么由函数被调用的地点call-site决定!!!

  • 相关阅读:
    Android OpenGL ES 相机预览适配不同分辨率的手机
    Android NDK 之CPU架构兼容与包体积控制方案
    [QUANTAXIS量化分析]三因素模型(ZZ)
    [QUANTAXIS量化分析]成长股内在价值投资策略(ZZ)
    [QUANTAXIS量化分析]成长股内在价值投资策略(ZZ)
    [QUANTAXIS量化分析]羊驼策略1(zz)
    联想数据守护者在Win10上不能安装的问题
    7月14号左右转为做多 目前需要一个月左右的时间去消化 大概点位在2万以下做多 不要操作 越操作越乱
    vim :.,$d 从当前行到结尾删除
    calico
  • 原文地址:https://www.cnblogs.com/chentianwei/p/9743606.html
Copyright © 2011-2022 走看看