Life at the bleeding edge

😀Mind map notes 😀File Vault

😀老男孩 - python入门与提高实践

[Discourse] Paraphrase "this" in JS in one time

PREWORDS

Try to write a downright article to introduce what this is and how to use it in javascript.

Two misconceptions:

"This" refers to the function itself.
"This" somehow refers to the function's scope.

See the below code:

varcount = 0;
functioncountTool(num) {

console.log(num);

this.count++;

}


countTool.count = 0;


for (vari = 0; i < 2; i++) {

countTool.call(countTool, i);

}


console.log(countTool.count); // 0, 1, 2

console.log(this.count);  // 0 [in browser]; undefined [in node]

What "this" is?

From the code above, this mechanism provides a more elegant way of implicitly "passing along" an object reference, leading to cleaner API design and easier reuse.

CALL-SITE

Two principles:

What's "this"? Call-site is the only thing that matters for "this binding".
What's call-site? It'a a scope where is holding the reference of fun. (所持函数的引用所在的调用域。)

We have a number of rule to apply.

* Implicit binding(ignore strict model)

Example 1

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

var a = "oops, glpbal"

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

var bar = obj.foo;

bar();             // < -- call-site is global
obj.foo();         // < -- call-site is obj

Here we see, in this example, bar and obj.foo they both are the reference to function foo. But they are in different call-site scope. bar is defined in the global scope and obj.foo is in the obj scope instead. So the outcomes are in different manner.

Example 2

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

function doFoo(fn) {
    fn();    // < -- call-site
}

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

var a = "oops, glpbal"

doFoo(obj.foo);

In this example, just one stuff need to be noted is fn is parameter to function doFoo instead of argument. So the scope of parameter is the same with the function which is belong to.

Another thing you have to be aware of is with "use strict" model in the global scope. As we know, this should point to window object in the global scope. Indeed it do, but we can't pass this into the function we expected. It's like a knid of bug remaining. See the example below. It will show us with error.

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

var a = "oops, glpbal"

foo();             // Error
* explicit binding("new" is a speciality of)

Explicit binding is to provide a kind of approch to leverage apply, call or bind built-in methods to hardcode the this object to the specific function.

Here we see an example below, in this one, obj is to be hardcoded to the function foo. So no matter in any situation, this of foo is always pointing to obj object.

function foo(something) {
    console.log(this.a, something);
    return this.a + something;
}

var obj = {
    a: 2,
}

var bar = function () {
    return foo.apply(obj, arguments);
}

var b = bar(3);  // 2 3
console.log(5);  // 5

A word says, the most typical way to wrap a function with a hard binding creates a pass-through of any arguments passed and any return calue received.

硬绑定最典型的方法是为任何传入参数和返回值创建“桥梁”。

How bind method works? See the code below:

function foo(something) {
    console.log(this.a, something);
    return this.a + something;
}

// simple bind helper
function bind(fn, obj) {
    return function () {
        return fn.apply(obj, arguments)
    };
}

var obj = {
    a: 2,
};

var bar = bind(foo, obj);

var b = bar(3);  // 2 3
console.log(5);  // 5
* new operation is not common use, but this will show you another area to this binding.

Let check the code below:

function foo(something) {
    this.a = something;
}

var obj = {};

var bar = foo.bind(obj); // 2
bar(2);
console.log(obj.a); // Here is to make explicit binding happen

var baz = new bar(3);
console.log(obj.a); // 2
console.log(baz.a); // 3 Here is to use new operation, this is in the highest priority

new operation is in the highest priority of all rules. Here we see.

new operation has done 4 steps when it is invoked.

  • A brand new object is created(aka constructed) out of thin air.(凭空,无中生有)
  • The newly constructed object is [[Prototype]]-linked.
  • The newly constructed object is set as the this binding for that function call.
  • Unless the function returns its own alternate object, the new-invoked function call will automatically return the newly constructed object.
posted @ 2018-05-10 10:13  Clown--  阅读(112)  评论(0)    收藏  举报