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

資訊專欄INFORMATION COLUMN

JavaScript高級(jí)程序設(shè)計(jì)——this

darkbug / 2992人閱讀

摘要:另外注意,構(gòu)造函數(shù)的函數(shù)名第一個(gè)字母大寫規(guī)則約定。綁定函數(shù)被調(diào)用時(shí),也接受預(yù)設(shè)的參數(shù)提供給原函數(shù)。一個(gè)綁定函數(shù)也能使用操作符創(chuàng)建對(duì)象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。

前言

本來this應(yīng)該放在《上下文環(huán)境和作用域》中來講,結(jié)果發(fā)現(xiàn)自己整理的時(shí)候,例子越來越多,所以多帶帶寫一篇用于加深理解,以后工作或項(xiàng)目中發(fā)現(xiàn)一些this相關(guān)問題可以進(jìn)一步完善文章的例子。

this 概念

在函數(shù)中this到底取何值,是在函數(shù)真正被調(diào)用執(zhí)行的時(shí)候確定的,函數(shù)定義的時(shí)候確定不了

因?yàn)閠his的取值是執(zhí)行上下文環(huán)境的一部分,每次調(diào)用函數(shù),都會(huì)產(chǎn)生一個(gè)新的執(zhí)行上下文環(huán)境。

構(gòu)造函數(shù)

所謂構(gòu)造函數(shù)就是用來new對(duì)象的函數(shù)。其實(shí)嚴(yán)格來說,所有的函數(shù)都可以new一個(gè)對(duì)象,但是有些函數(shù)的定義是為了new一個(gè)對(duì)象,而有些函數(shù)則不是。另外注意,構(gòu)造函數(shù)的函數(shù)名第一個(gè)字母大寫(規(guī)則約定)。例如:Object、Array、Function等。

function Foo() {
            this.name = "yzh";
            this.year = 1996;
            console.log(this); //Object { name: "yzh", year: 1998 }
        }
        var f1 = new Foo();
        console.log(f1.name); //yzh
        console.log(f1.year); //1996

以上代碼中,如果函數(shù)作為構(gòu)造函數(shù)用,那么其中的this就代表它即將new出來的對(duì)象。

注意,以上僅限newFoo()的情況,即Foo函數(shù)作為構(gòu)造函數(shù)的情況。如果直接調(diào)用Foo函數(shù),而不是new Foo(),情況就大不一樣了。

function Foo() {
            this.name = "yzh";
            this.year = 1996;
            console.log(this); //Object { name: "yzh", year: 1998 }
        }
        Foo();  //window

這種情況下this是window。

函數(shù)作為對(duì)象的一個(gè)屬性

如果函數(shù)作為對(duì)象的一個(gè)屬性時(shí),并且作為對(duì)象的一個(gè)屬性被調(diào)用時(shí),函數(shù)中的this指向該對(duì)象。

var obj = {
            x: 10,
            fn: function() {
                console.log(this); //Object { x: 10, fn: fn() }
                console.log(this.x); //10
            }
        };
        obj.fn();

以上代碼中,fn不僅作為一個(gè)對(duì)象的一個(gè)屬性,而且的確是作為對(duì)象的一個(gè)屬性被調(diào)用。結(jié)果this就是obj對(duì)象。

如果fn函數(shù)不作為obj的一個(gè)屬性被調(diào)用,會(huì)是什么結(jié)果呢?

var obj = {
            x: 10,
            fn: function() {
                console.log(this); //window
                console.log(this.x); //undefined
            }
        };
        var f1 = obj.fn;
        f1();

如上代碼,如果fn函數(shù)被賦值到了另一個(gè)變量中,并沒有作為obj的一個(gè)屬性被調(diào)用,那么this的值就是window,this.x為undefined。

函數(shù)用call或者apply調(diào)用

為了防止看不懂這塊先理解下基礎(chǔ)并重要的東西

函數(shù)內(nèi)部屬性

在函數(shù)內(nèi)部,有兩個(gè)特殊的對(duì)象:arguments和this.
主要介紹下arguments,它是類數(shù)組對(duì)象,包含傳入函數(shù)的所有參數(shù),這個(gè)對(duì)象還有一個(gè)叫callee的屬性,該屬性為一個(gè)指針,指向擁有這個(gè)arguments對(duì)象的函數(shù)。

這個(gè)例子主要用于消除函數(shù)的執(zhí)行與同名函數(shù)的緊密耦合現(xiàn)象。代碼如下:

function factorial(num) {
            if (num <= 1) {
                return 1;
            } else {
               // return num * factorial(num - 1);
                //1.一般的遞歸算法運(yùn)用
                return num * arguments.callee(num - 1) 
                //2.更好的做法
            }
        }

        var trueFactorial = factorial;

        factorial = function() {
            return 0;
        };

        alert(trueFactorial(5)); //120
        alert(factorial(5)); //0
函數(shù)屬性

每個(gè)函數(shù)都包含兩個(gè)屬性:length和prototype.
length表示函數(shù)希望接受的命名參數(shù)的個(gè)數(shù)

function sayName(name){
            alert(name);
        }      
        
        function sum(num1, num2){
            return num1 + num2;
        }
        
        function sayHi(){
            alert("hi");
        }
        
        alert(sayName.length);  //1
        alert(sum.length);      //2
        alert(sayHi.length);    //0

prototype屬性這里不再重復(fù)介紹。

函數(shù)方法

每個(gè)函數(shù)都包含兩個(gè)非繼承而來的方法:apply()和call(),這兩個(gè)方法的用途都是在特定的作用域中調(diào)用函數(shù),實(shí)際上等于設(shè)置函數(shù)體內(nèi)的this對(duì)象值。

apply()方法接受兩個(gè)參數(shù):一個(gè)是在其中運(yùn)行函數(shù)的作用域,另一個(gè)是參數(shù)數(shù)組。

function sum(num1, num2){
            return num1 + num2;
        }
        
        function callSum1(num1, num2){
            return sum.apply(this, arguments);
        }
        
        function callSum2(num1, num2){
            return sum.apply(this, [num1, num2]);
        }
        
        alert(callSum1(10,10));   //20
        alert(callSum2(10,10));   //20

callsSum1()執(zhí)行sum()函數(shù)時(shí)傳入this作為this值(在全局作用域中調(diào)用,所以傳入的對(duì)象為window對(duì)象)下面的例子同理。

call()方法與apply()方法差不多,區(qū)別在于接受參數(shù)的方式不同。簡(jiǎn)單來說就是:傳遞給函數(shù)的參數(shù)必須逐個(gè)列舉出來。(如果是無(wú)參函數(shù)就不用傳參數(shù))

function sum(num1, num2){
            return num1 + num2;
        }
        
        function callSum(num1, num2){
            return sum.call(this, num1, num2);
        }
        
        alert(callSum(10,10));   //20

傳遞參數(shù)并非兩個(gè)函數(shù)的真正用武之地,真正強(qiáng)大的地方是擴(kuò)充函數(shù)賴以運(yùn)行的作用域

window.color = "red";
        var o = { color: "blue" };
        
        function sayColor(){
            alert(this.color);
        }
        
        sayColor();            //red
        
        sayColor.call(this);   //red
        sayColor.call(window); //red
        sayColor.call(o);      //blue

如下代碼如果不用函數(shù)的方法來實(shí)現(xiàn)。

window.color = "red";
        var o = { color: "blue" };
        
        function sayColor(){
            alert(this.color);
        }
        
        sayColor();     //red
        
        o.sayColor = sayColor;
        o.sayColor();   //blue

如果要輸出o對(duì)象里的color屬性值,必須把sayColor函數(shù)賦給對(duì)象o并調(diào)用 o.sayColor()時(shí),this引用的對(duì)象為o

回歸要講的例子

當(dāng)一個(gè)函數(shù)被call和apply調(diào)用時(shí),this的值就取傳入的對(duì)象的值。

var obj = {
            x: 10
        };
        var fn = function() {
            console.log(this); //Object { x: 10 }
            console.log(this.x); //10
        };
        fn.call(obj);
全局 & 調(diào)用普通函數(shù)

在全局環(huán)境下,this永遠(yuǎn)是window,這個(gè)應(yīng)該沒有非議。

console.log(this === window); //true

普通函數(shù)在調(diào)用時(shí),其中的this也都是window。

var x = 10;
        var fn = function() {
            console.log(this); //window
            console.log(this.x); //10
        }
        fn();

注意以下的情況

var obj = {
            x: 10,
            fn: function() {
                function f() {
                    console.log(this); //Window 
                    console.log(this.x); //undefined
                }
                f();
            }
        };
        obj.fn();

函數(shù)f雖然是在obj.fn內(nèi)部定義的,但是它仍然是一個(gè)普通的函數(shù),this仍然指向window。

總結(jié):this指向調(diào)用該函數(shù)的對(duì)象

構(gòu)造函數(shù)的prototype中,this代表著什么
function Fn() {
            this.name = "yzh";
            this.year = 1996;
        }
        Fn.prototype.getName = function() {
            console.log(this.name);
        }
        var f1 = new Fn();
        f1.getName(); //yzh

在Fn.prototype.getName函數(shù)中,this指向的是f1對(duì)象。因此可以通過this.name獲取f1.name的值

bind()

bind()方法創(chuàng)建一個(gè)新的函數(shù), 當(dāng)被調(diào)用時(shí),它的this關(guān)鍵字被設(shè)置為提供的值 ,在調(diào)用新函數(shù)時(shí),提供任何一個(gè)給定的參數(shù)序列。

這個(gè)函數(shù)其實(shí)也很重要,只是當(dāng)時(shí)紅寶書也沒提及很多。

語(yǔ)法

fun.bind(thisArg[, arg1[, arg2[, ...]]])

參數(shù)

thisArg

當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的 this 指向。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無(wú)效。

arg1, arg2, ...

當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)將置于實(shí)參之前傳遞給被綁定的方法。
返回值

返回由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝

描述

bind() 函數(shù)會(huì)創(chuàng)建一個(gè)新函數(shù)(稱為綁定函數(shù)),新函數(shù)與被調(diào)函數(shù)(綁定函數(shù)的目標(biāo)函數(shù))具有相同的函數(shù)體(在 ECMAScript 5 規(guī)范中內(nèi)置的call屬性)。當(dāng)目標(biāo)函數(shù)被調(diào)用時(shí) this 值綁定到 bind() 的第一個(gè)參數(shù),該參數(shù)不能被重寫。綁定函數(shù)被調(diào)用時(shí),bind() 也接受預(yù)設(shè)的參數(shù)提供給原函數(shù)。一個(gè)綁定函數(shù)也能使用new操作符創(chuàng)建對(duì)象:這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。提供的 this 值被忽略,同時(shí)調(diào)用時(shí)的參數(shù)被提供給模擬函數(shù)。

示例

創(chuàng)建綁定函數(shù)

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在這種情況下,"this"指向全局作用域

// 創(chuàng)建一個(gè)新函數(shù),將"this"綁定到module對(duì)象
// 新手可能會(huì)被全局的x變量和module里的屬性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81
End

歡迎拍磚,有更多的好的例子,歡迎提出,文中有誤的地方也歡迎指正。

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

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

相關(guān)文章

  • javascript高級(jí)程序設(shè)計(jì)》筆記:繼承

    摘要:繼承和前面兩篇文章中的知識(shí)非常相關(guān),如果對(duì)函數(shù)創(chuàng)建原理和原型鏈不熟悉,請(qǐng)猛戳高級(jí)程序設(shè)計(jì)筆記創(chuàng)建對(duì)象高級(jí)程序設(shè)計(jì)筆記原型圖解繼承,通俗的說,就是將自身不存在的屬性或方法,通過某種方式為自己所用文章分別介紹原型鏈繼承繼承借用構(gòu)造函數(shù)繼承組合繼 繼承和前面兩篇文章中的知識(shí)非常相關(guān),如果對(duì)函數(shù)創(chuàng)建原理和原型鏈不熟悉,請(qǐng)猛戳:《javascript高級(jí)程序設(shè)計(jì)》筆記:創(chuàng)建對(duì)象《javascri...

    JerryC 評(píng)論0 收藏0
  • 《你不知道的javascript》筆記_對(duì)象&原型

    摘要:上一篇你不知道的筆記寫在前面這是年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響年是向上的一年在新的城市穩(wěn)定連續(xù)堅(jiān)持健身三個(gè)月早睡早起游戲時(shí)間大大縮減,學(xué)會(huì)生活。 上一篇:《你不知道的javascript》筆記_this 寫在前面 這是2019年第一篇博客,回顧去年年初列的學(xué)習(xí)清單,發(fā)現(xiàn)僅有部分完成了。當(dāng)然,這并不影響2018年是向上的一年:在新的城市穩(wěn)定、...

    seasonley 評(píng)論0 收藏0
  • JavaScript 高級(jí)技巧

    摘要:如果直接調(diào)用構(gòu)造函數(shù),那么會(huì)指向全局對(duì)象然后你的代碼就會(huì)覆蓋的原生。凍結(jié)對(duì)象最嚴(yán)格的防篡改就是凍結(jié)對(duì)象。中央定時(shí)器動(dòng)畫地址參考書籍高級(jí)程序設(shè)計(jì)忍者秘籍 1 安全類型檢測(cè) javascript內(nèi)置類型檢測(cè)并不可靠 safari某些版本( var person = {name: wdd}; undefined > Object.preventExtensions(person); Obj...

    wean 評(píng)論0 收藏0
  • javascript高級(jí)程序設(shè)計(jì)》之事件

    摘要:特性這樣指定事件處理程序具有一些獨(dú)到之處。級(jí)事件處理程序通過獲得要操作對(duì)象的引用,用把一個(gè)函數(shù)賦值給一個(gè)事件處理程序?qū)傩裕热?。以這種方式添加的事件處理程序會(huì)在事件流的冒泡階段被捕獲。級(jí)事件處理程序級(jí)事件定義了兩個(gè)方法,。 一、事件處理程序 響應(yīng)某個(gè)事件的函數(shù)叫做事件處理程序(或事件偵聽器),為事件指定處理程序的方式有下面幾種。 1、html特性 這樣指定事件處理程序具有一些獨(dú)到之處...

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

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

0條評(píng)論

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