js實行環境

提拔

  • 1 變量提拔

console.log(a);
var a = 1;
  • 2 函數表達式

  • 函數表達式的提拔 === 變量提拔
a(); 
var a = function(){...};
  • 3 函數聲明

func();
function func(){ console.log(1); }
var func = function(){ console.log(2); }
func();
  • TEST

function func(){
    a = 1;
    console.log(window.a);  //  ?
    console.log(a);         //  ?
    var a = 2;
    console.log(a);         //  ?
}
func();

this

  • TEST

var people = {
    Name: "a",
    getName : function(){
        console.log(this.Name);
    }
};
var bar = people.getName;

bar();
var people = {
    Name: "a",
    getName : function(){
        console.log(this.Name);
    }
};
people.getName();
  • 1 默許綁定

var name = 'b';
var a = {
    name: 'a',
    getName: function() {
        console.log(this.name);
    }
}
var obj = a.getName;
obj(); // ?
  • 2 隱性綁定

var name = 'b';
var a = {
    name: 'a',
    getName: function() {
        console.log(this.name);
    }
}
var obj = a.getName();
obj; // ?
  • 3 強迫綁定

  • call apply bind 區分

  • call從第二個參數最先一切的參數都是 原函數的參數。
  • apply只接收兩個參數,且第二個參數必需是數組,這個數組代表原函數的參數列表。
  • bind只要一個函數,且不會馬上實行,只是將一個值綁定到函數的this上,並將綁定好的函數返回。
var name = 'b';
var a = {
    name: 'a',
    getName: function() {
        console.log(this.name);
    }
}
a.getName.call(this);
var name = 'b';
var a = {
    name: 'a',
    getName: function() {
        console.log(this.name);
    }
}
var func = a.getName.bind(this);
func();
  • 4 New綁定

  • 建立一個新對象。

  • 把這個新對象的__proto__屬性指向原函數的prototype屬性。(即繼續原函數的原型)

  • 將這個新對象綁定到 此函數的this上 。

  • 返回新對象,假如這個函數沒有返回其他對象。

var name = 'b';
function func() {
    this.name = 'a';
    console.log(this.name);
}
var obj = new func();
obj; // ?
  • 5 箭頭函數

  • 在定義時綁定this

  • this沒法修正

var name = 'b';
var people = {
    name: "a",
    getName : function() {
        return () => {
            console.log(this.name);
        }
    }
};
var bar = people.getName();

bar();
  • TEST

function foo(arg){
    this.a = arg;
    return this
};

var a = foo(1);
var b = foo(2);

console.log(a.a);    // ?
console.log(b.a);    // ?
var x = 1;
var obj = {
    x: 2,
    f: function(){ console.log(this.x); }
};
var bar = obj.f;
var obj2 = {
    x: 3,
    f: obj.f
}
obj.f();
bar();
obj2.f();
function obj() {
    getName = function () { console.log (1); };
    return this;
}
obj.getName = function () { console.log(2);};
obj.prototype.getName = function () { console.log(3);};
var getName = function () { console.log(4);};
function getName () { console.log(5);}
 
obj.getName ();                // ?
getName ();                    // ?
obj().getName ();              // ?
getName ();                    // ?
new obj.getName ();            // ?
new obj().getName ();          // ?
new new obj().getName ();      // ?

實行環境&作用域

  • 變量、函數表達式——變量聲明,默許賦值為undefined;
  • this——賦值;
  • 函數聲明——賦值;

這三種數據的預備狀況我們稱之為“實行上下文”或許“實行上下文環境”。

作用域在函數定義時就已肯定了。而不是在函數調用時肯定。

var a = 10;
function fn() {
    console.log(a);
}
function bar(f) {
    var a = 20;
    f()
}
bar(fn);

1 全局實行環境
2 fn實行環境
3 bar實行環境

var a = 10;               // 1
var b = 200;    
function fn() {     
    var b = 20;
    function bar() { 
        console.log(a + b);
    }
    bar();                 // 3
}
fn();                    // 2
var a = 10;               // 1
var b = 200;    
function fn() {     
    var b = 20;
    function bar() { 
        console.log(this.a + this.b);
    }
    bar();                 // 3
}
fn();                    // 2

閉包

函數作為返回值,函數作為參數通報。

function fn () {
    var max = 10;
    return function bar(x) {
        if (x > max) {
            console.log(x);
        }
    }
}
var f1 = fn();
var max = 100;
f1(15);
    原文作者:阿木木
    原文地址: https://segmentfault.com/a/1190000014481310
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞