JavaScript函數(shù)及其prototype詳解
一、定義
函數(shù)可以通過聲明定義,也可以是一個表達式。
(1)函數(shù)聲明式:
分號是用來分隔可執(zhí)行JavaScript語句,由于函數(shù)聲明不是一個可執(zhí)行語句,所以不以分號結束。
function a(){ console.log('bbb'); }
(2)函數(shù)表達式:
函數(shù)表達式以分號結尾,因為它是一個執(zhí)行語句。
var a = function(){ console.log('aaa'); }
(3)聲明式變體:
var a = function a(){ console.log('bbb'); }
完全等價于 function b(){}
二、函數(shù)執(zhí)行
JavaScript解析器將當前作用域內(nèi)聲明的所有變量和函數(shù)都會放到作用域的開始處,但是,只有變量的聲明被提前到作用域的開始處了,而賦值操作被保留在原處。
示例1:
var a = function(){ console.log('aaa'); } function a(){ console.log('bbb'); } a(); //結果:aaa
示例2:
(function() { console.log(noSuchVariable); })(); //報錯,因為noSuchVariable變量根本沒定義
</pre><pre name="code" class="javascript">(function() { console.log(declaredLater); //"undefined" var declaredLater = "Now it's defined!"; console.log(declaredLater); //"Now it's defined!" })(); //上面這段代碼是正確的,沒有任何問題。
示例3:
var a; // 聲明一個變量,標識符為a function a() {} // 聲明一個函數(shù),標示符也為a alert(typeof a); // function function a() {} var a; alert(typeof a); //function function a() {} var a = 1; alert(typeof a); //number var a = 1; function a() {} alert(typeof a); //number
總結:
- 變量的聲明被提前到作用域頂部,賦值保留在原地;
- 聲明式函數(shù)整個“被提前”;
- 函數(shù)表達式只有變量“被提前”了,函數(shù)沒有“被提前”;
- 函數(shù)會首先被提升,然后才是變量,重復的var(變量)聲明會被忽略掉;
- 同名情況下,變量先“被提前”,函數(shù)再“再被提前”(即函數(shù)覆蓋變量);
- 賦值會根據(jù)前后順序進行覆蓋!
三、函數(shù)是對象[typeof instanceof]
在 JavaScript 中使用 typeof 操作符判斷函數(shù)類型將返回"function"。但JavaScript函數(shù)描述為一個對象更加準確。JavaScript函數(shù)有屬性和方法。
(1)typeof區(qū)分對象和其他原始值
JavaScript的數(shù)據(jù)類型分為:原始類型(數(shù)字、字符串、布爾值、null、undefined)和對象類型。
typeof[任何類型]返回值(boolean、string、number、object、undefined)和 function
typeof 2; //'number' typeof '2'; //'string' typeof true; //'boolean' typeof []; //'object' typeof null; //'object' typeof undefined; //'undefined' var a = function(){}; typeof a; //'function'
對于所有內(nèi)置可執(zhí)行對象,typeof一律返回“function”
typeof new Number(2); //'object' typeof new String('2'); //'object' typeof new Boolean(true); //'object'
(2)instanceof[對象 instanceof 類]判斷一個對象是否為類的實例
[] instanceof Object; //true 2 instanceof Number; //false new Number(2) instanceof Number; //true
示例:
var a = function(){}; var b = function(){}; a.prototype = new b(); new a() instanceof b; //true new a() instanceof Object; //true
首先確定b.prototype,如果b.prototype在a對象的原型鏈中,返回true,否則返回false。
注意;所有對象都是Object的實例。
(3)擴展 Object.prototype.toString.call([]) === '[object Array]';
四、prototype
JavaScript 對象有兩種不同的屬性,一種是對象自身的屬性,另外一種是繼承于原型鏈上的屬性。
JavaScript中,類的所有實例對象都從同一個原型對象上繼承屬性,因此,原型對象是類的核心。
(1)只有函數(shù)有prototype,對象沒有
var b = {}; b.prototype.bbb='bbb'; //報錯b.prototype為undefined function b(){} b.prototype.bbb='bbb'; console.log(b); //結果:function b(){} console.log(b.prototype); //結果:b {bbb: "bbb"} console.log(b.bbb); //結果:undefined console.log(new b().bbb); //結果:bbb
(2)prototype是函數(shù)的內(nèi)置屬性(用于設置函數(shù)的原型),__proto__是對象的內(nèi)置屬性(用于設置對象的原型)。
PS:注意區(qū)分函數(shù)和對象
function test(){} test.prototype; //結果:test {} new test().prototype; //結果:undefined,對象沒有prototype new test().__proto__; //結果:test {} function a(){ this.v='vvv'; } a.prototype; //a {} new a.__proto__; //a {} new a().__proto__ === a.prototype; //true 實例對象的__proto__,指向函數(shù)的原型
(3)每個JavasScript函數(shù)都自動擁有一個prototype屬性。這個屬性的值是一個對象,這個對象包含唯一一個不可枚舉屬性constructor。constructor屬性的值是一個函數(shù)對象。
function a(){ this.v='vvv'; } a.prototype.constructor === a; //true[物理地址一樣] a.prototype.constructor; //constructor屬性指代這個類 a.prototype.constructor.__proto__ === a.__proto__ === Function.prototype; //true Object.prototype.constructor.__proto__ === Object.__proto__ === Function.prototype; //true
PS:所有構造器、函數(shù)的__proto__都指向Function.prototype,它是一個空函數(shù)(Empty function)
(4)實例
示例1:
function a(){} function b(){} a.prototype = {aaa:'aaa'}; b.prototype = a.prototype; var aa1 = new a(); var bb1 = new b(); //aa1.prototype.aaa='xxx'; //錯誤,對象沒有原型 a.prototype.aaa = 'xxx'; console.log( aa1.aaa ); //xxx console.log( bb1.aaa ); //xxx
補充:a===b; //false a.prototype === b.prototype; //true
實例2:
function a(){} function b(){ this.bbb='bbb'} a.prototype = new b(); //相當于a.prototype = {bbb: "bbb"}; console.log(new a().bbb ); //結果:bbb
補充:a.prototype === b.prototype; //false
五、實例方法&靜態(tài)方法
(1)實例方法
function a(){} a.prototype.count = 0; var a1 = new a(); a1.count++; var a2 = new a(); a2.count++; a.prototype.count; //0
PS:方法類似 a.prototype.method = function(){}
(2)靜態(tài)方法
function a(){} a.count = 0; new a().count(); //undefined,只能使用a.count調(diào)用
PS:方法類似 a.method = function(){}
(3)當代碼var p = new Person()執(zhí)行時,new 做了如下幾件事情:
A. 創(chuàng)建一個空白對象
B. 創(chuàng)建一個指向Person.prototype的指針
C. 將這個對象通過this關鍵字傳遞到構造函數(shù)中并執(zhí)行構造函數(shù)
六、閉包
函數(shù)定義時的作用域鏈到函數(shù)執(zhí)行時依然有效。
示例-典型閉包:
var scope = "global scope"; function checkScope(){ var scope = "local scope"; function f(){ return scope; } return f(); } checkScope(); //local scope
示例:更為常用的閉包
function counter(){ var n=0; return{ count:function(){ return ++n; }, reset:function(){ n=0; } }; } var c1 = new counter(); c1.count(); //1 var c2 = new counter(); c2.count(); //1 c1.reset(); //c1置為0,c2不受影響 c2.count(); //2
PS:實例對象互相不影響,單個實例對象內(nèi)的方法,共享私有變量。
七、通過調(diào)用方法的形式來間接調(diào)用函數(shù):apply&call
function a(){ console.log(this.x+this.y); } a.call({x:100,y:100}); //200 function C(){ this.m = function(){ console.log(this.x+this.y); } } var c = new C(); c.m.call({x:100,y:100}); //200
call&apply第一個實參是要調(diào)用函數(shù)的母對象,會變?yōu)閠his的值。
函數(shù).call(對象,參數(shù)1,參數(shù)2);
函數(shù).apply(對象,[參數(shù)1,參數(shù)2]); //數(shù)組形式
補充:
function a(a,b,c,d){ ? //將偽數(shù)組轉變?yōu)檎鏀?shù)組 ? var args = [].slice.call(arguments); }
八、函數(shù)中this
function a(){ console.log(this); //a {} function b(){ console.log(this); //window } b(); } new a();
特別注意:函數(shù)內(nèi)部函數(shù)this指向window
此問題在嚴格模式已被修改;在非嚴格模式中,可使用變量接收外部函數(shù)this供內(nèi)部函數(shù)使用,如var that = this;
九、回調(diào)(函數(shù)當參數(shù))
function a(callback){ callback(); } a(function(){ console.log('aaa'); });
更加靈活,主頁面只需為子頁面提供對應接口,具體處理邏輯全部由子頁面處理。
到此這篇關于JavaScript函數(shù)及其prototype詳解的文章就介紹到這了,更多相關JavaScript函數(shù)及其prototype內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- js中繼承的幾種用法總結(apply,call,prototype)
- js中的hasOwnProperty和isPrototypeOf方法使用實例
- JavaScript prototype 使用介紹
- js中prototype用法詳細介紹
- 詳解Javascript中prototype屬性(推薦)
- Javascript中Array.prototype.map()詳解
- JQuery,Extjs,YUI,Prototype,Dojo 等JS框架的區(qū)別和應用場景簡述
- 判斷js中各種數(shù)據(jù)的類型方法之typeof與0bject.prototype.toString講解
- JavaScript中的prototype使用說明
相關文章
深入理解JavaScript系列(13) This? Yes,this!
在這篇文章里,我們將討論跟執(zhí)行上下文直接相關的更多細節(jié)。討論的主題就是this關鍵字。實踐證明,這個主題很難,在不同執(zhí)行上下文中this的確定經(jīng)常會發(fā)生問題2012-01-01Bootstrap-table自定義可編輯每頁顯示記錄數(shù)
這篇文章主要介紹了Bootstrap-table自定義可編輯每頁顯示記錄數(shù)的相關知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-09-09