從use strict看JS(一):this與箭頭函數

github看原文:點一下javascript

系列

一日,見「use strict」,冥想許久……html

系列列表:
從use strict看JS(一):this與箭頭函數
從use strict看JS(二):函數傳參模式與argumentsjava

use strict

use strict指js的嚴格模式,還沒了解的看這裏:Javascript 嚴格模式詳解git

use strict有3點比較重要github

  • 函數調用this爲undefined面試

  • arguments。不容許對arguments賦值。禁止使用arguments.callee。arguments再也不追蹤參數的變化babel

  • 不用var聲明不會提高成全局變量,而是報錯閉包

use strict還有一些常人不易寫錯的,不歸入寫做範圍:app

  • 對象不能有重名的屬性,函數不能有重名的參數函數

  • 規定保留字。class, implements

迴歸正題,什麼是函數調用?爲什麼嚴格模式函數調用要將this指向undefined?

this調用的四種模式

首先牢記:js function有四種方式調用,每一種的this都不一樣。

方法調用

當函數被保存爲對象的屬性時,咱們稱這個函數爲方法。方法調用的this就綁定到該對象

var dog={
        name:"doge",
        sayName:function(){
            console.log(this.name);
        }
    }
    //輸出doge,this綁定到了dog
    dog.sayName();

函數調用

聲明一個function而後調用。非嚴格模式this指向window,嚴格模式是undefined

function sayName(){
        console.log(this);
    }
    function sayNameStrict(){
        "use strict";
        console.log(this);
    }
    //指向window
    sayName();
    //開啓嚴格模式,指向undefined
    sayNameStrict();

構造函數調用

這在對象、對象繼承用的比較多,經過new來使用,this指向new出來的新對象。
後面會有文章講解new如何實現,到時候就會很清楚。

function Dog(name){
        this.name=name;
    }
    var dog=new Dog("doge");
    //this指向dog
    console.log(dog.name);

apply & call & bind

這類就是改變this,apply和call是很重要的,因此許多面試都會問,以後的文章咱們會看到它們的強大做用。

問題:當對象的方法返回了函數?

那就是函數調用了。這是js的一個設計錯誤,this應該綁定到外部函數的this變量,
這個錯誤便是「函數調用」this綁定的錯誤。嚴格模式規定,this不指向window了,但並無解決這個問題,因而箭頭函數來了。

var dog={
    name:"doge",
    sayName:function(){
        return function(){
            console.log(this);
        }
    }
}
// 此時是函數調用,this指向window
dog.sayName()();

箭頭函數對this的改變

箭頭函數怎麼解決這個問題呢?其實用了閉包,改爲下面這樣,babel啥的也是這樣作的。

var dog = {
    name: "doge",
    sayName: function sayName() {
        var _this = this;

        return function () {
            console.log(_this);
        };
    }
};

那若是嵌套了多層箭頭函數?對閉包來講是同樣的

var dog={
        name:"doge",
        sayName:function(){
            return ()=>{
                return ()=>{
                    console.log(this);
                }
            }
        }
    }

至關於

var dog = {
    name: "doge",
    sayName: function sayName() {
        var _this = this;
        return function () {
            return function () {
                console.log(_this);
            };
        };
    }
};

那若是函數的屬性就是箭頭函數?沒有這樣用的!你會拿到window

var dog={
        name:"doge",
        sayName:()=>{
            console.log(this);
        }
    }
    // this指向window,由於箭頭函數
    dog.sayName();

the good parts

這是一本書,文末有連接。

the good parts說過:js語言有些地方設計得很差,因而後來的標準不斷地補坑。
the good parts又說過:js 函數調用this綁定到window是一個設計錯誤

等等,嚴格模式函數調用this爲什麼指向undefined??

  • 首先,不應指向window,因此換一個。

  • 其次,指向undefined有一個好處,構造函數通常不要直接運行,那要是強行運行呢?this指向window會給window添加許多屬性,有擾亂命名空間之嫌,指向undefined以後,你強行運行我就強行報錯!

    function Dog(name){

    this.name=name;

    }
    //會給window增長name屬性,改爲嚴格模式就會TypeError
    Dog("doge");

固然,use strict不能解決全部問題,因此有了箭頭函數

參考

Javascript 嚴格模式詳解
the good parts

相關文章
相關標籤/搜索