摘要:因為構造函數調用會將一個全新的對象作為變量的值,并隱式返回這個新對象作為調用的結果。一個開發者熟知的解決方案是,在調用函數前先判斷函數的接收者是否為當前函數的實例。注意,上面二種解決方案都使用了操作符來判斷對象的實例。
在JavaScript中函數作為對象的屬性使用時,我們稱其為方法調用;如果函數使用new操作符來調用時,我們稱其為構造函數。
在涉及到構造函數時,通常繞不開關于this的討論。因為構造函數調用會將一個全新的對象作為this變量的值,并隱式返回這個新對象作為調用的結果。
在使用構造函數時,如果調用者忘記使用new關健字,那么函數的接收者將是全局對象。
function Person(name, age) { this.name = name; this.age = age; } // 使用`new`調用 var jenemy = new Person("jenemy", 18); console.log(window.age); // undefined // 不使用 var jenemy = Person("jenemy", 18); console.log(window.age); // 18
不使用new調用構造函數的結果是我們無意間創建了全局變量name和age,如果這些全局變量已經存在則會被修改。
一個開發者熟知的解決方案是,在調用函數前先判斷函數的接收者是否為當前函數的實例。
function Person(name, age) { if (!(this instanceof Person)) { return new Person(name, age); } this.name = name; this.age = age; }
這種模式的一個缺點是需要額外的函數調用,在性能上代價有點高。一種更為有效的方式是使用ES5的Object.create()函數。
function Person(name, age) { var self = this instanceof Person ? this : Object.create(Person.prototype); self.name = name; self.age = age; return self; }
注意,上面二種解決方案都使用了instance操作符來判斷對象的實例。如果看過我寫的《javascript判斷一個對象是否為數組》文章,會發現instanceof操作符并不可靠。上面的示例,稍作修改:
function Person(name, age) { this.name = name; this.age = age; } Object.defineProperty(Person, Symbol.hasInstance, { value(v) { return false; } }) var wu = new Person("jenemy", 18); console.log(wu instanceof Person); // false
如果沒有修改Person對象內建的Symbol.hasInstance方法,上面的結果很顯然應該在控制臺輸出true。為了解決函數調用這種模棱兩可的問題,ES6提供了元屬性new.target,當調用函數的[[Construct]]方法時,new.target被賦值為new操作的目標,通常為新創建對象的實例。
function Person(name, age) { if (!new.target) { throw "Peron must called with new"; } this.name = name; this.age = age; } var wu = Person("jenemy", 18); // Uncaught Peron must called with new
需要注意的是在函數外使用new.target會報語法錯誤。同時,它不受對象的Symbol.hasInstance方法被修改的影響。所以如果是在ES6環境,使用new.target是最可靠的解決方案。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88521.html
摘要:注意基本變量類型不是對象類型,只有基本包裝類型才是對象類型。至于顯示的原型,在里用屬性表示,這個是原型繼承的基礎知識,在這里就不在敘述了。 前言 如果你要開發一個復雜的產品,那么肯定少不了使用面向對象機制,當然也避不開 Javascript 里面的繼承,instanceof 運算符是原生 Javascript 語言中用來判斷實例繼承的操作符。所以我們有必要深入理解該運算符! inst...
摘要:三種使用構造函數創建對象的方法和的作用都是在某個特殊對象的作用域中調用函數。這種方式還支持向構造函數傳遞參數。叫法上把函數叫做構造函數,其他無區別適用情境可以在特殊的情況下用來為對象創建構造函數。 一、工廠模式 工廠模式:使用字面量和object構造函數會有很多重復代碼,在此基礎上改進showImg(https://segmentfault.com/img/bVbmKxb?w=456&...
摘要:檢測函數從技術上講,中的函數是引用類型,同樣存在構造函數,每個函數都是其實例,比如不好的寫法然而,這個方法亦不能跨幀使用,因為每個幀都有各自的構造函數,好在運算符也是可以用于函數的,返回。 上周寫過一篇讀書筆記《編寫可維護的JavaScript》之編程實踐,其中 第8章 避免『空比較』是博主在工作中遇坑較多的雷區,所以特此把該章節重新整理分享,希望大家不再坑隊友(>﹏<)。 在 Jav...
摘要:這樣每個實例獨享自己的屬性,并和其他同類型的實例共享方法構造函數原型以上這種方式定義的類型,可以通過來判斷一個實例是否是類型的實際上是通過實例的原型鏈來判斷一個對象是否某個類型的實例的,具體的細節后面會詳細介紹。 JavaScript面向對象編程 如何定義自定義類型 首先需要明確,JavaScript并不是傳統意義上的OO語言,它并沒有class的概念, 而是包含了另一套異常強大的...
摘要:和的作用一樣,區別在于寫法語法對象對象作用判斷對象是否在對象的原型鏈上語法對象構造函數作用判斷構造函數的屬性是否在對象的原型鏈上,如果在,就返回屬性是否可枚舉用于檢查給定的屬性是否能夠使用語句。 ## javascript對象原型成員詳解 ## ECMAScript 中的對象就是一組數據和功能的集合,對象可以通過 new 操作符后跟要創建的對象名稱來...
閱讀 2458·2021-09-27 13:36
閱讀 2163·2019-08-29 18:47
閱讀 2129·2019-08-29 15:21
閱讀 1394·2019-08-29 11:14
閱讀 1979·2019-08-28 18:29
閱讀 1623·2019-08-28 18:04
閱讀 568·2019-08-26 13:58
閱讀 3206·2019-08-26 12:12