js類型判斷及鴨式辨型

來源:互聯網
上載者:User

三種檢測對象的類方式: instanceof、constructor 、建構函式名字 用法如下: 1)instanceof console.log([1,2,3] instanceof Array);true console.log([1,2,3] instanceof Object);true儘管建構函式是原型的唯一標識,instanceof運算子的右運算元是建構函式,instanceof實際計算過程中檢測的是對象的繼承關係,而不是檢測的建立對象時的建構函式,只是使用了建構函式作為中介   當然也可以使用isPrototypeOf 來判斷一個對象是否存在於另一對象的原型鏈中,此時不使用建構函式作為中介 var a1 = new Array();console.log(Array.prototype.isPrototypeOf(a1));true console.log(Array.prototype.isPrototypeOf([1,2,3]));true注意:多個執行內容時(例如存在不同架構時)instanceof使用有限制   2)constructor 每個javascript函數都可以用作建構函式,調用建構函式需要使用prototype屬性,因而每個javascript函數會自動擁有prototype屬性,這個屬性值是一個對象,這個對象包含一個contructor屬性,constructor屬性值是一個函數對象。 即對於函數var F = function(){}; F.prototype.constructor===F 關係圖如下:     eg: 複製代碼var F= function(){};var p = F.prototype;var c = p.constructor;console.log(p);console.log(c);console.log(c===F); Object {}function (){}true複製代碼因而對象繼承的constructor均指代他們的建構函式 eg:   var o= new F();console.log(o.constructor===F); //輸出 true  var a = new Array();console.log(a.constructor===Array);//輸出true  複製代碼function typeDiscern(x){  switch(x.constructor){    case Number: return "Number:"+x;    case String: return "String:"+x;    case Array: return "Array:"+x;        }}console.log(typeDiscern([1,2,3]));console.log(typeDiscern("abc"));console.log(typeDiscern(5));//輸出Array:1,2,3String:abcNumber:5複製代碼    注意: 同instanceof在多個上下文下沒法使用,另外並不是所有的對象都包含constructor屬性   eg: 定義Person類   複製代碼function Person(name)   {      this.name=name;      this.getName=function()           {              return this.name;           }   };     var wish=new Person('js');     console.log(wish.constructor==Person); console.log(Person.prototype);console.log(Person.constructor);  console.log(wish.getName()); //輸出truePerson {}function Function() { [native code] }js複製代碼  給Person自訂prototype 複製代碼function Person(name)   {      this.name=name;      this.getName=function()           {              return this.name;           }   };   Person.prototype={    toString: function(){        return this.name;    }};  var wish=new Person('js');     console.log(wish.constructor==Person); console.log(Person.prototype);console.log(Person.constructor);  console.log(wish.getName());console.log(wish.toString()); //輸出falseObject {toString: function}function Function() { [native code] }jsjs複製代碼此時新定義的原型對象不含有constructor屬性,因而Person的執行個體也不包含constructor屬性 解決方案:可顯示的給原型添加構造方法   Person.prototype={    constructor=Person,    toString: function(){        return this.name;    }}; 建構函式名字 沒有intanceof和constructor的執行內容問題,一個視窗中的Array建構函式和另一個視窗內Array建構函式不等,但是建構函式名字相同,但是並不是每個函數都有名字 複製代碼Function.prototype.getName= function(){    if("name" in this){        return this.name;    }    return this.name=this.toString().match(/function\s*([^(]*)/);}function test1(){}console.log(test1.getName()); //輸出:test1複製代碼  鴨式辨型 關注對象能做什麼,而不是對象的類是什麼 James Whitcomb Riley提出像鴨子一樣走路、遊泳和嘎嘎叫的鳥就是鴨子 主要對象包含walk(),swim(),bike()這三個方法就可以作為參數傳入   利用鴨式辯型實現的函數: 複製代碼function quackImplements(o/*,...*/){    for(var i=1; i<arguments.length;i++){        var arg=arguments[i];        switch(typeof arg){            case 'string':                if(typeof o[arg]!=="function")                    return false;                continue;             case 'function':                arg=arg.prototype;             case 'object':                for (var m in arg){                    if(typeof arg[m]!=="function") continue;                    if(typeof o[m]!=="function") return false;             }        }    }    return true;}複製代碼對於字串直接檢查命名方法 對於對象檢查是否有同名方法 對於函數檢查建構函式的原型對象中是否有相同方法   在javascript中很多函數都不對對象做類型檢測只是關心這些對象能做什麼 eg:Array的prototype利用了鴨式辨型,arguments是偽數組 複製代碼 (function () {     var arr = Array.prototype.slice.apply(arguments);        console.log(arr);})(1, 2, 3); //輸出:[1, 2, 3]複製代碼   var arr = Array.prototype.slice.apply({ 0: 1, 1: 2, 2: 3, length: 3 }); console.log(arr); //輸出:[1, 2, 3]  使用鴨式辨型可以擴大對象的使用範圍 eg:讓普通對象具有數組的push方法 複製代碼Function.prototype.unCurrying = function () {    var f = this;    return function () {        var a = arguments;        return f.apply(a[0], [].slice.call(a, 1));    };};Function.prototype.unCurrying = function () {    return this.call.bind(this);}; var push = Array.prototype.push.unCurrying(),obj = {};push(obj, 'first', 'two');console.log(obj);console.log("length:"+obj.length)複製代碼  輸出: Object{0: "first", 1: "two", length: 2}length:2 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.