JavaScript面向?qū)ο蠛诵闹R(shí)與概念歸納整理
本文實(shí)例講述了JavaScript面向?qū)ο蠛诵闹R(shí)與概念。分享給大家供大家參考,具體如下:
一、面向?qū)ο?.1 概念 面向?qū)ο缶褪鞘褂脤?duì)象。面向?qū)ο箝_(kāi)發(fā)就是使用對(duì)象開(kāi)發(fā)。 面向過(guò)程就是用過(guò)程的方式進(jìn)行開(kāi)發(fā)。面向?qū)ο笫菍?duì)面向過(guò)程的封裝。1.2 三大特性抽象性所謂的抽象性就是:如果需要一個(gè)對(duì)象描述數(shù)據(jù),需要抽取這個(gè)對(duì)象的核心數(shù)據(jù)
提出需要的核心屬性和方法 不在特定的環(huán)境下無(wú)法明確對(duì)象的具體意義封裝性對(duì)象是將數(shù)據(jù)與功能組合到一起,即封裝
JS對(duì)象就是鍵值對(duì)的集合,鍵值如果是數(shù)據(jù)(基本數(shù)據(jù)、符合數(shù)據(jù)、空數(shù)據(jù))就稱(chēng)為屬性,如果鍵值是函數(shù)那么就稱(chēng)為方法 對(duì)象就是將屬性與方法封裝起來(lái) 方法是將過(guò)程封裝起來(lái)繼承性所謂繼承性就是自己沒(méi)有但是別人有,拿過(guò)來(lái)成為自己的,就是繼承,繼承是實(shí)現(xiàn)復(fù)用的一種手段
在Java等語(yǔ)言中繼承滿足一個(gè)class的規(guī)則,類(lèi)是一個(gè)class,他規(guī)定了一個(gè)對(duì)象有什么屬性和方法。 在這些語(yǔ)言中繼承是class之間的繼承,一個(gè)class繼承另一個(gè)class,那么該class就有了另一個(gè)class的成員,那么由該class創(chuàng)建出來(lái)的對(duì)象就同時(shí)具有兩個(gè)class的成員。在JS中沒(méi)有明確的繼承語(yǔ)法(ES6提供了class extend語(yǔ)法),一般都是按照繼承的理念實(shí)現(xiàn)對(duì)象的成員擴(kuò)充實(shí)現(xiàn)繼承,因此JS中實(shí)現(xiàn)繼承的方法非常對(duì)多。
傳統(tǒng)繼承基于類(lèi),JS繼承基于對(duì)象
一個(gè)簡(jiǎn)單的繼承模式:混入(mix)
function mix ( o1, o2 ) { for ( var k in o2 ) { o1[ k ] = o2[ k ]; }}1.3 關(guān)于面向?qū)ο蟮囊恍┢渌拍?p>類(lèi)class:在JS中就是構(gòu)造函數(shù)
在傳統(tǒng)的面向?qū)ο笳Z(yǔ)言中,使用一個(gè)叫類(lèi)的東西定義模板,然后使用模板創(chuàng)建對(duì)象。 在構(gòu)造方法中也具有類(lèi)似的功能,因此也稱(chēng)其為類(lèi)實(shí)例(instance)與對(duì)象(object)
實(shí)例一般是指某一個(gè)構(gòu)造函數(shù)創(chuàng)建出來(lái)的對(duì)象,我們稱(chēng)為XXXX 構(gòu)造函數(shù)的實(shí)例 實(shí)例就是對(duì)象。對(duì)象是一個(gè)泛稱(chēng) 實(shí)例與對(duì)象是一個(gè)近義詞鍵值對(duì)與屬性和方法
在JS中鍵值對(duì)的集合稱(chēng)為對(duì)象 如果值為數(shù)據(jù)(非函數(shù)),就稱(chēng)該鍵值對(duì)為屬性 如果值為函數(shù)(方法),就稱(chēng)該鍵值對(duì)為方法method父類(lèi)與子類(lèi)(基類(lèi)和派生類(lèi))
傳統(tǒng)的面向?qū)ο笳Z(yǔ)言中使用類(lèi)來(lái)實(shí)現(xiàn)繼承那么就有父類(lèi)、子類(lèi)的概念 父類(lèi)又稱(chēng)為基類(lèi),子類(lèi)又稱(chēng)為派生類(lèi) 在JS中沒(méi)有類(lèi)的概念,在JS中常常稱(chēng)為父對(duì)象,子對(duì)象,基對(duì)象,派生對(duì)象。二、構(gòu)造函數(shù)2.1 構(gòu)造函數(shù)是干什么用的 初始化數(shù)據(jù)的 在JS中給對(duì)象添加屬性用的,初始化屬性值用的2.2 創(chuàng)建對(duì)象的過(guò)程 代碼:var p = new Person();首先運(yùn)算符new創(chuàng)建了一個(gè)對(duì)象,類(lèi)似于{},是一個(gè)沒(méi)有任何(自定義)成員的對(duì)象。
使用new 創(chuàng)建對(duì)象,那么對(duì)象的類(lèi)型就是創(chuàng)建他的構(gòu)造函數(shù)名 使用{}無(wú)論如何都是Object類(lèi)型,相當(dāng)于new Object然后調(diào)用構(gòu)造函數(shù),為其初始化成員
構(gòu)造函數(shù)在調(diào)用的一開(kāi)始,有一個(gè)賦值操作,即this = 剛剛創(chuàng)建出來(lái)的對(duì)象。 因此在構(gòu)造函數(shù)中this表示剛剛創(chuàng)建出來(lái)的對(duì)象。 在構(gòu)造函數(shù)中 利用 對(duì)象的動(dòng)態(tài)特性 為其對(duì)象添加成員。三、作用域3.1 什么是作用域域表示的就是范圍,即作用域,就是一個(gè)名字在什么地方可以使用,什么時(shí)候不能使用。簡(jiǎn)單的說(shuō),作用域是針對(duì)變量的,比如我們創(chuàng)建一個(gè)函數(shù) a1,函數(shù)里面又包了一個(gè)子函數(shù) a2。
// 全局作用域functiona a1() { // a1作用域 function a2() { // a2作用域 }}
此時(shí)就存 在三個(gè)作用域:全局作用域,a1 作用域,a2 作用域;即全局作用域包含了 a1 的作用域,a2 的作用域包含了 a1 的作用域。
當(dāng) a2 在查找變量的時(shí)候會(huì)先從自身的作用域區(qū)查找,找不到再到上一級(jí) a1 的作用域查找,如果還沒(méi)找到就到全局作用域區(qū)查找,這樣就形成了一個(gè)作用域鏈。
3.2 JS中詞法作用域的規(guī)則 函數(shù)允許訪問(wèn)函數(shù)外部的數(shù)據(jù) 整個(gè)代碼結(jié)構(gòu)中只有函數(shù)可以限定作用域 作用規(guī)則首先使用提升規(guī)則分析 如果當(dāng)前作用域中有了名字了,就不考慮外面的名字3.3 屬性搜索原則 所謂的屬性搜索原則,就是對(duì)象在訪問(wèn)屬性或方法的時(shí)候,首先在當(dāng)前對(duì)象中查找 如果當(dāng)前對(duì)象中存儲(chǔ)著屬性或方法,停止查找,直接使用該屬性或方法 如果當(dāng)前對(duì)象沒(méi)有該成員,那么再在其原型對(duì)象中查找 如果原型對(duì)象中含有該成員,那么停止查找,直接使用 如果原型中還沒(méi)有,就到原型的原型中查找 如此往復(fù),直到Object.protitype還沒(méi)有,那么就返回undefined 如果是調(diào)用方法就報(bào)錯(cuò),該xxx不是一個(gè)函數(shù)四、閉包4.1 說(shuō)說(shuō)你對(duì)閉包的理解實(shí)用閉包主要是為了設(shè)計(jì)私有方法和變量。閉包的優(yōu)點(diǎn)是可以避免全局變量的污染;缺點(diǎn)是閉包會(huì)常駐內(nèi)存,增加內(nèi)存使用量,使用不當(dāng)很容易造成內(nèi)存泄露。在JavaScript中,函數(shù)即閉包,只有函數(shù)才能產(chǎn)生作用域。
閉包有3個(gè)特性:
函數(shù)嵌套函數(shù) 在函數(shù)內(nèi)部可以引用外部的參數(shù)和變量 參數(shù)和變量不會(huì)以垃圾回收機(jī)制回收4.2 閉包有什么用(特性)閉包的作用,就是保存自己私有的變量,通過(guò)提供的接口(方法)給外部使用,但外部不能直接訪問(wèn)該變量。通過(guò)使用閉包,我們可以做很多事情,比如模擬面向?qū)ο蟮拇a風(fēng)格;更優(yōu)雅,更簡(jiǎn)潔的表達(dá)出代碼;在某些方面提升代碼的執(zhí)行效率。利用閉包可以實(shí)現(xiàn)如下需求:
匿名自執(zhí)行函數(shù)一個(gè)匿名的函數(shù),并立即執(zhí)行它,由于外部無(wú)法引用它內(nèi)部的變量,因此在執(zhí)行完后很快就會(huì)被釋放,關(guān)鍵是這種機(jī)制不會(huì)污染全局對(duì)象。
緩存閉包正是可以做到這一點(diǎn),因?yàn)樗粫?huì)釋放外部的引用,從而函數(shù)內(nèi)部的值可以得以保留。
實(shí)現(xiàn)封裝 模擬面向?qū)ο蟮拇a風(fēng)格4.3 閉包的基本模型對(duì)象模式函數(shù)內(nèi)部定義個(gè)一個(gè)對(duì)象,對(duì)象中綁定多個(gè)函數(shù)(方法),返回對(duì)象,利用對(duì)象的方法訪問(wèn)函數(shù)內(nèi)的數(shù)據(jù)
function createPerson() { var __name__ = ''; return { getName: function () { return __name__; }, setName: function( value ) { // 如果不姓張就報(bào)錯(cuò) if ( value.charAt(0) === ’張’ ) { __name__ = value; } else { throw new Error( ’姓氏不對(duì),不能取名’ ); } } }}var p = createPerson();p.set_Name( ’張三豐’ );console.log( p.get_Name() );p.set_Name( ’張王富貴’ );console.log( p.get_Name() );
函數(shù)模式函數(shù)內(nèi)部定義一個(gè)新函數(shù),返回新函數(shù),用新函數(shù)獲得函數(shù)內(nèi)的數(shù)據(jù)
function foo() { var num = Math.random(); function func() { return mun; } return func;}var f = foo();// f 可以直接訪問(wèn)這個(gè) numvar res1 = f();var res2 = f();
沙箱模式沙箱模式就是一個(gè)自調(diào)用函數(shù),代碼寫(xiě)到函數(shù)中一樣會(huì)執(zhí)行,但是不會(huì)與外界有任何的影響,比如jQuery
(function () { var jQuery = function () { // 所有的算法 } // .... // .... jQuery.each = function () {} window.jQuery = window.$ = jQuery;})();$.each( ... )4.4 閉包的性能問(wèn)題
js 垃圾回收機(jī)制,也就是當(dāng)一個(gè)函數(shù)被執(zhí)行完后,其作用域會(huì)被收回,如果形成了閉包,執(zhí)行完后其作用域就不會(huì)被收回。
函數(shù)執(zhí)行需要內(nèi)存,那么函數(shù)中定義的變量,會(huì)在函數(shù)執(zhí)行結(jié)束后自動(dòng)回收,凡是因?yàn)殚]包結(jié)構(gòu)的,被引出的數(shù)據(jù),如果還有變量引用這些數(shù)據(jù)的話,那么這些數(shù)據(jù)就不會(huì)被回收。因此在使用閉包的時(shí)候如果不使用某些數(shù)據(jù)了,一定要賦值一個(gè)null
var f = (function () { var num = 123; return function () { return num; };})();// f 引用著函數(shù),函數(shù)引用著變量num// 因此在不使用該數(shù)據(jù)的時(shí)候,最好寫(xiě)上f = null;五、原型5.1 什么是原型
一句話說(shuō)明什么是原型:原型能存儲(chǔ)我們的方法,構(gòu)造函數(shù)創(chuàng)建出來(lái)的實(shí)例對(duì)象能夠引用原型中的方法。
JS中一切皆對(duì)象,而每個(gè)對(duì)象都有一個(gè)原型(Object除外),這個(gè)原型,大概就像Java中的父類(lèi),所以,基本上你可以認(rèn)為原型就是這個(gè)對(duì)象的父對(duì)象,即每一個(gè)對(duì)象(Object除外)內(nèi)部都保存了它自己的父對(duì)象,這個(gè)父對(duì)象就是原型。一般創(chuàng)建的對(duì)象如果沒(méi)有特別指定原型,那么它的原型就是Object(這就很類(lèi)似Java中所有的類(lèi)默認(rèn)繼承自O(shè)bject類(lèi))。
ES6通過(guò)引入class ,extends等關(guān)鍵字,以一種語(yǔ)法糖的形式把構(gòu)造函數(shù)包裝成類(lèi)的概念,更便于大家理解。是希望開(kāi)發(fā)者不再花精力去關(guān)注原型以及原型鏈,也充分說(shuō)明原型的設(shè)計(jì)意圖和類(lèi)是一樣的。
5.2 查看對(duì)象的原型當(dāng)對(duì)象被創(chuàng)建之后,查看它們的原型的方法不止一種,以前一般使用對(duì)象的__proto__屬性,ES6推出后,推薦用Object.getPrototypeOf()方法來(lái)獲取對(duì)象的原型
function A(){ this.name=’lala’;}var a=new A();console.log(a.__proto__) //輸出:Object {} //推薦使用這種方式獲取對(duì)象的原型console.log(Object.getPrototypeOf(a)) //輸出:Object {}
無(wú)論對(duì)象是如何創(chuàng)建的,默認(rèn)原型都是Object,在這里需要提及的比較特殊的一點(diǎn)就是,通過(guò)構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象,函數(shù)A本身也是一個(gè)對(duì)象,而A有兩個(gè)指向表示原型的屬性,分別是__proto__和prototype,而且兩個(gè)屬性并不相同
function A(){ this.name=’lala’;}var a=new A();console.log(A.prototype) //輸出:Object {} console.log(A.__proto__) //輸出:function () {}console.log(Object.getPrototypeOf(A))//輸出:function () {}
函數(shù)的的prototype屬性只有在當(dāng)作構(gòu)造函數(shù)創(chuàng)建的時(shí)候,把自身的prototype屬性值賦給對(duì)象的原型。而實(shí)際上,作為函數(shù)本身,它的原型應(yīng)該是function對(duì)象,然后function對(duì)象的原型才是Object。
總之,建議使用ES6推薦的查看原型和設(shè)置原型的方法。
5.3 原型的用法其實(shí)原型和類(lèi)的繼承的用法是一致的:當(dāng)你想用某個(gè)對(duì)象的屬性時(shí),將當(dāng)前對(duì)象的原型指向該對(duì)象,你就擁有了該對(duì)象的使用權(quán)了。
function A(){ this.name=’world ’;}function B(){ this.bb='hello'}var a=new A();var b=new B();//將b設(shè)置為a的原型,此處有一個(gè)問(wèn)題,即a的constructor也指向了B構(gòu)造函數(shù),可能需要糾正 Object.setPrototypeOf(a,b);a.constructor=A;console.log(a.bb); //hello
如果使用ES6來(lái)做的話則簡(jiǎn)單許多,甚至不涉及到prototype這個(gè)屬性
class B{ constructor(){ this.bb=’hello’ }}class A extends B{ constructor(){ super(); this.name=’world’; }} var a=new A();console.log(a.bb+' '+a.name); //hello worldconsole.log(typeof(A)) //'function'
怎么樣?是不是已經(jīng)完全看不到原型的影子了?活脫脫就是類(lèi)繼承,但是你也看得到實(shí)際上類(lèi)A 的類(lèi)型是function,所以說(shuō),本質(zhì)上class在JS中是一種語(yǔ)法糖,JS繼承的本質(zhì)依然是原型,不過(guò),ES6引入class,extends 來(lái)掩蓋原型的概念也是一個(gè)很友好的舉動(dòng),對(duì)于長(zhǎng)期學(xué)習(xí)那些類(lèi)繼承為基礎(chǔ)的面對(duì)對(duì)象編程語(yǔ)言的程序員而言。
我的建議是,盡可能理解原型,盡可能用class這種語(yǔ)法糖。
好了,問(wèn)自己兩個(gè)問(wèn)題:
為什么要使用原型?——提高函數(shù)的復(fù)用性。為什么屬性不放在原型上而方法要放在原型上?
利用對(duì)象的動(dòng)態(tài)特性:構(gòu)造函數(shù).prototype.xxxx = vvv 利用直接替換Student.prototype = {sayHello : function(){},study : function(){}}; 5.4 原型鏈
什么是原型鏈? 凡是對(duì)象就有原型,那么原型又是對(duì)象,因此凡是給定一個(gè)對(duì)象,那么就可以找到他的原型,原型還有原型,那么如此下去,就構(gòu)成一個(gè)對(duì)象的序列,稱(chēng)該結(jié)構(gòu)為原型鏈。
每個(gè)實(shí)例對(duì)象都有一個(gè)__proto_屬性,該屬性指向它原型對(duì)象,這個(gè)實(shí)例對(duì)象 的構(gòu)造函數(shù)有一個(gè)原型屬性 prototype,與實(shí)例的__proto__屬性指向同一個(gè)對(duì)象。當(dāng)一個(gè)對(duì)象在查找一個(gè)屬性的時(shí), 自身沒(méi)有就會(huì)根據(jù)__proto__ 向它的原型進(jìn)行查找,如果都沒(méi)有,則向它的原型的原型繼續(xù)查找,直到查到 Object.prototype._proto_為 null,這樣也就形成了原型鏈。這個(gè)概念其實(shí)也變得比較簡(jiǎn)單,可以類(lèi)比類(lèi)的繼承鏈條,即每個(gè)對(duì)象的原型往上追溯,一直到Object為止,這組成了一個(gè)鏈條,將其中的對(duì)象串聯(lián)起來(lái),當(dāng)查找當(dāng)前對(duì)象的屬性時(shí),如果沒(méi)找到,就會(huì)沿著這個(gè)鏈條去查找,一直到Object,如果還沒(méi)發(fā)現(xiàn),就會(huì)報(bào)undefined。
原型鏈的結(jié)構(gòu)凡是使用構(gòu)造函數(shù),創(chuàng)建出對(duì)象,并且沒(méi)有利用賦值的方式修改原型,就說(shuō)該對(duì)象保留默認(rèn)的原型鏈。默認(rèn)原型鏈結(jié)構(gòu)是什么樣子呢?
function Person(){}var p = new Person();//p 具有默認(rèn)的原型鏈
默認(rèn)的原型鏈結(jié)構(gòu)就是:當(dāng)前對(duì)象 -> 構(gòu)造函數(shù).prototype -> Object.prototype -> null
在實(shí)現(xiàn)繼承的時(shí)候,有時(shí)候會(huì)利用替換原型鏈結(jié)構(gòu)的方式實(shí)現(xiàn)原型繼承,那么原型鏈結(jié)構(gòu)就會(huì)發(fā)生改變
function DunizbCollection(){}DunizbCollection.prototype = [];var arr = new DunizbCollection();
此時(shí)arr對(duì)象的原型鏈結(jié)構(gòu)被指向了數(shù)組對(duì)象的原型鏈結(jié)構(gòu)了:arr -> [] -> Array.prototype -> Object.prototype -> null
用圖形表示對(duì)象的原型鏈結(jié)構(gòu)以如下代碼為例繪制原型鏈結(jié)構(gòu)
function Person(){}var p = new Person();
原型鏈結(jié)構(gòu)圖為:
使用原型需要注意兩點(diǎn):
原型繼承鏈條不要太長(zhǎng),否則會(huì)出現(xiàn)效率問(wèn)題。 指定原型時(shí),注意constructor也會(huì)改變。六、繼承實(shí)現(xiàn)繼承有兩種常見(jiàn)方式:
6.1 混合式繼承最簡(jiǎn)單的繼承就是將別的對(duì)象的屬性強(qiáng)加到我身上,那么我就有這個(gè)成員了?;旌鲜嚼^承的簡(jiǎn)單描述:
function Person() {};Person.prototype.extend = function ( o ) { for ( var k in o ) { this[ k ] = o[ k ]; }};Person.prototype.extend({ run: function () { console.log( ’我能跑了’ ); }, eat: function () { console.log( ’我可以吃了’ ); }, sayHello: function () { console.log( ’我吃飽了’ ); }});6.2 原型繼承
利用原型也可以實(shí)現(xiàn)繼承,不需要在我身上添加任何成員,只要原型有了我就有了。
6.3 借用構(gòu)造函數(shù)繼承這種技術(shù)的基本思想相當(dāng)簡(jiǎn)單,即在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類(lèi)型構(gòu)造函數(shù),而函數(shù)只不過(guò)是在特定環(huán)境中執(zhí)行代碼的對(duì)象,因此通過(guò)使用apply()和call()方法也可以在(將來(lái))新創(chuàng)建的對(duì)象上執(zhí)行構(gòu)造函數(shù)
function Person ( name, age, gender ) { this.name = name; this.age = age; this.gender = gender;}// 需要提供一個(gè) Student 的構(gòu)造函數(shù)創(chuàng)建學(xué)生對(duì)象// 學(xué)生也應(yīng)該有 name, age, gender, 同時(shí)還需要有 course 課程function Student ( name, age, gender, course ) { Person.call( this, name, age, gender ); this.course = course;}
在《JavaScript高級(jí)程序設(shè)計(jì)(第三版)》中詳細(xì)介紹了繼承的6種方式
七、函數(shù)的四種調(diào)用模式7.1 函數(shù)模式就是一個(gè)簡(jiǎn)單的函數(shù)調(diào)用。函數(shù)名的前面沒(méi)有任何引導(dǎo)內(nèi)容。
function foo () {}var func = function () {};...foo();func();(function () {} )();
this 的含義:在函數(shù)中 this 表示全局對(duì)象,在瀏覽器中式 window
7.2 方法模式方法一定式依附與一個(gè)對(duì)象,將函數(shù)賦值給對(duì)象的一個(gè)屬性,那么就成為了方法。
function f() { this.method = function () {};}var o = { method: function () {}}
this 的含義:這個(gè)依附的對(duì)象
7.3 構(gòu)造器調(diào)用模式創(chuàng)建對(duì)象的時(shí)候構(gòu)造函數(shù)做了什么?由于構(gòu)造函數(shù)只是給 this 添加成員,沒(méi)有做其他事情。而方法也可以完成這個(gè)操作,就是 this 而言,構(gòu)造函數(shù)與方法沒(méi)有本質(zhì)的區(qū)別。
特征:
使用 new 關(guān)鍵字,來(lái)引導(dǎo)構(gòu)造函數(shù)。 構(gòu)造函數(shù)中的 this 與方法中的一樣,表示對(duì)象,但是構(gòu)造函數(shù)中的對(duì)象是剛剛創(chuàng)建出來(lái)的對(duì)象構(gòu)造函數(shù)中不需要 return ,就會(huì)默認(rèn)的 return this。
如果手動(dòng)添加return ,就相當(dāng)于 return this 如果手動(dòng)的添加 return 基本類(lèi)型,無(wú)效,還是保留原來(lái) 返回 this 如果手動(dòng)添加的 return null,或 return undefined ,無(wú)效 如果手動(dòng)添加 return 對(duì)象類(lèi)型,那么原來(lái)創(chuàng)建的 this 就會(huì)被丟掉,返回的是 return 后面的對(duì)象 7.4 上下文調(diào)用模式上下文就是環(huán)境。就是自己定義設(shè)置 this 的含義。
語(yǔ)法
函數(shù)名.apply( 對(duì)象, [ 參數(shù) ] ); 函數(shù)名.call( 對(duì)象, 參數(shù) );描述
函數(shù)名就是表示函數(shù)本身,使用函數(shù)進(jìn)行調(diào)用的時(shí)候默認(rèn) this 是全局變量 函數(shù)名也可以是方法提供,使用方法調(diào)用的時(shí)候,this 是指向當(dāng)前對(duì)象 使用 apply 進(jìn)行調(diào)用后,無(wú)論是函數(shù)還是方法都無(wú)效了,我們的 this ,由 apply 的第一個(gè)參數(shù)決定參數(shù)問(wèn)題無(wú)論是 call 還是 apply 在沒(méi)有后面的參數(shù)的情況下(函數(shù)無(wú)參數(shù),方法五參數(shù))是完全一致的
function foo(){ console.log( this );}foo.apply( obj );foo.call( obj );
第一個(gè)參數(shù)的使用也是有規(guī)則的:
如果傳入的是一個(gè)對(duì)象,那么就相當(dāng)于設(shè)置該函數(shù)中的 this 為參數(shù) 如果不傳入?yún)?shù),或傳入 null、undefined 等,那么相當(dāng)于 this 默認(rèn)為 windowfoo();foo.apply();foo.apply( null ); 如果傳入的是基本類(lèi)型,那么 this 就是基本類(lèi)型對(duì)應(yīng)的包裝類(lèi)型的引用
在使用上下文調(diào)用的時(shí)候,原函數(shù)(方法)可能會(huì)帶有參數(shù),那么這個(gè)參數(shù)再上下文調(diào)用中使用 第二個(gè)(第 n 個(gè))參數(shù)來(lái)表示
function foo( num ) { console.log( num );}foo.apply( null, [ 123 ] );// 等價(jià)于foo( 123 );
參考資料
本文原型部分部分引用自《JavaScript原型詳解》,版權(quán)歸原作者所有 js閉包的用途感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
相關(guān)文章:
1. 理解PHP5中static和const關(guān)鍵字2. Android table布局開(kāi)發(fā)實(shí)現(xiàn)簡(jiǎn)單計(jì)算器3. jQuery 實(shí)現(xiàn)DOM元素拖拽交換位置的實(shí)例代碼4. IntelliJ IDEA安裝插件的方法步驟5. php模擬實(shí)現(xiàn)斗地主發(fā)牌6. vue 使用localstorage實(shí)現(xiàn)面包屑的操作7. Vue封裝一個(gè)TodoList的案例與瀏覽器本地緩存的應(yīng)用實(shí)現(xiàn)8. Python random庫(kù)使用方法及異常處理方案9. .Net Core使用Coravel實(shí)現(xiàn)任務(wù)調(diào)度的完整步驟10. Vuex localStorage的具體使用

網(wǎng)公網(wǎng)安備