You do not know javascript (1)

Scope

  • 1. Scope: Find a set of rules based on the variable name.
  • 2. Note: When variables RHS inquiry until the outermost scope can not find the variable. ReferenceError type of abnormal thrown. But when the variables are LHS inquiry, until the top-level scope can not be found, say in the global scope will be created in non-strict mode, a change that variable.

Lexical scoping

  • 1. Define the scope of the lexical stage
  • 2.eval () and will deceive with lexical scope and impact performance.

Function scope and block-level scope

  • 1. If the function is declared in the first word, then that is a function declaration, otherwise, it is a function expression.
  • 2. Because the variable scope likely to be covered, so the scope of the concept of functions is introduced, in order to prevent contamination of the variable. But the name of this function polluted the global scope, followed by the need to call a function in which to run the code. Therefore, the concept of execution of the function derived immediately be optimized.
  • 3.var is the global scope or function-level scope, so there will be a variable contamination occurs. So let the introduction of this block-level scope.
  • Var variable situation will improve the situation. Let the situation did not improve the appearance.
  • When the block-level scope to complete its mission, garbage collection will take it up. The global scope down but can not.

Upgrade

  • 1. The function can also be promoted.
  • 2. The function expression can not be improved.
foo();//不是ReferenceError,而是TypeError!
var foo=function bar(){};
复制代码

Closure

My own understanding: closures is to let you get the value you should not get. Not their lexical scoping in value. Callback function must be closure.

This evil

  • 1.this does not point to itself.
function foo(num){
    console.log('foo:'+num);
    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
console.log(foo.count); //0 居然是0次?
复制代码

The above example does not fully explain this point to itself. call () can help this point to itself. Examples are as follows:

function foo(num){
    console.log("foo:"+num);
    this.count++;
}
foo.count=0;
var i;
for(i=0;i<10;i++){
    if(i>5){
        foo.call(foo,i);
    }
}
// foo:6
// foo:7
// foo:8
// foo:9
console.log(foo.count);//4
复制代码

this does not point to the lexical scope of a function.

function foo(){
    var a=2;
    this.bar();
}
function bar(){
    console.log(this.a);
}
foo();//a is not defined
复制代码

this depends only on the call of a function of position

How to call location analysis Consider the following example.

function baz(){
    // 当前调用栈是:baz
    // 因此,当前调用位置是全局作用域
    console.log("baz");
    bar();//bar的调用位置
}
function bar(){
    // 当前调用栈是baz-->bar
    // 因此,当前调用位置在baz中
    console.log("baz");
    foo();
}
function foo(){
    // 当前调用栈是baz-->bar-->foo
    // 因此,当前调用位置在bar中
    console.log("foo");
}
baz();// baz的调用位置
复制代码

this default binding rules

function foo(){
    console.log(this.a);
}
var a=2;
foo();//2
复制代码

If you are using strict mode, you can not set the global default binding target language, so this will be bound to undefined.

function foo(){
    "use strict";
    console.log(this.a);
}
var a=2;
foo();// this is undefined
复制代码

Implicit Bind

When the function references have context object, the implicit this binding rule will function call is bound to the context object. Because the call foo () when this is bound to obj, and therefore this.a obj.a is the same.

function foo(){
    console.log(this.a);
}
var obj={
    a:2,
    foo:foo
};
obj.foo();//2
复制代码

Object attribute refers to the chain only on one or the last one in a position to play a role call.

function foo(){
    console.log(this.a);
}
var obj2={
    a:42,
    foo:foo
};
var obj1={
    a:2,
    obj2:obj2
};
obj1.obj2.foo(); // 42
复制代码

Implicit loss

One of the most common function of this binding is implicit binding bound objects will be lost, that is, it applies the default binding, so this is bound to put the global object or undefined, depending on whether strict mode.

function foo(){
    console.log(this.a);
}
var obj={
    a:2,
    foo:foo
};
var bar=obj.foo;
var a="oops,global";
bar();// oops,global
复制代码
  • Although the bar is obj.foo a reference, but in fact, it refers to is itself a function foo, so this time the bar () is a fact without any modification of function calls, so the application of the default bindings.
function foo(){
    console.log(this.a);
}
function doFoo(fn){
// fn其实引用的是foo
    fn();// 调用位置
}
var obj={
    a:2,
    foo:foo
};
var a="oops,global";
doFoo(obj.foo);//oops,global
复制代码

Parameter passing is actually an implicit assignment, therefore when we passed to the function will also be implicitly assigned.

function foo(){
    console.log(this.a);
}
var obj={
    a:2,
    foo:foo
};
var a="oops,global";
setTimeout(obj.foo,100);//oops,global
复制代码

Show Binding

call (), apply (), bind () will change this point

function foo(){
    console.log(this.a);
}
var obj={
    a:2,
};
foo.call(obj);//2
复制代码

By foo.call (...) you can force it to bind to the obj of this when calling foo.

function foo(){
    console.log(this.a);
}
var obj={
    a:2
};
var bar=function(){
    foo.call(obj);
};
bar();; //2
setTimeout(bar,100); //2
bar.call(window); //2 硬绑定的bar不可能再修改它的this
复制代码

No matter how after the call bar, which is always manually call foo on obj.

function foo(el){
    console.log(el,this.id);
}
var obj={
    id:'awesome'
};
[1,2,3].forEach(foo,obj);
// 调用foo时把this绑定到obj上。
// 1 awesome 2 awesome 3 awesome
复制代码

new bindings

The constructor is equivalent to creating a new object. this point to the new object.

function foo(a){
    this.a=a;
}
var bar=new foo(2);
console.log(bar.a); //2
复制代码

Reproduced in: https: //juejin.im/post/5d05d257e51d45554877a5c9

Guess you like

Origin blog.csdn.net/weixin_34327761/article/details/93173910