成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

【譯文】this全解

dreamtecher / 3269人閱讀

摘要:避免從構(gòu)造函數(shù)返回任何東西,因?yàn)樗赡軙?huì)替換所產(chǎn)生的實(shí)例。避免使用使用也能創(chuàng)建一個(gè)實(shí)例然而這不會(huì)調(diào)用構(gòu)造函數(shù)。因?yàn)椴粫?huì)調(diào)用構(gòu)造函數(shù),所以這是一個(gè)有效的創(chuàng)建繼承模式的方法,能夠重寫(xiě)原型鏈上的構(gòu)造函數(shù)。

一. 全局 this

1.在瀏覽器中,在一個(gè)全局環(huán)境中,this就是window對(duì)象。

2.在瀏覽器中,在全局中使用var相當(dāng)于分配給this或者window

3.假如你創(chuàng)建一個(gè)新的變量,不使用var或者let(ECMAScript6),你是添加或者改變?nèi)?b>this的屬性

4.在node中使用repl,this是最頂級(jí)的命名空間,你可以認(rèn)為是global

> this
{ ArrayBuffer: [Function: ArrayBuffer],
  Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
  Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
  ...
> global === this
true

5.在node中執(zhí)行腳本,在全局中this是一個(gè)空對(duì)象,而不與global相等

test.js:
console.log(this);
console.log(this === global);
$ node test.js
{}
false

6.在node中,全局環(huán)境中的var并非像在瀏覽器中執(zhí)行腳本一樣,分配給this

test.js:
var foo = "bar";
console.log(this.foo);
$ node test.js
undefined

但是在repl中是一樣的

> var foo = "bar";
> this.foo
bar
> global.foo
bar

7.在node中,使用腳本執(zhí)行,不用var或者let創(chuàng)建的變量會(huì)添加到global而不是this.

test.js
foo = "bar";
console.log(this.foo);
console.log(global.foo);
$ node test.js
undefined
bar

在repl中,它是分配到這兩個(gè)上的。

二. 函數(shù)中的this

除了DOM事件處理程序或者一個(gè)thisArg已經(jīng)設(shè)置的情況外,在node和瀏覽器中,函數(shù)中(不實(shí)例化new)的this是全局范圍的。

test.js:
foo = "bar";

function testThis () {
  this.foo = "foo";
}

console.log(global.foo);
testThis();
console.log(global.foo);
$ node test.js
bar
foo

除非你使用user strictthis會(huì)變?yōu)?b>underfined

當(dāng)你new一個(gè)函數(shù)的時(shí)候,this會(huì)成為一個(gè)新的上下文,不等同于全局this

三. 原型中的this

函數(shù)對(duì)象有一個(gè)特殊的屬性prototype,當(dāng)你創(chuàng)建一個(gè)函數(shù)實(shí)例,可以訪問(wèn)prototype屬性,可以使用this進(jìn)行訪問(wèn)

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

    Thing.prototype.foo = "bar";

    var thing = new Thing(); //logs "bar"
    console.log(thing.foo);  //logs "bar"

加入創(chuàng)建多個(gè)實(shí)例化,它們共享原型上的值,this.foo都會(huì)返回相同的值,除非你在實(shí)例化函數(shù)上進(jìn)行覆蓋。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo);
}
Thing.prototype.setFoo = function (newFoo) {
    this.foo = newFoo;
}

var thing1 = new Thing();
var thing2 = new Thing();

thing1.logFoo(); //logs "bar"
thing2.logFoo(); //logs "bar"

thing1.setFoo("foo");
thing1.logFoo(); //logs "foo";
thing2.logFoo(); //logs "bar";

thing2.foo = "foobar";
thing1.logFoo(); //logs "foo";
thing2.logFoo(); //logs "foobar";

this在一個(gè)實(shí)例中是一個(gè)特殊的對(duì)象,this實(shí)際是一個(gè)關(guān)鍵字,可以認(rèn)為this作為一種方法去訪問(wèn)prototype,直接分配給this,將會(huì)覆蓋原來(lái)prototype上的方法。你可以刪除this掛接的方法,從而恢復(fù)訪問(wèn)默認(rèn)prototype

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo);
}
Thing.prototype.setFoo = function (newFoo) {
    this.foo = newFoo;
}
Thing.prototype.deleteFoo = function () {
    delete this.foo;
}

var thing = new Thing();
thing.setFoo("foo");
thing.logFoo(); //logs "foo";
thing.deleteFoo();
thing.logFoo(); //logs "bar";
thing.foo = "foobar";
thing.logFoo(); //logs "foobar";
delete thing.foo;
thing.logFoo(); //logs "bar";

或者直接引用函數(shù)對(duì)象的原型。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    console.log(this.foo, Thing.prototype.foo);
}

var thing = new Thing();
thing.foo = "foo";
thing.logFoo(); //logs "foo bar";

創(chuàng)建的實(shí)例都共享相同的屬性和方法,如果給prototype分配一個(gè)數(shù)組,所有實(shí)例都能夠訪問(wèn)。

function Thing() {
}
Thing.prototype.things = [];


var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing2.things); //logs ["foo"]

prototype上分配一個(gè)數(shù)組通常是一個(gè)錯(cuò)誤,如果希望每個(gè)實(shí)例都有自己的數(shù)組,那在函數(shù)中創(chuàng)建。

function Thing() {
    this.things = [];
}


var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []

this可以通過(guò)原型鏈找到相應(yīng)的方法。

function Thing1() {
}
Thing1.prototype.foo = "bar";

function Thing2() {
}
Thing2.prototype = new Thing1();


var thing = new Thing2();
console.log(thing.foo); //logs "bar"

在javascript中可以使用原型鏈模擬傳統(tǒng)面向?qū)ο罄^承。
使用函數(shù)內(nèi)含有綁定this的方法或者屬性去創(chuàng)建原型鏈,將會(huì)隱藏上層原型鏈定義的內(nèi)容。

function Thing1() {
}
Thing1.prototype.foo = "bar";

function Thing2() {
    this.foo = "foo";
}
Thing2.prototype = new Thing1();

function Thing3() {
}
Thing3.prototype = new Thing2();


var thing = new Thing3();
console.log(thing.foo); //logs "foo"

我喜歡叫綁定在原型上的函數(shù)為methods.在methods中使用this綁定某個(gè)值,將會(huì)覆蓋原型上的相關(guān)定義。

function Thing1() {
}
Thing1.prototype.foo = "bar";
Thing1.prototype.logFoo = function () {
    console.log(this.foo);
}

function Thing2() {
    this.foo = "foo";
}
Thing2.prototype = new Thing1();


var thing = new Thing2();
thing.logFoo(); //logs "foo";

在JavaScript嵌套函數(shù)中,雖然可以捕獲到父函數(shù)中的變量,但是不繼承this

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    var info = "attempting to log this.foo:";
    function doIt() {
        console.log(info, this.foo);
    }
    doIt();
}


var thing = new Thing();
thing.logFoo();  //logs "attempting to log this.foo: undefined"

函數(shù)doIt中的this指向global,在use strict下則為undefined,這是很多不熟悉this用法的人痛苦的根源之一。
更壞的情況是,將一個(gè)實(shí)例方法作為參數(shù)傳入函數(shù)。this將指向global,在use strict下則為undefined

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {  
    console.log(this.foo);   
}

function doIt(method) {
    method();
}

var thing = new Thing();
thing.logFoo(); //logs "bar"
doIt(thing.logFoo); //logs undefined

一些人把this賦值給一個(gè)變量,通常叫self,能夠避免this指向global這個(gè)問(wèn)題。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    var self = this;
    var info = "attempting to log this.foo:";
    function doIt() {
        console.log(info, self.foo);
    }
    doIt();
}

var thing = new Thing();
thing.logFoo();  //logs "attempting to log this.foo: bar"

但是這種方法在將一個(gè)實(shí)例方法作為參數(shù)傳入函數(shù)情況下,不起作用

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () { 
    var self = this;
    function doIt() {
        console.log(self.foo);
    }
    doIt();
}

function doItIndirectly(method) {
    method();
}


var thing = new Thing();
thing.logFoo(); //logs "bar"
doItIndirectly(thing.logFoo); //logs undefined

解決這個(gè)方法,可以使用函數(shù)綁定的方法bind

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () { 
    console.log(this.foo);
}

function doIt(method) {
    method();
}


var thing = new Thing();
doIt(thing.logFoo.bind(thing)); //logs bar

你也可以使用apply或者call在新的上下文環(huán)境中調(diào)用方法或者函數(shù)。

function Thing() {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () { 
    function doIt() {
        console.log(this.foo);
    }
    doIt.apply(this);
}

function doItIndirectly(method) {
    method();
}

var thing = new Thing();
doItIndirectly(thing.logFoo.bind(thing)); //logs bar

可以使用bind替換this,適用于任何函數(shù)或方法,即使沒(méi)有在實(shí)例原型上定義。

function Thing() {
}
Thing.prototype.foo = "bar";


function logFoo(aStr) {
    console.log(aStr, this.foo);
}


var thing = new Thing();
logFoo.bind(thing)("using bind"); //logs "using bind bar"
logFoo.apply(thing, ["using apply"]); //logs "using apply bar"
logFoo.call(thing, "using call"); //logs "using call bar"
logFoo("using nothing"); //logs "using nothing undefined"

避免從構(gòu)造函數(shù)返回任何東西,因?yàn)樗赡軙?huì)替換所產(chǎn)生的實(shí)例。

function Thing() {
    return {};
}
Thing.prototype.foo = "bar";


Thing.prototype.logFoo = function () {
    console.log(this.foo);
}


var thing = new Thing();
thing.logFoo(); //Uncaught TypeError: undefined is not a function

奇怪的是,假如你返回的是原始值(string或者number),返回語(yǔ)句將會(huì)被忽略。最好不要從你打算調(diào)用的構(gòu)造函數(shù)中返回任何東西,即使你知道你在做什么。如果你想創(chuàng)建一個(gè)工廠模式,使用一個(gè)函數(shù)來(lái)創(chuàng)建實(shí)例,不要用new的。當(dāng)然,這只是個(gè)人觀點(diǎn)。
避免使用new`,使用Object.create也能創(chuàng)建一個(gè)實(shí)例

function Thing() {
}
Thing.prototype.foo = "bar";


Thing.prototype.logFoo = function () {
    console.log(this.foo);
}


var thing =  Object.create(Thing.prototype);
thing.logFoo(); //logs "bar"

然而這不會(huì)調(diào)用構(gòu)造函數(shù)。

function Thing() {
    this.foo = "foo";
}
Thing.prototype.foo = "bar";


Thing.prototype.logFoo = function () {
    console.log(this.foo);
}


var thing =  Object.create(Thing.prototype);
thing.logFoo(); //logs "bar"

因?yàn)?b>Object.create不會(huì)調(diào)用構(gòu)造函數(shù),所以這是一個(gè)有效的創(chuàng)建繼承模式的方法,能夠重寫(xiě)原型鏈上的構(gòu)造函數(shù)。

function Thing1() {
    this.foo = "foo";
}
Thing1.prototype.foo = "bar";

function Thing2() {
    this.logFoo(); //logs "bar"
    Thing1.apply(this);
    this.logFoo(); //logs "foo"
}
Thing2.prototype = Object.create(Thing1.prototype);
Thing2.prototype.logFoo = function () {
    console.log(this.foo);
}

var thing = new Thing2();
四. 對(duì)象中的this

可以在對(duì)象的任何函數(shù)中使用this來(lái)引用該對(duì)象上的其他屬性。這與使用new實(shí)例不同。

var obj = {
    foo: "bar",
    logFoo: function () {
        console.log(this.foo);
    }
};

obj.logFoo(); //logs "bar"

不使用new,Object.create ,function 去創(chuàng)建一個(gè)對(duì)象,也可以像實(shí)例化一樣綁定到對(duì)象上。

var obj = {
    foo: "bar"
};

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

logFoo.apply(obj); //logs "bar"

當(dāng)你像下面使用this時(shí),沒(méi)有順著對(duì)象的層次結(jié)構(gòu)。只有直接父對(duì)象上的屬性才能通過(guò)this進(jìn)行訪問(wèn)

var obj = {
    foo: "bar",
    deeper: {
        logFoo: function () {
            console.log(this.foo);
        }
    }
};

obj.deeper.logFoo(); //logs undefined

你可以直接使用你想要的屬性。

var obj = {
    foo: "bar",
    deeper: {
        logFoo: function () {
            console.log(obj.foo);
        }
    }
};

obj.deeper.logFoo(); //logs "bar"
五. DOM event中的this

在一個(gè)HTML DOM event處理程序中,this通常是指DOM element event綁定的對(duì)象

function Listener() {
    document.getElementById("foo").addEventListener("click",
       this.handleClick);
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs "
" } var listener = new Listener(); document.getElementById("foo").click();

除非你綁定新的上下文

function Listener() {
    document.getElementById("foo").addEventListener("click", 
        this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs Listener {handleClick: function}
}

var listener = new Listener();
document.getElementById("foo").click();
六. HTML中的this

在HTML屬性中可以放js代碼,this指向當(dāng)前的元素

this的覆蓋
你不能夠復(fù)寫(xiě)this,因?yàn)樗且粋€(gè)關(guān)鍵詞

function test () {
    var this = {};  // Uncaught SyntaxError: Unexpected token this 
}
七. eavl中的this

可以使用eavl訪問(wèn)this

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    eval("console.log(this.foo)"); //logs "bar"
}

var thing = new Thing();
thing.logFoo();

這種做法有安全隱患,可以使用Function訪問(wèn)this

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = new Function("console.log(this.foo);");

var thing = new Thing();
thing.logFoo(); //logs "bar"
八. with中的this

可以使用withthis添加到當(dāng)前的范圍來(lái)讀取和寫(xiě)入值,而不用顯式調(diào)用。

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    with (this) {
        console.log(foo);
        foo = "foo";
    }
}

var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"

很多人認(rèn)為這是錯(cuò)的做法,鑒于with引起的歧義。

九. jQuery中的this

像HTML DOM elements的事件處理程序一樣,jQuery在很多地方使用this指向DOM元素。比如$.each

鑒于筆者翻譯水平有限,有什么問(wèn)題歡迎提出指教。

十.參考資料

原文地址:all this

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/80248.html

相關(guān)文章

  • 《JS編程全解》—— 回調(diào)函數(shù)

    摘要:事件驅(qū)動(dòng)正是一種回調(diào)函數(shù)設(shè)計(jì)模式。由于不支持多線程,所以為了實(shí)現(xiàn)并行處理,不得不使用回調(diào)函數(shù),這逐漸成為了一種慣例。上面的回調(diào)函數(shù)只是單純的函數(shù)而不具有狀態(tài)。如果回調(diào)函數(shù)具有狀態(tài),就能得到更為廣泛的應(yīng)用。 回調(diào)函數(shù)模式 回調(diào)函數(shù)與控制反轉(zhuǎn) 回調(diào)函數(shù)是程序設(shè)計(jì)的一種方法。這種方法是指,在傳遞了可能會(huì)進(jìn)行調(diào)用的函數(shù)或?qū)ο笾螅谛枰獣r(shí)再分別對(duì)其進(jìn)行調(diào)用。由于調(diào)用方與被調(diào)用方的依賴(lài)關(guān)系與通常...

    mj 評(píng)論0 收藏0
  • 全解小程序猜數(shù)字游戲 04《 程序員變現(xiàn)指南之 微信&QQ 小程序 真的零基礎(chǔ)開(kāi)發(fā)寶

    摘要:此時(shí)使用設(shè)置當(dāng)前值中的猜測(cè)值為輸入框的內(nèi)容值。接著判斷猜測(cè)之是否大于或者小于,因?yàn)檫@兩者是范圍之外不再進(jìn)行判斷,所以最開(kāi)始使用進(jìn)行判斷不能小于不能大于以上代碼中表示調(diào)用微信小程序接口彈出提示,傳入的參數(shù)為提示內(nèi)容。 ...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • lisahost:美國(guó)新的全解鎖原生IP 206段上架開(kāi)售,支持tiktok等,季付122元起

    摘要:怎么樣好不好最近美國(guó)新的全解鎖原生段上架開(kāi)售,支持等,原一期產(chǎn)品可加價(jià)更換年付免費(fèi)更換,美國(guó)原生段仍有少量剩余,套餐原價(jià)基礎(chǔ)上每月加價(jià)元可更換美國(guó)原生,更換的為純凈新分配美國(guó)段,絕對(duì)傳家寶產(chǎn)品,支持解鎖美區(qū)游戲,,等,同時(shí)支持。lisahost怎么樣?lisahost好不好?lisahost最近美國(guó)新的全解鎖原生IP 206段上架開(kāi)售,支持tiktok等,原CN2一期產(chǎn)品可加價(jià)更換(年付免費(fèi)...

    xingqiba 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<