Javascript - interesting features

1. Immediately Invoked Function Expressions (IIFEs)

The traditional function is declared but not executed, we need to explicitly execute it after definition. Like:

var foo = function() {
    // ..
};

foo(); // execute

var x = function bar(){
    // ..
};

x(); // execute

If we want to execute the function refrenced immediately before it. We can realize as following:

// `IIFE` function expression,
// then `()` executes it
(function IIFE(){ .. })();


2. Closure

You can think of closure as a way to “remember” and continue to access a function’s scope (its variables) even once the function has finished running.

For example:

function makeAdder(x) {
    // parameter `x` is an inner variable

    // inner function `add()` uses `x`, so
    // it has a "closure" over it
    function add(y) {
        return y + x;
    };

    return add;
}
// makeAdder() will return a function, rather than a value. And the returned function can still access its parameter - x

// we can use it like this:
// `plusOne` gets a reference to the inner `add(..)`
// function with closure over the `x` parameter of
// the outer `makeAdder(..)`
var plusOne = makeAdder( 1 );

plusOne( 3 );       // 4  <-- 1 + 3
plusOne( 41 );      // 42 <-- 1 + 41

More on how this code works:

  1. When we call makeAdder(1), we get back a reference to its inner add(..) that remembers x as 1. We call this function reference plusOne(..).
  2. When we call plusOne(3), it adds 3 (its inner y) to the 1 (remembered by x), and we get 4 as the result.

The most common usage of closure in JavaScript is the module pattern. Modules let you define private implementation details (variables, functions) that are hidden from the outside world, as well as a public API that is accessible from the outside.

For example:

function User(){
    var username, password;

    function doLogin(user,pw) {
        username = user;
        password = pw;

        // do the rest of the login work
    }

    var publicAPI = {
        login: doLogin
    };

    return publicAPI;
}

// create a `User` module instance
var fred = User();

fred.login( "fred", "12Battery34!" );

NOTE: The User() function serves as an outer scope that holds the variables username and password, as well as the inner doLogin() function; these are all private inner details of this User module that cannot be accessed from the outside world.

The inner doLogin() function has a closure over username and password, meaning it will retain its access to them even after the User() function finishes running.



3. this Identifier

While it may often seem that this is related to “object-oriented patterns,” in JS this is a different mechanism.

If a function has a this reference inside it, that this reference usually points to an object. But which object it points to depends on how the function was called.

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

var bar = "global";

var obj1 = {
    bar: "obj1",
    foo: foo
};

var obj2 = {
    bar: "obj2"
};

// --------

foo();              // "global"
obj1.foo();         // "obj1"
foo.call( obj2 );   // "obj2"  obj2.foo();
new foo();          // undefined

Note:

  1. foo() ends up setting this to the global object in non-strict mode – in strict mode, this would be undefined and you’d get an error in accessing the bar property – so “global” is the value found for this.bar.

  2. obj1.foo() sets this to the obj1 object.

  3. foo.call(obj2) sets this to the obj2 object.
  4. new foo() sets this to a brand new empty object.


4. Prototypes

When you reference a property on an object, if that property doesn’t exist, JavaScript will automatically use that object’s internal prototype reference to find another object to look for the property on. You could think of this almost as a fallback if the property is missing.

The internal prototype reference linkage from one object to its fallback happens at the time the object is created. The simplest way to illustrate it is with a built-in utility called Object.create(..). Example:

var foo = {
    a: 42
};

// create `bar` and link it to `foo`
var bar = Object.create( foo );

bar.b = "hello world";

bar.b;      // "hello world"
bar.a;      // 42 <-- delegated to `foo`
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值