下面小編就為大家帶來一篇js es6系列教學 - 基於new.target屬性與es5改造es6的類別語法。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
es5的建構子前面如果不用new調用,this指向window,物件的屬性就得不到值了,所以以前我們都要在建構子中透過判斷this是否使用了new關鍵字來確保普通的函數呼叫方式都能讓物件複製到屬性
function Person( uName ){ if ( this instanceof Person ) { this.userName = uName; }else { return new Person( uName ); } } Person.prototype.showUserName = function(){ return this.userName; } console.log( Person( 'ghostwu' ).showUserName() ); console.log( new Person( 'ghostwu' ).showUserName() );
在es6中,為了識別函數呼叫時,是否使用了new關鍵字,引入了一個新的屬性new.target:
1,如果函數使用了new,那麼new.target就是建構子
2,如果函數沒有用new,那麼new .target就是undefined
3,es6的類別方法中,在呼叫時候,使用new,new.target指向類別本身,沒有使用new就是undefined
function Person( uName ){ if( new.target !== undefined ){ this.userName = uName; }else { throw new Error( '必须用new实例化' ); } } // Person( 'ghostwu' ); //报错 console.log( new Person( 'ghostwu' ).userName ); //ghostwu
使用new之後, new.target就是Person這個建構函數,那麼上例也可以用下面這種寫法:
function Person( uName ){ if ( new.target === Person ) { this.userName = uName; }else { throw new Error( '必须用new实例化' ); } } // Person( 'ghostwu' ); //报错 console.log( new Person( 'ghostwu' ).userName ); //ghostwu
class Person{ constructor( uName ){ if ( new.target === Person ) { this.userName = uName; }else { throw new Error( '必须要用new关键字' ); } } } // Person( 'ghostwu' ); //报错 console.log( new Person( 'ghostwu' ).userName ); //ghostwu
上例,在使用new的時候, new.target等於Person
掌握new.target之後,接下來,我們用es5語法改寫上文中es6的類別語法
let Person = ( function(){ 'use strict'; const Person = function( uName ){ if ( new.target !== undefined ){ this.userName = uName; }else { throw new Error( '必须使用new关键字' ); } } Object.defineProperty( Person.prototype, 'sayName', { value : function(){ if ( typeof new.target !== 'undefined' ) { throw new Error( '类里面的方法不能使用new关键字' ); } return this.userName; }, enumerable : false, writable : true, configurable : true } ); return Person; })(); console.log( new Person( 'ghostwu' ).sayName() ); console.log( Person( 'ghostwu' ) ); //没有使用new,报错
以上是JavaScript基於new.target屬性與es5改造es6的類別語法的詳細內容。更多資訊請關注PHP中文網其他相關文章!