JS中有一種說法,叫作一切皆爲對象。對象是什麼呢?大話來說,對象是一種容器,裏面封裝了屬性和方法。在天天編程中,最基本的事情也是頻繁的乾的事情就是建立一個對象,而後使用它幹各類各樣的事情。建立對象的方法有構造函數建立、語法糖建立、還有new
命令建立。固然,本文的標題已經代表此次的主角是new
關鍵字了。面試
new
命令的做用,就是執行構造函數,返回一個實例對象。編程
ps:若是忘了使用new命令,構造函數就變成了普通函數,並不會生成實例對象。
segmentfault
// 一、不帶參數狀況 var Vehicle = function () { this.price = 1000; }; var v = new Vehicle(); v.price // 1000 // 二、帶參數狀況 var Vehicle = function (p) { this.price = p; }; var v = new Vehicle(500);
固然,爲了保證構造函數必須與new
命令一塊兒使用兩種方法。數組
方法一:
構造函數內部使用嚴格模式,即第一行加上use strict
。這樣的話,一旦忘了使用new
命令,直接調用構造函數就會報錯。app
function Fubar(foo, bar){ 'use strict'; this._foo = foo; this._bar = bar; } Fubar() // TypeError: Cannot set property '_foo' of undefined
方法二:
構造函數內部判斷是否使用new
命令,若是發現沒有使用,則直接返回一個實例對象。函數
function Fubar(foo, bar) { if (!(this instanceof Fubar)) { return new Fubar(foo, bar); } this._foo = foo; this._bar = bar; } Fubar(1, 2)._foo // 1 (new Fubar(1, 2))._foo // 1
面試的時候經常會問道,使用new
命令時,會發生什麼。post
一、建立一個空對象,做爲將要返回的對象實例。this
二、將這個空對象的原型,指向構造函數的prototype
屬性。url
三、將這個空對象賦值給函數內部的this
關鍵字。prototype
四、開始執行構造函數內部的代碼。
從上面步驟能夠看出,其構造函數內部,經過this
指的就是新生對象。
若是你對this
不是很清楚,能夠看個人另外一篇文章
關於this、call、applay和bind。
注意:若是構造函數內部有return語句,並且return後面跟着一個對象,new命令會返回return語句指定的對象;不然,就會無論return語句,返回this對象。
例子1
var Vehicle = function () { this.price = 1000; return 1000; }; (new Vehicle()) === 1000 // false
例子2
var Vehicle = function (){ this.price = 1000; return { price: 2000 }; }; (new Vehicle()).price // 2000
另外一方面,若是對普通函數(內部沒有this
關鍵字的函數)使用new
命令,則會返回一個空對象。
function getMessage() { return 'this is a message'; } var msg = new getMessage(); msg // {} typeof msg // "object"
function _new(/* 構造函數 */ constructor, /* 構造函數參數 */ params) { // 將 arguments 對象轉爲數組 var args = [].slice.call(arguments); // 取出構造函數 var constructor = args.shift(); // 建立一個空對象,繼承構造函數的 prototype 屬性 var context = Object.create(constructor.prototype); // 執行構造函數 var result = constructor.apply(context, args); // 若是返回結果是對象,就直接返回,不然返回 context 對象 return (typeof result === 'object' && result != null) ? result : context; } // 實例 var actor = _new(Person, '張三', 28);